- Synced the scripting branch with trunk.

SVN r2166 (scripting)
This commit is contained in:
Randy Heit 2010-02-17 04:46:11 +00:00
commit 913555aa4e
284 changed files with 13344 additions and 7516 deletions

View file

@ -1,3 +1,645 @@
January 3, 2010 (Changes by Graf Zahl)
- fixed: The player setup menu used the main menu's line spacing which
for all non-Doom games was too wide.
- fixed: Strife's dialogues cannot use the new options menu code to draw
themselves so now they use a stripped down version of the old code.
- Replaced I_MSTime with I_FPSTime in node builder timing because basetime
will not be initialized yet if a map is started directly from the commandline.
January 2, 2010 (Changes by Graf Zahl)
- fixed: Polyobjects could contain segs that weren't flagged as such.
- fixed: Trying to show a popup crashed in the SBARINFO code because of a
missing NULL pointer check.
- fixed: The ACS thinker needs its own statnum above all actors. Otherwise
order of execution is not guaranteed.
- fixed: Only ActorMovers should go into STAT_ACTORMOVER, not all PathFollowers.
- fixed: SBARINFO's DrawGem command accepted a size value of 0 and divided
by it. Reinstated the old '+1' this command had in the old code.
- fixed: The floor waggle code used FloatBobOffsets as sine table but this
only has 64 entries and is not precise enough. It now uses finesine instead.
- fixed: When compositing a multipatch texture any patch that is a multpatch
texture itself and contains rotations may not be composited directly into
the destination buffer. This must be done with an intermediate buffer.
- Fixed: Drawing a slider in the options menu did not scale the x-coordinate.
- Fixed: If the alt HUD had to draw negative numbers the minus sign was misplaced
due to incorrect texture coordinate calculations.
- changed option menu scaling for widescreen modes so that it doesn't scale down
so quickly.
- made some error messages in DECORATE that don't affect the parsing non-fatal
so that the parser can continue to find more problems.
January 1, 2010 (Changes by Graf Zahl)
- added initial support for a GAMEINFO lump in PWADs. When the game is started
all files loaded with '-file' are scanned for this lump. This lump is read
before any WAD initialization takes place, in particular the IWAD is not yet
loaded at this time. This allows PWADs the option to specify an IWAD they
want to run with and optionally autoload external resource WADs.
- Fixed a few places where FixPathSeperator was called with a locked FString buffer.
It's better to use the FString version of this function instead.
- replaced wadlist_t with an array of FStrings and added a list parameter to
everything that eventually calls D_AddFile. Also create the list of files
loaded on the command line separately to allow further checks on them.
- Added Blzut3's Solaris patch.
- Fixed: Heretic's Weredragon (Beast) should not have a melee state.
January 1, 2010 (SBARINFO update)
- Reorganized the SBarInfo code.
- Added interpolate(<speed>) flag to drawnumber, drawbar, and drawgem. The old
way of interpolating the health and armor is depreciated.
- Added: armortype to drawswitchableimage loosely based on Gez's submission.
- As an extension to the previous you can now use comparison operators on
inventory items and armortype in drawswitchableimage.
January 1, 2010 (Changes by Graf Zahl)
- Added Blzut3's Solaris patch.
- Fixed: Heretic's Weredragon (Beast) should not have a melee state.
December 31, 2009 (Changes by Graf Zahl)
- fixed: FastProjectile was missing all sky checks when the projectile's move
was blocked.
December 30, 2009
- Fixed: A_ThrowGrenade used the same code as the old fighter flechette, so
it was just as broken at aiming up and down.
December 30, 2009 (Changes by Graf Zahl)
- fixed: Movement performed by actor movers was not interpolated because
it happened outside the moved actor's Tick function. This got particularly
obvious with moving skybox viewpoints (See Daedalus's MAP21 intro for a good
example.)
Fixing this exposed a design flaw in the thinker system:
Having every single actor default to the highest available statnum means that
nothing can be placed in a slot where it is guaranteed to be run after all actors
have ticked. But this is required for any thinker that moves an actor
(i.e. AActorMover and DSectorEffect.) With DSectorEffect it just went unnoticed
because they were added at the end of the list so almost nothing they moved was
behind them in a thinker list. However, when an actor was spawned on a moving
floor it did not move smoothly. The default statnum is now 100 so that there's
sufficient slots above where such thinkers can be placed.
December 28, 2009
- Fixed: Shooting up and down with AArtiPoisonBag3::Use() was completely
broken. I don't know what I thinking when I plugged in 2*finesine[pitch]
for Hexen's lookdir, because that's totally wrong. Not only is the
magnitude far too low, but it also aims in the opposite direction you
are looking. The new code only attempts to be close to Hexen's original
while looking straight ahead and extrapolates that to other angles using
proper 3D math.
December 28, 2009 (Changes by Graf Zahl)
- Added full sound definitions for Heretic's ChickenPlayer and Hexen's
PigPlayer (submitted by NeuralStunner.)
- Added unmorph fix by Gez.
- merged all portals with the same displacement together. While this provides
a mild performance increase it's not what I hoped it would do...
- Moved portal initialization for the portal things to P_SpawnSpecials
instead of having the things self-initialize in PostBeginPlay. This was
done to ensure that the portals are fully set up when the game begins.
Otherwise there is no decent way to let the renderer post-process this
information during setup.
- Changed: For 800x600 the default scaling handling of the options menu
makes it become too small so for any resolution with a width between
800 and 959 it has been reverted to the regular clean scaling factor.
December 27, 2009 (Changes by Graf Zahl)
- added Hirogen2's Backpack fix for sv_unlimited_pickup.
- added a linedef based method to define portals. Portals defined this way
still have the same limitations as those defines with the portal things.
December 25, 2009 (Changes by Graf Zahl)
- Fixed: Decals could spread to walls which had a decal-less texture or
were flagged not to have decals.
- Fixed: DBaseDecal/DImpactDecal::CloneSelf never checked the return value
from their StickToWall call and left unplaced decals behind if that happened.
- Reintroduced Doom.exe's player_t::usedown variable so that respawning a
player does not immediately activate switches. oldbuttons was not usable
for this. This also required that CopyPlayer preserves this info.
- Fixed: When restarting the music there was a NULL pointer check missing
so it crashed when the game was started wi
- Fixed: If the Use key is used to respawn the player it must be cleared
so that it doesn't trigger any subsequent actions after respawning.
- Fixed: Resurrecting a monster did not restore flags5 and flags6.
- Fixed: Projectiles which killed a non-monster were unable to determine
what precisely they hit because MF_CORPSE is only valid for monsters.
A new flag, MF6_KILLED that gets set for all objects that die, was added
for this case.
- Added a generic A_Weave function that exposes all possible options of
A_BishopMissileWeave and A_CStaffMissileSlither. These 2 functions are
no longer needed from DECORATE and therefore deprecated.
December 24, 2009
- The options menu no longer scales up so quickly, so it can fit wider text
onscreen. In addition, it now uses the whole height available to it. Also,
at lower resolutions, items on the compatibility options menu now cut off
the beginning of the option label rather than the option setting, making
this menu useable where previously it was not.
- Added a channel parameter to the sector overload of SN_StopSequence() so
it can be properly paired with calls to SN_StartSequence().
- Fixed: P_CheckPlayerSprites() ignored the MF4_NOSKIN flag. It now also sets
the X scale, so switching skins while morphed does not produce weird
stretching upon unmorphing.
- Fixed: Calling S_ChangeMusic() with the same song but a different looping
flag now restarts the song so that the new looping setting can be applied.
(This was easier than modifying every music handler to support modifying
loop changes on the fly, which seems like overkill.)
- Fixed: savepatchsize was declared incorrectly in d_dehacked.cpp:DoInclude().
- Changed AFastProjectile::Effect() so that it sets the spawned trail to face
same direction as the projectile.
December 24, 2009 (Changes by Graf Zahl)
- fixed: The UDMF blockfloaters flag was misnamed. Changed to match the spec.
December 23, 2009 (Changes by Graf Zahl)
- made the initial weave index for A_BishopMissileWeave and A_CStaffMissileSlither
a configurable actor property.
- added a menu item for snd_channels.
December 20, 2009 (Changes by Graf Zahl)
- Fixed: The Dehacked parser could read past the end of the file if the last
element was improperly defined.
December 19, 2009
- Extended MF3_SKYEXPLODE to apply to horizon walls as well.
December 19, 2009 (Changes by Graf Zahl)
- Fixed: It was not possible to set the ammo type of a weapon explicitly to
'none'.
December 18, 2009
- A_FreezeDeath() now removes fuzz effects.
- In mus2midi.cpp, added range checking to MUS_SYSEVENT and MUS_CTRLCHANGE,
and masking for note-off keys, note-on velocities, and program changes.
December 18, 2009 (Changes by Graf Zahl)
- added all known maps requiring inverted sprite sorting to compatibility.txt.
- added compatibility option to invert sprite sorting. Apparently Doom.exe
originally sorted them differently than most source port and on some maps
which depends on this it doesn't look right (e.g. Strain MAP13)
December 17, 2009
- Fixed: Using Transfer_Heights with the SECF_UNDERWATER and
SECF_FAKEFLOORONLY flags applied the water effect to the ceiling and not
just the floor.
- Replaced sprite sorting with a stable sort. Performance at the start of
nuts.wad seems the same.
December 16, 2009 (Changes by Graf Zahl)
- Fixed: Morphed players tried endlessly to switch to a weapon they picked up.
- fixed: P_DamageMobj just set an ice corpse's velocity to 0 to make it shatter.
But that's insufficient because it doesn't factor in any subsequent velocity
change that happens between the damaging and the next call to A_FreezeDeathChunks.
- fixed: The TimeFreezer did not freeze other players' controls in a
multiplayer game.
- fixed: DECORATE's 'gravity' property incorrectly messed around with the
NOGRAVITY flag.
- fixed: Hitscan attacks didn't check the puff's replacement for damage types.
December 13, 2009 (Changes by Graf Zahl)
- fixed: old-style DECORATE definitions with non-alphanumeric characters in
the name produced an error.
December 12, 2009
- Added a DMG_NO_FACTOR flag for P_DamageMobj(). A_KillChildren, A_KillMaster,
and A_KillSiblings now use it.
- Added a damage type parameter to A_KillChildren, A_KillMaster, and
A_KillSiblings.
December 11, 2009 (Changes by Graf Zahl)
- fixed: Auto-COMPAT_SHORTTEX for IWADs must be set per IWAD, not in general
for Doom.
- added autodetection of Harmony's IWAD.
- Added SnailMan's updated language.ita file.
December 11, 2009
- Fixed: You should still be able to pick up ammo that has a max amount set
at 0.
- Added a few NULL screen checks.
December 6, 2009 (Changes by Graf Zahl)
- added some code that prevents overlapping monsters from getting stuck in
each other. PIT_CheckThing will return true under the following contitions
now:
* It was called from P_Move
* The actor that is blocking the move already overlaps with the monster
that is being moved.
* the move will take the 2 actors further apart.
December 1, 2009
- Added another surface to receive a copy of the top back buffer immediately
before it is presented. This effectively produces a copy of the front
buffer without the performance penalty of GetFrontBufferData, so fullscreen
wipe preparation and screenshots are faster now. At lower resolutions,
always copying the backbuffer does incur a slight FPS hit, but it's
practically free at higher resolutions.
November 30, 2009
- The initial wipe screen is now kept in video memory. I had previously
assumed that since the wipes only run at 35 FPS, the time spent DMA'ing
it from system to video memory would be acceptable. Apparently I was wrong.
In particular, updating the same surface several times probably has to
synchronize between each one, making melt particularly slower than it
needs to be.
November 29, 2009 (Changes by Graf Zahl)
- fixed: Line_SetBlocking and Line_SetTextureScale were not in the list
of action specials used by DECORATE or MAPINFO.
- fixed: Teleport_NoStop was not in the line special function table.
November 28, 2009
- Fixed: The FPS meter cannot use I_MSTime(), because if the game is started
with +vid_fps 1, it can need the time before the timer is ready to start.
- Initialize TempRenderTexture and the back buffer to black upon creation.
- Fixed: Windowed mode always needs to draw to the temporary surface, even
when not gamma correcting, so that D3DFB::GetCurrentScreen() can read from
it.
- Use the spawned class's scale as default for ScriptedMarine instead of
DoomPlayer.
November 28, 2009 (Changes by Graf Zahl)
- fixed: Morph weapons weren't destroyed because the code checked for
them in the unmorphed player class.
- fixed: With padding the largest texture to fit into a page is 254x254.
November 27, 2009 (Changes by Graf Zahl)
- fixed an uninitialized variable in p_xlat.cpp (Thanks, MSVC for not
warning about such an obvious problem! :( )
- fixed: The charge attack of Heretic's imp is not precisely the same
as A_SkullAttack with a different speed so A_ImpMsAttack has been
reinstated.
November 25, 2009
- Make the palette indexes used by FRemapTable subject to the global remap
table, just as the images they translate are.
November 24, 2009 (Changes by Graf Zahl)
- Added MF4_ALLOWPARTICLES checks to blood spawning code.
- Fixed: EV_DoDonut, EV_DoElevator and EV_StartWaggle did not to any 0-tag
checks.
- Fixed: Doom line type 44 (lower ceiling to 8 above floor) must halt
movement if blocked which essentially means it acts like a Hexen-style
crusher.
- Fixed: Not all places checking for player start spots did it correctly.
The editor number for player start spot 5 is now stored in the game info
so that there's only one place where this check needs to be done.
- Fixed: WIF_NOAUTOAIM only worked for projectiles.
November 23, 2009
- Added Windows 7 (aka Windows NT 6.1) and Server 2008 identification to
I_DetectOS().
- Fixed: ArtiPork did not use all its sprite frames.
- Fixed: FWadCollection::AddFile() did not call FixPathSeperator(), so
savegames would hold the full file path for wads that had been specified
with backslash characters, because GetWadName() would not trim off the
path.
November 22, 2009 (Changes by Graf Zahl)
- extended Doom map format linedef translator so that it also handles the flags.
November 19, 2009
- Replaced toint/quickertoint with the portable routines from xs_Float.h. The
former used fistp, which is not portable across platforms, so cannot be
used in the play simulation. They were only suitable for the renderer.
xs_Float.h also has a very fast float->fixed conversion, so FLOAT2FIXED
uses that now.
(And I also learned that the FPU's round to nearest is not the rounding I
learned in grade school but actually Banker's Rounding. I had no idea.)
(Also, also, the only thing that could have made quickertoint faster than
toint was that it stored a 32-bit int. I never timed them, and I doubt in
practice there was any real difference between the two.)
November 18, 2009
- Added padding around packed textures to compensate for apparent NVidia
texture coordinate imprecision.
November 17, 2009
- Fixed two bugs in FMODSoundRenderer::HandleChannelDelay():
* Looping sounds that have been playing for a very long time, were evicted,
and then were restarted need to have their positions clamped to lie
within the bounds of the sounds. If we try to set a start position very
far beyond the end, it will overflow inside FMOD and not work.
* A start time of 0 is not actually valid and means the sound was never
assigned a start time.
- The latter bug also reveals a problem with starting looped sounds evicted:
They need to be assigned a start time so if they should have the opportunity
to start later, they will be properly synchronized.
November 17, 2009 (Changes by Graf Zahl)
- fixed: P_NowayTraverse was called with a trace distance of 128 instead of
the 64 that should have been used.
- fixed: R_PointToAngle could overflow with very long vectors passed to
it. This caused rendering bugs on some maps. (Interestingly the only
other port having a safeguard for this in place was PrBoom.)
- reverted the change that makes 0-damage projectiles call P_DamageMobj.
Both Hexen and Heretic depend on such projectiles not doing it as do many
mods that create snow/rain effects plus any terrain splash mod.
November 15, 2009 (Changes by Graf Zahl)
- fixed: fullscreen images with texture scaling used the unscaled size for
positioning. To avoid future problems with them I added a new DTA_Fullscreen
option for DrawTexture.
- fixed: The sky baseline position needs to take texture scaling into account.
November 14, 2009
- Do not squash skies taller than 200 into square pixels.
November 14, 2009 (Changes by Graf Zahl)
- Added skillinfo fix by Gez.
- added a r_scaletallskies CVAR so that sky positioning can be checked
more easily.
- fixed: Skies with a height of exactly 200 pixels should not be stretched.
November 13, 2009
- More sky changes: Textures taller than 200 pixels but shorter than 241
are scaled to the height of a 200 pixel tall sky. Skies taller than 240
use the same scale as a 240 tall sky but are shifted down to make the
top of the texture align with the top of the screen when looking fully up.
Thus, by using a sky texture with a height of 240 or more pixels, the sky
will be drawn with square pixels instead of the vertically elongated ones
imposed by Doom's native 320x200 resolution.
November 12, 2009
- Improved sky stretching a bit: It now only stretches the sky as tall as it
needs to be: 228 pixels, not 256. It no longer stretches horizontally,
either.
The reason it stretches to 228 and not 200 pixels is because Doom shifted
its sky texture down 28 pixels. By stretching to 228 pixels, we can keep
the sky tiled at the same height on the horizon. Skies 200 pixels tall
(or more) will continue to tile at the center of the screen when looking
directly ahead.
- Cleaned up win32/i_system.cpp.
- Put back the previous event-driven ticker, except now the timer isn't
started until the first time it is needed.
November 11, 2009
- Modified the event-driven ticks to use the same code for calculating the
time as the polled timer so that the timer does not start running until the
first time it is used.
- Removed the srand() call from D_DoomMain(), because it started the game
timer running prematurely, and we never call rand() anywhere. (Not to
mention, even if we did use rand(), always seeding it with 0 is rather
pointless.)
- Fixed: The framerate was not capped before starting a game.
- Removed the one embedded DeHackEd lump restriction.
- Fixed: nofreeaim in P_SpawnPlayerMissile() was broken.
- Fixed: MBF sky Y offsets were ignored. X offsets should also be applied to
the sky cylinder, not the screen like Hexen scrolling skies.
November 9, 2009
- Maps inside zips can now satisfy the map checks for IWAD detection.
- Fixed: F7ZFile did not delete its Archive when destroyed.
November 7, 2009
- Fixed: The x64 Release build was configured to use the 32-bit GME, and
neither release nor debug builds built the library.
- Fixed: R_GetOneSkyColumn() and R_GetTwoSkyColumns are mulscaling an
unsigned integer that can use all 32 bits. They must therefore use
the unsigned mul instruction rather than the signed imul instruction.
- Fixed several signed/unsigned comparison and possibly uninitialized
variable warnings flagged by GCC.
November 5, 2009 (Changes by Graf Zahl)
- fixed: The 'new format only' flag for MAPINFO options was never checked.
(ZDoom itself doesn't use it yet so it's only relevant for child ports.)
November 3, 2009
- Fixed: S_RestartSound() cleared the evicted flag even if the sound
was not restarted because it was too close to too many other identical
sounds that were already playing.
- Added virtual status and audibility to the noise debug display.
- Added a command line option -warpwipe to perform the screen wipe if you
start with -warp or +map.
October 31, 2009
- Changed all coordinates for DrawTexture() to floating point so that the
player sprites will retain the same precision they had when they were
rendered as part of the 3D view. (needed for propery alignment of flashes
on top of weapon sprites) It worked just fine for D3D, but software
rendering was another matter. I consequently did battle with imprecisions
in the whole masked texture drawing routines that had previously been
partially masked by only drawing on whole pixel boundaries. Particularly,
the tops of posts are calculated by multiplying by spryscale, and the
texture mapping coordinates are calculated by multiplying by dc_iscale
(where dc_iscale = 1 / spryscale). Since these are both 16.16 fixed point
values, there is a significant variance. For best results, the drawing
routines should only use one of these values, but that would mean
introducing division into the inner loop. If the division removed the
necessity for the fudge code in R_DrawMaskedColumn(), would it be worth it?
Or would the divide be slower than the fudging? Or would I be better off
doing it like Build and using transparent pixel checks instead, not
bothering with skipping transparent areas? For now, I chop off the
fractional part of the top coordinate for software drawing, since it was
the easiest thing to do (even if it wasn't the most correct thing to do).
October 29, 2009
- Fixed: Sprites and decals that are drawn with addition must fade to black.
- Make TranslateToStartSpot() set the new sector references for a polyobj's
walls so that P_CheckSwitchRange() will work with them.
- Fixed: An unspecified save_dir will now save to the program directory on
Windows. (Other operating systems already use the user's home directory
instead.)
- Fixed: S_EvictAllChannels() must replace the channel's start time with its
position when evicting sounds, because restarting the sound system causes
the DSP clock to restart at 0, so start times that were recorded before
the reset are no longer applicable after the reset.
- Fixed: S_StopChannel() always set the channel's actor to NULL, eliminating
origin information when resetting the sound system.
October 28, 2009
- Added Gez's patch for IWAD detection of Blasphemer and Action Doom 2.
- Fixed: 0 damage projectiles did not call P_DamageMobj.
- Fixed: Do not exit P_DamageMobj early if damage is 0, so we can still get
the side effects from it. PainThreshold also needs to be inclusive, as
the docs already state.
October 26, 2009
- Changes to both A_MonsterRail() and A_CustomRailgun(): Save actor's pitch,
use a larger aiming range, ignore non-targets in P_AimLineAttack(), and
aim at the target anyway even if P_AimLineAttack() decides it has no
chance of hitting.
- Added another parameter to P_AimLineAttack(): A target to be aimed at. If
this is non-NULL, then all actors between the shooter and the target will
be ignored.
- Added new sound sequence ACS functions:
SoundSequenceOnActor(int tid, string seqname);
SoundSequenceOnSector(int tag, string seqname, int location);
SoundSequenceOnPolyobj(int polynum, string seqname);
SoundSequenceOnSector takes an extra parameter that specifies where in the
sector the sound comes from (floor, ceiling, interior, or all of it). See
the SECSEQ defines in zdefs.acs.
- Fixed: R_RenderDecal() must save various Wall globals, because the originals
may still be needed. In particular, when drawing a seg with a midtexture is
split by foreground geometry, the first drawseg generated from it will have
the correct WallSZ1,2 values, but subsequent ones will have whatever
R_RenderDecal() left behind. These values are used to calculate the upper
and lower bounds of the midtexture. (Ironically, my work to Build-ify things
had done away with these globals, but that's gone now.)
October 24, 2009 (Changes by Graf Zahl)
- fixed: sector_t::GetHeightSec checked the wrong MoreFlags.
- made max. view pitch a property of the renderer so that it's overridable without
changing game code.
- made SpawningMapThing an argument of AActor::StaticSpawn instead of a global
variable.
- added a stub to the DECORATE parser for defining dynamic lights directly
in DECORATE. This is needed so that ZDoom remains compatible with any DECORATE
which uses this GZDoom feature in the future.
October 24, 2009
- Removed the Actor uservar array and replaced it with user-defined variables.
A_SetUserVar/SetUserVariable/GetUserVariable now take a variable name
instead of an array index. A_SetUserArray/SetUserArray/GetUserArray
have been added to access elements in user-defined arrays.
- Rewrote wide sky texture scaling again. This time, it should work for any
size textures at any scale. I also tried doing sky scrolling on the sky
cylinder, but that didn't look so good, so I left it in screen space.
October 23, 2009
- Fixed: When giving completely new ammo, the backpack did not clamp the
amount given to the ammo's max amount.
- Fixed drawing of wide high resolution skies. (At least for the samples I
received. I'm not convinced that it's yet fixed for the general case.)
October 19, 2009 (Changes by Graf Zahl)
- fixed: Setting the first state's duration of a fast projectile to 0 caused
an underflow and blocked all further state changes.
October 18, 2009 (Changes by Graf Zahl)
- fixed: FMultiPatchTexture::MakeTexture was missing a range check for the
special colormap index.
October 17, 2009 (Changes by Graf Zahl)
- Fixed: 3DMidtex checks were treating the Null texture as a valid texture.
- Fixed: The rail sound's position was not clamped to the actual range between
the trail's start and end point.
- Fixed: Explosions no longer caused splashes.
- Fixed: Copying translations to lower decals had the shade color check wrong.
- Fixed: Waggling floors did not moved attached geometry.
- Cleaned up p_floor.cpp so that related parts of the code are grouped together.
- fixed: The translation addition broke parsing of palette index based translations.
October 16, 2009 (Changes by Graf Zahl)
- added 'defaultterrain' option to terrain parser for mods that want to have
a different default terrain than a generic solid surface.
- added format char processing to A_Print(Bold) and all printable messages
that can be defined in DECORATE.
- Fixed: The railgun code ignored MF3_ALWAYSPUFF.
- added desaturated translations.
- added optional state parameters to A_ReFire and A_GunFlash and A_CountdownArg.
October 15, 2009 (Changes by Graf Zahl)
- added ACS CheckActorClass function
- fixed: When a blasted actor collided with another one this other actor's
DONTBLAST flag was not checked.
- added a global DamageFactor actor property. All damage this actor takes is multiplied
by this factor in addition to damage type specific damage factors.
- added better earthquake functions for ACS and DECORATE.
October 10, 2009 (Changes by Graf Zahl)
- Added MF6_NOTRIGGER flag that disables all line actions for an actor.
October 9, 2009 (Changes by Graf Zahl)
- Added Gez's seeker missile submission.
- Added Gez's thing activation submission.
- added a NULL pointer check to fog spawning in unmorphing code.
- fixed: frozen corpses need to be treated as solid by z-movement code.
- fixed: AAmbientSound::Serialize was adjusting its timer value for savegames
even when it was set to a 'don't check' value.
October 8, 2009
- Reinstated the off-by-one check in D3DFB from r399. I thought I could get by
at just fixing it at a specific value, since the supply of SM14 cards isn't
all that diverse and all from ATI, but apparently Radeon 8500s and 9000s
have different precision levels in their pixel shaders. See bug report
<http://forum.zdoom.org/viewtopic.php?p=444523>
October 8, 2009 (Changes by Graf Zahl)
- Added a PainThreshold actor property.
- fixed: Teleport_EndGame did not set the end sequence name properly.
October 7, 2009
- Since I am currently without a primary video card and stuck with this
Mobility Radeon 9000 (on a PCI card, no less!), I have decided to give the
PS14 support some loving: D3D windowed gamma now works on these cards using
a texture lookup for the gamma table. Sadly, this halves my framerate, so
setting gamma to 1 will skip the gamma correction, as it was before, for
full speed. (On my 8800 GT, the gamma correction was free.)
October 4, 2009 (Changes by Graf Zahl)
- Deleted a_magewand.cpp because it only contained unused code.
- Fixed: The conversation code tried to get the player's tag instead of the
NPC's he is talking to when it had no given name.
October 3, 2009 (Changes by Graf Zahl)
- Added Gez's MageWandMissile customization patch but moved the new functionality
into the FastProjectile base class and removed the native MageWandMissile
class, using the generic functionality instead.
- Fixed: GetReplacement and GetReplacee always checked the skill definitions,
even if they weren't supposed to be used. It was also missing a range check
for 'gameskill'.
October 2, 2009 (Changes by Graf Zahl)
- fixed: Savegames stored the global fixed light levels when saving a player.
October 1, 2009 (Changes by Graf Zahl)
- Fixed some GCC warnings.
- fixed: The BossCube could be blocked by floors and ceiling resulting
in incorrect movement. I changed it so that A_BrainSpit now sets the
MF5_NOINTERACTION flag for anything it spawns that has the MF_NOCLIP
flag. For travelling cubes active collision detection makes no sense
and only causes problems. This should also make the boss brain
work in the other games which previously were excluded by a game mode
check in the movement code.
- fixed: ACS's GetUserVariable did not work for the script activator.
- fixed: Moving floors could be blocked by 2 actors without MF2_PASSMOBJ
overlapping each other (common mapping bug, check Herian 2 MAP30.)
September 30, 2009 (Changes by Graf Zahl)
- Fixed: Coordinate handling for multipatch texture compositing was not correct
for true color. Instead of using a clipping rectangle on the destination it
tried to alter the source offsets which produced incorrect results for
mirrored or rotated patches.
September 29, 2009
- Fixed: Alt+F4 no longer quit the program.
September 28, 2009 (Changes by Graf Zahl)
- Added BHS's death special flags submission.
- Added Gez's A_Blast submission.
September 27, 2009 (Changes by Graf Zahl)
- Fixed: Floor and ceiling huggers' velocity was wrong when used with
P_SpawnPlayerMissile.
- Fixed: When hitting a voodoo doll the real player needs to be checked for
invulnerability.
- Fixed: G_QueueBody was not notifying the translation that it was changed.
- Fixed: The multitexture composition code was missing a NULL pointer check.
- fixed: The changes for new colormap handling in FMultipatchtexture were incomplete.
Some code was still checking Blend.r instead of the full variable for colormap indices.
September 26, 2009
- Fixed: R_DrawPSprite() did not initialize the colormap for the targeter
vissprites.
- Added a check for SPAC_AnyCross to P_TestActivateLine() before the "monster"
activation checks. They are actually non-player checks and interfered with
SPAC_AnyCross.
- idclev and hxvisit are no longer considered cheats, however, they are still
invalid for net games. hxvisit was erroneously accepted for net games
before, which it shouldn't have, since it's basically idclev for Hexen.
September 24, 2009
- Fixed: "give health" without an amount would set your health to IDDQD health
instead of the player class's maximum.
- Fixed: A_CStaffCheck() assumed the player's max health was 100 instead
of getting checking for the true maximum.
- Changed P_XYMovement() to not call P_SlideMove() if the act of being
blocked changed the actor's velocity. I'm not entirely happy with this,
but it gets push-activated force fields to work.
- Fixed: FMultiPatchTexture::CopyTrueColorPixels() should clear the buffer
first before drawing into it if the copy op passed to it is OP_OVERWRITE.
FTexture::FillBuffer() sets this to erase whatever texture might have been
in the space it is going into.
September 22, 2009
- Added a technique to try and minimize input lag with vsync enabled: Two
surfaces are alternately locked for read-only access each frame, forcing

View file

@ -192,6 +192,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
208: TranslucentLine, arg0 (arg0 must be preserved)
1: Polyobj_StartLine, arg3
5: Polyobj_ExplicitLine, arg4
181: Plane_Align, arg2
215: Teleport_Line, arg0
222: Scroll_Texture_Model, arg0 (arg0 must be preserved)

View file

@ -696,8 +696,7 @@ add_executable( zdoom WIN32
g_shared/a_weaponpiece.cpp
g_shared/a_weapons.cpp
g_shared/hudmessages.cpp
g_shared/sbarinfo_display.cpp
g_shared/sbarinfo_parser.cpp
g_shared/sbarinfo.cpp
g_shared/sbar_mugshot.cpp
g_shared/shared_hud.cpp
g_shared/shared_sbar.cpp
@ -779,6 +778,11 @@ add_executable( zdoom WIN32
set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" )
set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" )
if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
# [BL] Solaris requires these to be explicitly linked.
set( ZDOOM_LIBS ${ZDOOM_LIBS} nsl socket)
endif(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
target_link_libraries( zdoom ${ZDOOM_LIBS} gme gdtoa dumb lzma )
include_directories( .
g_doom

View file

@ -53,6 +53,9 @@ DEFINE_SPECIAL(Sector_SetLink, 51, 4, 4, 4)
DEFINE_SPECIAL(Scroll_Wall, 52, 5, 5, 5)
DEFINE_SPECIAL(Line_SetTextureOffset, 53, 5, 5, 5)
DEFINE_SPECIAL(Sector_ChangeFlags, 54, 3, 3, 3)
DEFINE_SPECIAL(Line_SetBlocking, 55, 3, 3, 3)
DEFINE_SPECIAL(Line_SetTextureScale, 56, 5, 5, 5)
DEFINE_SPECIAL(Sector_SetPortal, 57, -1, -1, 5)
DEFINE_SPECIAL(Plat_PerpetualRaise, 60, 3, 3, 3)
DEFINE_SPECIAL(Plat_Stop, 61, 1, 1, 1)
@ -103,19 +106,11 @@ DEFINE_SPECIAL(Light_Glow, 114, 4, 4, 4)
DEFINE_SPECIAL(Light_Flicker, 115, 3, 3, 3)
DEFINE_SPECIAL(Light_Strobe, 116, 5, 5, 5)
DEFINE_SPECIAL(Light_Stop, 117, 1, 1, 1)
DEFINE_SPECIAL(Plane_Copy, 118, -1, -1, 5)
DEFINE_SPECIAL(Thing_Damage, 119, 2, 3, 3)
DEFINE_SPECIAL(Radius_Quake, 120, 5, 5, 5) // Earthquake
DEFINE_SPECIAL(Line_SetIdentification, 121, -1, -1, 5)
#if 0 // Skull Tag specials that might be added later
Thing_SetGravity, 122, -1, -1)
Thing_ReverseGravity, 123, -1, -1)
Thing_RevertGravity, 124, -1, -1)
#endif
DEFINE_SPECIAL(Thing_Move, 125, 2, 3, 3)
#if 0 // Skull Tag special I doubt I will add
Thing_SetSprite, 126, -1, -1)
#endif
DEFINE_SPECIAL(Thing_SetSpecial, 127, 5, 5, 5)
DEFINE_SPECIAL(ThrustThingZ, 128, 4, 4, 4)
DEFINE_SPECIAL(UsePuzzleItem, 129, 2, 5, 5)
@ -136,6 +131,7 @@ DEFINE_SPECIAL(Teleport_NoStop, 154, 2, 3, 3)
// Although ZDoom doesn't support them it's better to have them defined so that
// WADs using them somewhere can at least be started without aborting due
// to an error message.
DEFINE_SPECIAL(SetGlobalFogParameter, 157, 2, 2, 2)
DEFINE_SPECIAL(FS_Execute, 158, 1, 4, 4)
DEFINE_SPECIAL(Sector_SetPlaneReflection, 159, 3, 3, 3)
DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1, 5)
@ -154,7 +150,7 @@ DEFINE_SPECIAL(Thing_Hate, 177, 2, 3, 3)
DEFINE_SPECIAL(Thing_ProjectileAimed, 178, 4, 5, 5)
DEFINE_SPECIAL(ChangeSkill, 179, 1, 1, 1)
DEFINE_SPECIAL(Thing_SetTranslation, 180, 2, 2, 2)
DEFINE_SPECIAL(Plane_Align, 181, -1, -1, 2)
DEFINE_SPECIAL(Plane_Align, 181, -1, -1, 3)
DEFINE_SPECIAL(Line_Mirror, 182, -1, 0, 0)
DEFINE_SPECIAL(Line_AlignCeiling, 183, 2, 2, 2)
DEFINE_SPECIAL(Line_AlignFloor, 184, 2, 2, 2)
@ -163,7 +159,7 @@ DEFINE_SPECIAL(Sector_SetCeilingPanning, 186, 5, 5, 5)
DEFINE_SPECIAL(Sector_SetFloorPanning, 187, 5, 5, 5)
DEFINE_SPECIAL(Sector_SetCeilingScale, 188, 5, 5, 5)
DEFINE_SPECIAL(Sector_SetFloorScale, 189, 5, 5, 5)
DEFINE_SPECIAL(Static_Init, 190, -1, -1, 3)
DEFINE_SPECIAL(Static_Init, 190, -1, -1, 4)
DEFINE_SPECIAL(SetPlayerProperty, 191, 3, 3, 3)
DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 2, 2)
DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 3, 3)

View file

@ -217,7 +217,7 @@ enum
MF3_CRASHED = 0x00200000, // Actor entered its crash state
MF3_FULLVOLDEATH = 0x00400000, // DeathSound is played full volume (for missiles)
MF3_AVOIDMELEE = 0x00800000, // Avoids melee attacks (same as MBF's monster_backing but must be explicitly set)
/* = 0x01000000, */
MF3_SCREENSEEKER = 0x01000000, // Fails the IsOkayToAttack test if potential target is outside player FOV
MF3_FOILINVUL = 0x02000000, // Actor can hurt MF2_INVULNERABLE things
MF3_NOTELEOTHER = 0x04000000, // Monster is unaffected by teleport other artifact
MF3_BLOODLESSIMPACT = 0x08000000, // Projectile does not leave blood
@ -316,6 +316,9 @@ enum
MF6_ARMED = 0x00002000, // From MBF: Object is armed (for MF6_TOUCHY objects)
MF6_FALLING = 0x00004000, // From MBF: Object is falling (for pseudotorque simulation)
MF6_LINEDONE = 0x00008000, // From MBF: Object has already run a line effect
MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse)
// --- mobj.renderflags ---
@ -431,17 +434,23 @@ enum EBounceFlags
};
// Used to affect the logic for MF5_USESPECIAL and MF6_BUMPSPECIAL
// Used to affect the logic for thing activation through death, USESPECIAL and BUMPSPECIAL
// "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it
enum EThingSpecialActivationType
{
THINGSPEC_Default = 0, // Normal behavior: a player must be the trigger, and is the activator
THINGSPEC_ThingActs = 1, // The thing itself is the activator of the special
THINGSPEC_ThingTargets = 2, // The thing changes its target to the trigger
THINGSPEC_TriggerTargets = 4, // The trigger changes its target to the thing
THINGSPEC_MonsterTrigger = 8, // The thing can be triggered by a monster
THINGSPEC_MissileTrigger = 16, // The thing can be triggered by a projectile
THINGSPEC_ClearSpecial = 32, // Clears special after successful activation
THINGSPEC_Default = 0, // Normal behavior: a player must be the trigger, and is the activator
THINGSPEC_ThingActs = 1, // The thing itself is the activator of the special
THINGSPEC_ThingTargets = 1<<1, // The thing changes its target to the trigger
THINGSPEC_TriggerTargets = 1<<2, // The trigger changes its target to the thing
THINGSPEC_MonsterTrigger = 1<<3, // The thing can be triggered by a monster
THINGSPEC_MissileTrigger = 1<<4, // The thing can be triggered by a projectile
THINGSPEC_ClearSpecial = 1<<5, // Clears special after successful activation
THINGSPEC_NoDeathSpecial = 1<<6, // Don't activate special on death
THINGSPEC_TriggerActs = 1<<7, // The trigger is the activator of the special
// (overrides LEVEL_ACTOWNSPECIAL Hexen hack)
THINGSPEC_Activate = 1<<8, // The thing is activated when triggered
THINGSPEC_Deactivate = 1<<9, // The thing is deactivated when triggered
THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered
};
// [RH] Like msecnode_t, but for the blockmap
@ -540,7 +549,7 @@ public:
void Serialize (FArchive &arc);
static AActor *StaticSpawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
static AActor *StaticSpawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false);
inline AActor *GetDefault () const
{
@ -561,6 +570,7 @@ public:
// BeginPlay: Called just after the actor is created
virtual void BeginPlay ();
virtual void PostBeginPlay ();
// LevelSpawned: Called after BeginPlay if this actor was spawned by the world
virtual void LevelSpawned ();
// Translates SpawnFlags into in-game flags.
@ -602,7 +612,7 @@ public:
virtual bool SpecialBlastHandling (AActor *source, fixed_t strength);
// Called by RoughBlockCheck
virtual bool IsOkayToAttack (AActor *target);
bool IsOkayToAttack (AActor *target);
// Plays the actor's ActiveSound if its voice isn't already making noise.
void PlayActiveSound ();
@ -773,6 +783,8 @@ public:
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
fixed_t SpawnPoint[3]; // For nightmare respawn
WORD SpawnAngle;
BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions.
BYTE WeaveIndexZ;
int skillrespawncount;
int TIDtoHate; // TID of things to hate (0 if none)
FNameNoInit Species; // For monster families
@ -782,7 +794,6 @@ public:
int tid; // thing identifier
int special; // special
int args[5]; // special arguments
int uservar[10]; // user variables, accessible by DECORATE and ACS
AActor *inext, **iprev;// Links to other mobjs in same bucket
TObjPtr<AActor> goal; // Monster's goal if not chasing anything
@ -805,6 +816,7 @@ public:
fixed_t pushfactor;
int lastpush;
int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL
int lastbump; // Last time the actor was bumped, used to control BUMPSPECIAL
int Score; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything.
FNameNoInit Tag; // Strife's tag name. FIXME: should be case sensitive!
@ -840,7 +852,9 @@ public:
fixed_t MaxDropOffHeight, MaxStepHeight;
SDWORD Mass;
SWORD PainChance;
int PainThreshold;
FNameNoInit DamageType;
fixed_t DamageFactor;
FState *SpawnState;
FState *SeeState;
@ -855,6 +869,7 @@ public:
// [RH] Used to interpolate the view to get >35 FPS
fixed_t PrevX, PrevY, PrevZ;
angle_t PrevAngle;
// ThingIDs
static void ClearTIDHashes ();
@ -894,7 +909,6 @@ public:
return GetClass()->ActorInfo->FindState(2, names, exact);
}
bool HasSpecialDeathStates () const;
};
@ -967,6 +981,7 @@ inline AActor *Spawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, repla
}
AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
template<class T>
inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)

View file

@ -167,6 +167,7 @@ CVAR (Color, am_ovtelecolor, 0xffff00, CVAR_ARCHIVE);
CVAR (Color, am_intralevelcolor, 0x0000ff, CVAR_ARCHIVE);
CVAR (Color, am_interlevelcolor, 0xff0000, CVAR_ARCHIVE);
CVAR (Color, am_secretsectorcolor, 0xff00ff, CVAR_ARCHIVE);
CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE);
CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE);
CVAR (Bool, am_drawmapback, true, CVAR_ARCHIVE);
CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE);
@ -413,14 +414,24 @@ void AM_getIslope (mline_t *ml, islope_t *is)
}
*/
//=============================================================================
//
// called by the coordinate drawer
//
//=============================================================================
void AM_GetPosition(fixed_t &x, fixed_t &y)
{
x = (m_x + m_w/2) << FRACTOMAPBITS;
y = (m_y + m_h/2) << FRACTOMAPBITS;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_activateNewScale ()
{
m_x += m_w/2;
@ -433,9 +444,12 @@ void AM_activateNewScale ()
m_y2 = m_y + m_h;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_saveScaleAndLoc ()
{
old_m_x = m_x;
@ -444,9 +458,12 @@ void AM_saveScaleAndLoc ()
old_m_h = m_h;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_restoreScaleAndLoc ()
{
m_w = old_m_w;
@ -469,9 +486,12 @@ void AM_restoreScaleAndLoc ()
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
}
//=============================================================================
//
// adds a marker at the current location
//
//=============================================================================
bool AM_addMark ()
{
if (marknums[0].isValid())
@ -484,10 +504,13 @@ bool AM_addMark ()
return false;
}
//=============================================================================
//
// Determines bounding box of all vertices,
// sets global variables controlling zoom range.
//
//=============================================================================
static void AM_findMinMaxBoundaries ()
{
min_x = min_y = FIXED_MAX;
@ -515,6 +538,12 @@ static void AM_findMinMaxBoundaries ()
AM_calcMinMaxMtoF();
}
//=============================================================================
//
//
//
//=============================================================================
static void AM_calcMinMaxMtoF()
{
fixed_t a = MapDiv (SCREENWIDTH << MAPBITS, max_w);
@ -524,6 +553,12 @@ static void AM_calcMinMaxMtoF()
max_scale_mtof = MapDiv (SCREENHEIGHT << MAPBITS, 2*PLAYERRADIUS);
}
//=============================================================================
//
//
//
//=============================================================================
static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty)
{
if (am_rotate == 0 || (am_rotate == 2 && !viewactive))
@ -588,6 +623,12 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty)
m_y2 = m_y + m_h;
}
//=============================================================================
//
//
//
//=============================================================================
static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy)
{
mapxstart -= MulScale12 (dmapx, scale_mtof);
@ -614,9 +655,12 @@ static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy)
}
}
//=============================================================================
//
//
//
//=============================================================================
void AM_changeWindowLoc ()
{
if (0 != (m_paninc.x | m_paninc.y))
@ -646,9 +690,12 @@ void AM_changeWindowLoc ()
}
//=============================================================================
//
//
//
//=============================================================================
void AM_initVariables ()
{
int pnum;
@ -694,6 +741,11 @@ static void GetComponents (int color, DWORD *palette, float &r, float &g, float
}
*/
//=============================================================================
//
//
//
//=============================================================================
static void AM_initColors (bool overlayed)
{
@ -719,7 +771,8 @@ static void AM_initColors (bool overlayed)
{
YourColor.FromCVar (am_ovyourcolor);
WallColor.FromCVar (am_ovwallcolor);
SecretSectorColor = SecretWallColor = WallColor;
SecretWallColor = WallColor;
SecretSectorColor.FromCVar (am_ovsecretsectorcolor);
ThingColor_Item.FromCVar (am_ovthingcolor_item);
ThingColor_Friend.FromCVar (am_ovthingcolor_friend);
ThingColor_Monster.FromCVar (am_ovthingcolor_monster);
@ -840,9 +893,12 @@ static void AM_initColors (bool overlayed)
lastpal = palette;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_loadPics ()
{
int i;
@ -859,6 +915,12 @@ void AM_loadPics ()
mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch);
}
//=============================================================================
//
//
//
//=============================================================================
bool AM_clearMarks ()
{
for (int i = AM_NUMMARKPOINTS-1; i >= 0; i--)
@ -867,9 +929,12 @@ bool AM_clearMarks ()
return marknums[0].isValid();
}
//=============================================================================
//
// called right after the level has been loaded
//
//=============================================================================
void AM_LevelInit ()
{
leveljuststarted = 0;
@ -883,9 +948,12 @@ void AM_LevelInit ()
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
}
//=============================================================================
//
//
//
//=============================================================================
void AM_Stop ()
{
automapactive = false;
@ -894,9 +962,12 @@ void AM_Stop ()
viewactive = true;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_Start ()
{
if (!stopped) AM_Stop();
@ -907,27 +978,36 @@ void AM_Start ()
//=============================================================================
//
// set the window scale to the maximum size
//
//=============================================================================
void AM_minOutWindowScale ()
{
scale_mtof = min_scale_mtof;
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
}
//=============================================================================
//
// set the window scale to the minimum size
//
//=============================================================================
void AM_maxOutWindowScale ()
{
scale_mtof = max_scale_mtof;
scale_ftom = MapDiv(MAPUNIT, scale_mtof);
}
//=============================================================================
//
// Called right after the resolution has changed
//
//=============================================================================
void AM_NewResolution()
{
fixed_t oldmin = min_scale_mtof;
@ -949,11 +1029,23 @@ void AM_NewResolution()
}
//=============================================================================
//
//
//
//=============================================================================
CCMD (togglemap)
{
gameaction = ga_togglemap;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_ToggleMap ()
{
if (gamestate != GS_LEVEL)
@ -983,9 +1075,12 @@ void AM_ToggleMap ()
}
}
//=============================================================================
//
// Handle events (user inputs) in automap mode
//
//=============================================================================
bool AM_Responder (event_t *ev)
{
bool rc;
@ -1110,9 +1205,12 @@ bool AM_Responder (event_t *ev)
}
//=============================================================================
//
// Zooming
//
//=============================================================================
void AM_changeWindowScale ()
{
// Change the scaling multipliers
@ -1126,9 +1224,12 @@ void AM_changeWindowScale ()
}
//=============================================================================
//
//
//
//=============================================================================
void AM_doFollowPlayer ()
{
fixed_t sx, sy;
@ -1156,6 +1257,12 @@ void AM_doFollowPlayer ()
}
}
//=============================================================================
//
//
//
//=============================================================================
static void AM_ToggleFollowPlayer()
{
followplayer = !followplayer;
@ -1163,9 +1270,12 @@ static void AM_ToggleFollowPlayer()
Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF"));
}
//=============================================================================
//
// Updates on Game Tick
//
//=============================================================================
void AM_Ticker ()
{
if (!automapactive)
@ -1186,9 +1296,12 @@ void AM_Ticker ()
}
//=============================================================================
//
// Clear automap frame buffer.
//
//=============================================================================
void AM_clearFB (const AMColor &color)
{
if (!mapback.isValid() || !am_drawmapback)
@ -1217,6 +1330,7 @@ void AM_clearFB (const AMColor &color)
}
//=============================================================================
//
// Automap clipping of lines.
//
@ -1224,6 +1338,8 @@ void AM_clearFB (const AMColor &color)
// faster reject and precalculated slopes. If the speed is needed,
// use a hash algorithm to handle the common cases.
//
//=============================================================================
bool AM_clipMline (mline_t *ml, fline_t *fl)
{
enum {
@ -1345,9 +1461,12 @@ bool AM_clipMline (mline_t *ml, fline_t *fl)
#undef DOOUTCODE
//=============================================================================
//
// Clip lines, draw visible parts of lines.
//
//=============================================================================
void AM_drawMline (mline_t *ml, const AMColor &color)
{
fline_t fl;
@ -1358,11 +1477,12 @@ void AM_drawMline (mline_t *ml, const AMColor &color)
}
}
//=============================================================================
//
// Draws flat (floor/ceiling tile) aligned grid lines.
//
//=============================================================================
void AM_drawGrid (const AMColor &color)
{
fixed_t x, y;
@ -1425,6 +1545,12 @@ void AM_drawGrid (const AMColor &color)
}
}
//=============================================================================
//
//
//
//=============================================================================
static bool AM_CheckSecret(line_t *line)
{
if (line->frontsector != NULL)
@ -1445,10 +1571,15 @@ static bool AM_CheckSecret(line_t *line)
}
return false;
}
//=============================================================================
//
// Determines visible lines, draws them.
// This is LineDef based, not LineSeg based.
//
//=============================================================================
void AM_drawWalls (bool allmap)
{
int i;
@ -1556,10 +1687,13 @@ void AM_drawWalls (bool allmap)
}
//=============================================================================
//
// Rotation in 2D.
// Used to rotate player arrow line character.
//
//=============================================================================
void AM_rotate (fixed_t *x, fixed_t *y, angle_t a)
{
fixed_t tmpx;
@ -1570,6 +1704,12 @@ void AM_rotate (fixed_t *x, fixed_t *y, angle_t a)
*x = tmpx;
}
//=============================================================================
//
//
//
//=============================================================================
void AM_rotatePoint (fixed_t *x, fixed_t *y)
{
fixed_t pivotx = m_x + m_w/2;
@ -1581,6 +1721,12 @@ void AM_rotatePoint (fixed_t *x, fixed_t *y)
*y += pivoty;
}
//=============================================================================
//
//
//
//=============================================================================
void
AM_drawLineCharacter
( const mline_t *lineguy,
@ -1627,6 +1773,12 @@ AM_drawLineCharacter
}
}
//=============================================================================
//
//
//
//=============================================================================
void AM_drawPlayers ()
{
mpoint_t pt;
@ -1723,6 +1875,12 @@ void AM_drawPlayers ()
}
}
//=============================================================================
//
//
//
//=============================================================================
void AM_drawThings ()
{
AMColor color;
@ -1777,6 +1935,12 @@ void AM_drawThings ()
}
}
//=============================================================================
//
//
//
//=============================================================================
static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust,
INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD fillcolor, FRenderStyle renderstyle)
{
@ -1803,6 +1967,12 @@ static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust,
TAG_DONE);
}
//=============================================================================
//
//
//
//=============================================================================
void AM_drawMarks ()
{
for (int i = 0; i < AM_NUMMARKPOINTS; i++)
@ -1815,6 +1985,12 @@ void AM_drawMarks ()
}
}
//=============================================================================
//
//
//
//=============================================================================
void AM_drawAuthorMarkers ()
{
// [RH] Draw any actors derived from AMapMarker on the automap.
@ -1876,11 +2052,23 @@ void AM_drawAuthorMarkers ()
}
}
//=============================================================================
//
//
//
//=============================================================================
void AM_drawCrosshair (const AMColor &color)
{
screen->DrawPixel(f_w/2, (f_h+1)/2, color.Index, color.RGB);
}
//=============================================================================
//
//
//
//=============================================================================
void AM_Drawer ()
{
if (!automapactive)
@ -1928,6 +2116,12 @@ void AM_Drawer ()
AM_drawMarks();
}
//=============================================================================
//
//
//
//=============================================================================
void AM_SerializeMarkers(FArchive &arc)
{
arc << markpointnum;

View file

@ -623,10 +623,6 @@ rdcp1: sub edi,SPACEFILLER4
cmp BYTE [CPU+66],byte 5
jg rdcploop2
; need 12 bytes of filler to make it aligned
db 0x8D,0x80,0,0,0,0 ; lea eax,[eax+00000000]
db 0x8D,0xBF,0,0,0,0 ; lea edi,[edi+00000000]
align 16
; The registers should now look like this:

View file

@ -15,121 +15,123 @@
#define __forceinline inline
#endif
__forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
static __forceinline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a*b)/c);
}
__forceinline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
static __forceinline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a*b)>>c);
}
__forceinline SDWORD MulScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 1); }
__forceinline SDWORD MulScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 2); }
__forceinline SDWORD MulScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 3); }
__forceinline SDWORD MulScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 4); }
__forceinline SDWORD MulScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 5); }
__forceinline SDWORD MulScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 6); }
__forceinline SDWORD MulScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 7); }
__forceinline SDWORD MulScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 8); }
__forceinline SDWORD MulScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 9); }
__forceinline SDWORD MulScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 10); }
__forceinline SDWORD MulScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 11); }
__forceinline SDWORD MulScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 12); }
__forceinline SDWORD MulScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 13); }
__forceinline SDWORD MulScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 14); }
__forceinline SDWORD MulScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 15); }
__forceinline SDWORD MulScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 16); }
__forceinline SDWORD MulScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 17); }
__forceinline SDWORD MulScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 18); }
__forceinline SDWORD MulScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 19); }
__forceinline SDWORD MulScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 20); }
__forceinline SDWORD MulScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 21); }
__forceinline SDWORD MulScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 22); }
__forceinline SDWORD MulScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 23); }
__forceinline SDWORD MulScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 24); }
__forceinline SDWORD MulScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 25); }
__forceinline SDWORD MulScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 26); }
__forceinline SDWORD MulScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 27); }
__forceinline SDWORD MulScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 28); }
__forceinline SDWORD MulScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 29); }
__forceinline SDWORD MulScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 30); }
__forceinline SDWORD MulScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 31); }
__forceinline SDWORD MulScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 32); }
static __forceinline SDWORD MulScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 1); }
static __forceinline SDWORD MulScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 2); }
static __forceinline SDWORD MulScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 3); }
static __forceinline SDWORD MulScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 4); }
static __forceinline SDWORD MulScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 5); }
static __forceinline SDWORD MulScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 6); }
static __forceinline SDWORD MulScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 7); }
static __forceinline SDWORD MulScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 8); }
static __forceinline SDWORD MulScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 9); }
static __forceinline SDWORD MulScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 10); }
static __forceinline SDWORD MulScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 11); }
static __forceinline SDWORD MulScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 12); }
static __forceinline SDWORD MulScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 13); }
static __forceinline SDWORD MulScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 14); }
static __forceinline SDWORD MulScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 15); }
static __forceinline SDWORD MulScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 16); }
static __forceinline SDWORD MulScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 17); }
static __forceinline SDWORD MulScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 18); }
static __forceinline SDWORD MulScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 19); }
static __forceinline SDWORD MulScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 20); }
static __forceinline SDWORD MulScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 21); }
static __forceinline SDWORD MulScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 22); }
static __forceinline SDWORD MulScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 23); }
static __forceinline SDWORD MulScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 24); }
static __forceinline SDWORD MulScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 25); }
static __forceinline SDWORD MulScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 26); }
static __forceinline SDWORD MulScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 27); }
static __forceinline SDWORD MulScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 28); }
static __forceinline SDWORD MulScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 29); }
static __forceinline SDWORD MulScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 30); }
static __forceinline SDWORD MulScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 31); }
static __forceinline SDWORD MulScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a * b) >> 32); }
__forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
static __forceinline DWORD UMulScale16 (DWORD a, DWORD b) { return (DWORD)(((QWORD)a * b) >> 16); }
static __forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
{
return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> s);
}
__forceinline SDWORD DMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 1); }
__forceinline SDWORD DMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 2); }
__forceinline SDWORD DMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 3); }
__forceinline SDWORD DMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 4); }
__forceinline SDWORD DMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 5); }
__forceinline SDWORD DMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 6); }
__forceinline SDWORD DMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 7); }
__forceinline SDWORD DMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 8); }
__forceinline SDWORD DMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 9); }
__forceinline SDWORD DMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 10); }
__forceinline SDWORD DMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 11); }
__forceinline SDWORD DMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 12); }
__forceinline SDWORD DMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 13); }
__forceinline SDWORD DMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 14); }
__forceinline SDWORD DMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 15); }
__forceinline SDWORD DMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 16); }
__forceinline SDWORD DMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 17); }
__forceinline SDWORD DMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 18); }
__forceinline SDWORD DMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 19); }
__forceinline SDWORD DMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 20); }
__forceinline SDWORD DMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 21); }
__forceinline SDWORD DMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 22); }
__forceinline SDWORD DMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 23); }
__forceinline SDWORD DMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 24); }
__forceinline SDWORD DMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 25); }
__forceinline SDWORD DMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 26); }
__forceinline SDWORD DMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 27); }
__forceinline SDWORD DMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 28); }
__forceinline SDWORD DMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 29); }
__forceinline SDWORD DMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 30); }
__forceinline SDWORD DMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 31); }
__forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 32); }
static __forceinline SDWORD DMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 1); }
static __forceinline SDWORD DMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 2); }
static __forceinline SDWORD DMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 3); }
static __forceinline SDWORD DMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 4); }
static __forceinline SDWORD DMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 5); }
static __forceinline SDWORD DMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 6); }
static __forceinline SDWORD DMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 7); }
static __forceinline SDWORD DMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 8); }
static __forceinline SDWORD DMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 9); }
static __forceinline SDWORD DMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 10); }
static __forceinline SDWORD DMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 11); }
static __forceinline SDWORD DMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 12); }
static __forceinline SDWORD DMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 13); }
static __forceinline SDWORD DMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 14); }
static __forceinline SDWORD DMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 15); }
static __forceinline SDWORD DMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 16); }
static __forceinline SDWORD DMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 17); }
static __forceinline SDWORD DMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 18); }
static __forceinline SDWORD DMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 19); }
static __forceinline SDWORD DMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 20); }
static __forceinline SDWORD DMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 21); }
static __forceinline SDWORD DMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 22); }
static __forceinline SDWORD DMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 23); }
static __forceinline SDWORD DMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 24); }
static __forceinline SDWORD DMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 25); }
static __forceinline SDWORD DMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 26); }
static __forceinline SDWORD DMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 27); }
static __forceinline SDWORD DMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 28); }
static __forceinline SDWORD DMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 29); }
static __forceinline SDWORD DMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 30); }
static __forceinline SDWORD DMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 31); }
static __forceinline SDWORD DMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d) >> 32); }
__forceinline SDWORD TMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 1); }
__forceinline SDWORD TMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 2); }
__forceinline SDWORD TMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 3); }
__forceinline SDWORD TMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 4); }
__forceinline SDWORD TMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 5); }
__forceinline SDWORD TMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 6); }
__forceinline SDWORD TMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 7); }
__forceinline SDWORD TMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 8); }
__forceinline SDWORD TMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 9); }
__forceinline SDWORD TMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 10); }
__forceinline SDWORD TMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 11); }
__forceinline SDWORD TMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 12); }
__forceinline SDWORD TMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 13); }
__forceinline SDWORD TMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 14); }
__forceinline SDWORD TMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 15); }
__forceinline SDWORD TMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 16); }
__forceinline SDWORD TMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 17); }
__forceinline SDWORD TMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 18); }
__forceinline SDWORD TMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 19); }
__forceinline SDWORD TMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 20); }
__forceinline SDWORD TMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 21); }
__forceinline SDWORD TMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 22); }
__forceinline SDWORD TMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 23); }
__forceinline SDWORD TMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 24); }
__forceinline SDWORD TMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 25); }
__forceinline SDWORD TMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 26); }
__forceinline SDWORD TMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 27); }
__forceinline SDWORD TMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 28); }
__forceinline SDWORD TMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 29); }
__forceinline SDWORD TMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 30); }
__forceinline SDWORD TMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 31); }
__forceinline SDWORD TMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 32); }
static __forceinline SDWORD TMulScale1 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 1); }
static __forceinline SDWORD TMulScale2 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 2); }
static __forceinline SDWORD TMulScale3 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 3); }
static __forceinline SDWORD TMulScale4 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 4); }
static __forceinline SDWORD TMulScale5 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 5); }
static __forceinline SDWORD TMulScale6 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 6); }
static __forceinline SDWORD TMulScale7 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 7); }
static __forceinline SDWORD TMulScale8 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 8); }
static __forceinline SDWORD TMulScale9 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 9); }
static __forceinline SDWORD TMulScale10 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 10); }
static __forceinline SDWORD TMulScale11 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 11); }
static __forceinline SDWORD TMulScale12 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 12); }
static __forceinline SDWORD TMulScale13 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 13); }
static __forceinline SDWORD TMulScale14 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 14); }
static __forceinline SDWORD TMulScale15 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 15); }
static __forceinline SDWORD TMulScale16 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 16); }
static __forceinline SDWORD TMulScale17 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 17); }
static __forceinline SDWORD TMulScale18 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 18); }
static __forceinline SDWORD TMulScale19 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 19); }
static __forceinline SDWORD TMulScale20 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 20); }
static __forceinline SDWORD TMulScale21 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 21); }
static __forceinline SDWORD TMulScale22 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 22); }
static __forceinline SDWORD TMulScale23 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 23); }
static __forceinline SDWORD TMulScale24 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 24); }
static __forceinline SDWORD TMulScale25 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 25); }
static __forceinline SDWORD TMulScale26 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 26); }
static __forceinline SDWORD TMulScale27 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 27); }
static __forceinline SDWORD TMulScale28 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 28); }
static __forceinline SDWORD TMulScale29 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 29); }
static __forceinline SDWORD TMulScale30 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 30); }
static __forceinline SDWORD TMulScale31 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 31); }
static __forceinline SDWORD TMulScale32 (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD f) { return (SDWORD)(((SQWORD)a*b + (SQWORD)c*d + (SQWORD)e*f) >> 32); }
__forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
static __forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
{
SQWORD x = ((SQWORD)a * b) >> c;
return x > 0x7FFFFFFFll ? 0x7FFFFFFF :
@ -137,45 +139,45 @@ __forceinline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
(SDWORD)x;
}
inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
{
return (SDWORD)(((SQWORD)a << c) / b);
}
inline SDWORD DivScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 1) / b); }
inline SDWORD DivScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 2) / b); }
inline SDWORD DivScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 3) / b); }
inline SDWORD DivScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 4) / b); }
inline SDWORD DivScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 5) / b); }
inline SDWORD DivScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 6) / b); }
inline SDWORD DivScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 7) / b); }
inline SDWORD DivScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 8) / b); }
inline SDWORD DivScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 9) / b); }
inline SDWORD DivScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 10) / b); }
inline SDWORD DivScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 11) / b); }
inline SDWORD DivScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 12) / b); }
inline SDWORD DivScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 13) / b); }
inline SDWORD DivScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 14) / b); }
inline SDWORD DivScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 15) / b); }
inline SDWORD DivScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 16) / b); }
inline SDWORD DivScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 17) / b); }
inline SDWORD DivScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 18) / b); }
inline SDWORD DivScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 19) / b); }
inline SDWORD DivScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 20) / b); }
inline SDWORD DivScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 21) / b); }
inline SDWORD DivScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 22) / b); }
inline SDWORD DivScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 23) / b); }
inline SDWORD DivScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 24) / b); }
inline SDWORD DivScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 25) / b); }
inline SDWORD DivScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 26) / b); }
inline SDWORD DivScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 27) / b); }
inline SDWORD DivScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 28) / b); }
inline SDWORD DivScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 29) / b); }
inline SDWORD DivScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 30) / b); }
inline SDWORD DivScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 31) / b); }
inline SDWORD DivScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 32) / b); }
static inline SDWORD DivScale1 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 1) / b); }
static inline SDWORD DivScale2 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 2) / b); }
static inline SDWORD DivScale3 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 3) / b); }
static inline SDWORD DivScale4 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 4) / b); }
static inline SDWORD DivScale5 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 5) / b); }
static inline SDWORD DivScale6 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 6) / b); }
static inline SDWORD DivScale7 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 7) / b); }
static inline SDWORD DivScale8 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 8) / b); }
static inline SDWORD DivScale9 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 9) / b); }
static inline SDWORD DivScale10 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 10) / b); }
static inline SDWORD DivScale11 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 11) / b); }
static inline SDWORD DivScale12 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 12) / b); }
static inline SDWORD DivScale13 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 13) / b); }
static inline SDWORD DivScale14 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 14) / b); }
static inline SDWORD DivScale15 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 15) / b); }
static inline SDWORD DivScale16 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 16) / b); }
static inline SDWORD DivScale17 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 17) / b); }
static inline SDWORD DivScale18 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 18) / b); }
static inline SDWORD DivScale19 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 19) / b); }
static inline SDWORD DivScale20 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 20) / b); }
static inline SDWORD DivScale21 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 21) / b); }
static inline SDWORD DivScale22 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 22) / b); }
static inline SDWORD DivScale23 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 23) / b); }
static inline SDWORD DivScale24 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 24) / b); }
static inline SDWORD DivScale25 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 25) / b); }
static inline SDWORD DivScale26 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 26) / b); }
static inline SDWORD DivScale27 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 27) / b); }
static inline SDWORD DivScale28 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 28) / b); }
static inline SDWORD DivScale29 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 29) / b); }
static inline SDWORD DivScale30 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 30) / b); }
static inline SDWORD DivScale31 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 31) / b); }
static inline SDWORD DivScale32 (SDWORD a, SDWORD b) { return (SDWORD)(((SQWORD)a << 32) / b); }
__forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
static __forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
{
SDWORD *b2 = (SDWORD *)buff;
for (unsigned int i = 0; i != count; ++i)
@ -184,7 +186,7 @@ __forceinline void clearbuf (void *buff, unsigned int count, SDWORD clear)
}
}
__forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
static __forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
{
SWORD *b2 = (SWORD *)buff;
for (unsigned int i = 0; i != count; ++i)
@ -193,19 +195,9 @@ __forceinline void clearbufshort (void *buff, unsigned int count, WORD clear)
}
}
__forceinline SDWORD ksgn (SDWORD a)
static __forceinline SDWORD ksgn (SDWORD a)
{
if (a < 0) return -1;
else if (a > 0) return 1;
else return 0;
}
__forceinline int toint (float v)
{
return int(v);
}
__forceinline int quickertoint (float v)
{
return int(v);
}

View file

@ -23,6 +23,10 @@ typedef int64_t SQWORD;
typedef uint64_t QWORD;
#endif
typedef SDWORD int32;
typedef float real32;
typedef double real64;
// windef.h, included by windows.h, has its own incompatible definition
// of DWORD as a long. In files that mix Doom and Windows code, you
// must define USE_WINDOWS_DWORD before including doomtype.h so that

View file

@ -159,8 +159,8 @@ static const FBinding DefHexenBindings[] =
{ "9", "use ArtiBlastRadius" },
{ "8", "use ArtiTeleport" },
{ "7", "use ArtiTeleportOther" },
{ "6", "use ArtiEgg" },
{ "5", "use ArtiInvulnerability" },
{ "6", "use ArtiPork" },
{ "5", "use ArtiInvulnerability2" },
{ "scroll", "+showscores" },
{ NULL }
};

View file

@ -253,7 +253,7 @@ CCMD (chase)
CCMD (idclev)
{
if (CheckCheatmode () || netgame)
if (netgame)
return;
if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1])
@ -291,7 +291,7 @@ CCMD (idclev)
CCMD (hxvisit)
{
if (CheckCheatmode ())
if (netgame)
return;
if ((argv.argc() > 1) && (*(argv[1] + 2) == 0) && *(argv[1] + 1) && *argv[1])

View file

@ -1824,8 +1824,8 @@ CCMD (echo)
int last = argv.argc()-1;
for (int i = 1; i <= last; ++i)
{
strbin (argv[i]);
Printf ("%s%s", argv[i], i!=last ? " " : "\n");
FString formatted = strbin1 (argv[i]);
Printf ("%s%s", formatted.GetChars(), i!=last ? " " : "\n");
}
}
@ -1843,7 +1843,7 @@ static const char logbar[] = "\n<------------------------------->\n";
void C_MidPrint (FFont *font, const char *msg)
{
if (StatusBar == NULL)
if (StatusBar == NULL || screen == NULL)
return;
if (msg != NULL)

View file

@ -1376,6 +1376,7 @@ void FConsoleAlias::SafeDelete ()
static BYTE PullinBad = 2;
static const char *PullinFile;
extern TArray<FString> allwads;
int C_ExecFile (const char *file, bool usePullin)
{
@ -1492,7 +1493,7 @@ CCMD (pullin)
FixPathSeperator (path);
}
}
D_AddFile (path);
D_AddFile (allwads, path);
if (path != argv[i])
{
delete[] path;

View file

@ -105,6 +105,7 @@ static FCompatOption Options[] =
{ "mbfmonstermove", COMPATF_MBFMONSTERMOVE, 0 },
{ "corpsegibs", COMPATF_CORPSEGIBS, 0 },
{ "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 },
{ "spritesort", COMPATF_SPRITESORT, 0 },
{ NULL, 0, 0 }
};
@ -196,7 +197,7 @@ void CheckCompatibility(MapData *map)
FCompatValues *flags;
// When playing Doom IWAD levels force COMPAT_SHORTTEX.
if (Wads.GetLumpFile(map->lumpnum) == 1 && gameinfo.gametype == GAME_Doom && !(level.flags & LEVEL_HEXENFORMAT))
if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATSHORTTEX) && !(level.flags & LEVEL_HEXENFORMAT))
{
ii_compatflags = COMPATF_SHORTTEX;
ib_compatflags = 0;

View file

@ -252,6 +252,7 @@ DehSpriteMappings[] =
#define CHECKKEY(a,b) if (!stricmp (Line1, (a))) (b) = atoi(Line2);
static char *PatchFile, *PatchPt, *PatchName;
static int PatchSize;
static char *Line1, *Line2;
static int dversion, pversion;
static bool including, includenotext;
@ -285,6 +286,7 @@ static int PatchPars (int);
static int PatchCodePtrs (int);
static int PatchMusic (int);
static int DoInclude (int);
static bool DoDehPatch();
static const struct {
const char *name;
@ -426,7 +428,7 @@ static bool ReadChars (char **stuff, int size)
size++;
PatchPt++;
} while (--size);
} while (--size && *PatchPt != 0);
*str = 0;
return true;
@ -523,7 +525,7 @@ static char *igets (void)
{
char *line;
if (*PatchPt == '\0')
if (*PatchPt == '\0' || PatchPt >= PatchFile + PatchSize )
return NULL;
line = PatchPt;
@ -2203,7 +2205,7 @@ static int PatchStrings (int dummy)
static int DoInclude (int dummy)
{
char *data;
int savedversion, savepversion;
int savedversion, savepversion, savepatchsize;
char *savepatchfile, *savepatchpt, *savepatchname;
if (including)
@ -2238,6 +2240,7 @@ static int DoInclude (int dummy)
savepatchname = PatchName;
savepatchfile = PatchFile;
savepatchpt = PatchPt;
savepatchsize = PatchSize;
savedversion = dversion;
savepversion = pversion;
including = true;
@ -2260,7 +2263,7 @@ static int DoInclude (int dummy)
}
}
DoDehPatch (path, false);
D_LoadDehFile(path);
if (data != path)
{
@ -2271,6 +2274,7 @@ static int DoInclude (int dummy)
PatchName = savepatchname;
PatchFile = savepatchfile;
PatchPt = savepatchpt;
PatchSize = savepatchsize;
dversion = savedversion;
pversion = savepversion;
}
@ -2280,105 +2284,70 @@ static int DoInclude (int dummy)
return GetLine();
}
void DoDehPatch (const char *patchfile, bool autoloading, int lump)
int D_LoadDehLumps()
{
char file[256];
int cont;
int filelen = 0; // Be quiet, gcc
int lastlump = 0, lumpnum, count = 0;
PatchFile = NULL;
PatchName = NULL;
if (lump < 0)
while ((lumpnum = Wads.FindLump("DEHACKED", &lastlump)) >= 0)
{
lump = Wads.CheckNumForName ("DEHACKED");
count += D_LoadDehLump(lumpnum);
}
return count;
}
if (lump >= 0 && autoloading)
bool D_LoadDehLump(int lumpnum)
{
PatchSize = Wads.LumpLength(lumpnum);
PatchName = copystring(Wads.GetLumpFullPath(lumpnum));
PatchFile = new char[PatchSize + 1];
Wads.ReadLump(lumpnum, PatchFile);
PatchFile[PatchSize] = '\0'; // terminate with a '\0' character
return DoDehPatch();
}
bool D_LoadDehFile(const char *patchfile)
{
FILE *deh;
deh = fopen(patchfile, "rb");
if (deh != NULL)
{
// Execute the DEHACKED lump as a patch.
strcpy (file, "DEHACKED lump");
filelen = Wads.LumpLength (lump);
if ( (PatchFile = new char[filelen + 1]) )
{
Wads.ReadLump (lump, PatchFile);
}
else
{
Printf ("Not enough memory to apply patch\n");
return;
}
}
else if (patchfile)
{
// Try to use patchfile as a patch.
FILE *deh;
PatchSize = Q_filelength(deh);
strcpy (file, patchfile);
FixPathSeperator (file);
DefaultExtension (file, ".deh");
if ( !(deh = fopen (file, "rb")) )
{
strcpy (file, patchfile);
FixPathSeperator (file);
DefaultExtension (file, ".bex");
deh = fopen (file, "rb");
}
if (deh)
{
filelen = Q_filelength (deh);
if ( (PatchFile = new char[filelen + 1]) )
{
fread (PatchFile, 1, filelen, deh);
fclose (deh);
PatchName = copystring (patchfile);
FixPathSeperator (PatchName);
}
}
if (!PatchFile)
{
// Couldn't find it on disk, try reading it from a lump
lump = Wads.CheckNumForFullName(patchfile, true);
if (lump == -1)
{
// Compatibility fallback. It's just here because
// some WAD may need it. Should be deleted it it can
// be confirmed that nothing uses this case.
FString filebase(ExtractFileBase (patchfile));
lump = Wads.CheckNumForName (filebase);
}
if (lump >= 0)
{
filelen = Wads.LumpLength (lump);
if ( (PatchFile = new char[filelen + 1]) )
{
Wads.ReadLump (lump, PatchFile);
}
else
{
Printf ("Not enough memory to apply patch\n");
return;
}
}
}
if (!PatchFile)
{
Printf ("Could not open DeHackEd patch \"%s\"\n", file);
return;
}
PatchName = copystring(patchfile);
PatchFile = new char[PatchSize + 1];
fread(PatchFile, 1, PatchSize, deh);
fclose(deh);
PatchFile[PatchSize] = '\0'; // terminate with a '\0' character
return DoDehPatch();
}
else
{
// Nothing to do.
return;
// Couldn't find it in the filesystem; try from a lump instead.
int lumpnum = Wads.CheckNumForFullName(patchfile, true);
if (lumpnum < 0)
{
// Compatibility fallback. It's just here because
// some WAD may need it. Should be deleted if it can
// be confirmed that nothing uses this case.
FString filebase(ExtractFileBase(patchfile));
lumpnum = Wads.CheckNumForName(filebase);
}
if (lumpnum >= 0)
{
return D_LoadDehLump(lumpnum);
}
}
Printf ("Could not open DeHackEd patch \"%s\"\n", patchfile);
return false;
}
// End file with a NULL for our parser
PatchFile[filelen] = 0;
static bool DoDehPatch()
{
Printf("Adding dehacked patch %s\n", PatchName);
int cont;
dversion = pversion = -1;
cont = 0;
@ -2386,10 +2355,10 @@ void DoDehPatch (const char *patchfile, bool autoloading, int lump)
{
if (PatchFile[25] < '3')
{
if (PatchName != NULL) delete[] PatchName;
delete[] PatchName;
delete[] PatchFile;
Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", file);
return;
Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchFile);
return false;
}
PatchPt = strchr (PatchFile, '\n');
while ((cont = GetLine()) == 1)
@ -2399,10 +2368,10 @@ void DoDehPatch (const char *patchfile, bool autoloading, int lump)
}
if (!cont || dversion == -1 || pversion == -1)
{
if (PatchName != NULL) delete[] PatchName;
delete[] PatchName;
delete[] PatchFile;
Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", file);
return;
Printf (PRINT_BOLD, "\"%s\" is not a DeHackEd patch file\n", PatchFile);
return false;
}
}
else
@ -2412,7 +2381,7 @@ void DoDehPatch (const char *patchfile, bool autoloading, int lump)
pversion = 6;
PatchPt = PatchFile;
while ((cont = GetLine()) == 1)
;
{}
}
if (pversion != 6)
@ -2439,10 +2408,10 @@ void DoDehPatch (const char *patchfile, bool autoloading, int lump)
if (!LoadDehSupp ())
{
Printf ("Could not load DEH support data\n");
if (PatchName != NULL) delete[] PatchName;
delete[] PatchFile;
UnloadDehSupp ();
return;
delete[] PatchName;
delete[] PatchFile;
return false;
}
do
@ -2459,10 +2428,10 @@ void DoDehPatch (const char *patchfile, bool autoloading, int lump)
} while (cont);
UnloadDehSupp ();
if (PatchName != NULL) delete[] PatchName;
delete[] PatchName;
delete[] PatchFile;
Printf ("Patch installed\n");
return true;
}
static inline bool CompareLabel (const char *want, const BYTE *have)

View file

@ -56,8 +56,9 @@ public:
bool droppedbymonster;
};
void DoDehPatch (const char *patchfile, bool autoloading, int lumpnum=-1);
int D_LoadDehLumps();
bool D_LoadDehLump(int lumpnum);
bool D_LoadDehFile(const char *filename);
void FinishDehPatch ();
#endif //__D_DEHACK_H__

View file

@ -58,18 +58,18 @@ EIWADType gameiwad;
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
{
// banner text, autoname, fg color, bg color
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx },
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx },
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx | GI_COMPATSHORTTEX },
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx | GI_COMPATSHORTTEX },
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_SHAREWARE },
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx | GI_COMPATSHORTTEX },
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
{ "Heretic: Shadow of the Serpent Riders", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt", GI_MENUHACK_EXTENDED },
{ "Heretic", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt" },
{ "DOOM Shareware", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_SHAREWARE },
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/ultdoom.txt" },
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt" },
{ "DOOM Shareware", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_SHAREWARE | GI_COMPATSHORTTEX },
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/ultdoom.txt", GI_COMPATSHORTTEX },
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_COMPATSHORTTEX },
{ "Strife: Quest for the Sigil", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx },
{ "Strife: Teaser (Old Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE },
{ "Strife: Teaser (New Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE | GI_TEASER2 },
@ -77,8 +77,11 @@ const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
{ "Ultimate Freedoom", "Freedoom1",MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom1.txt" },
{ "Freedoom \"Demo\"", NULL, MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom1.txt" },
{ "FreeDM", "FreeDM", MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Blasphemer", "Blasphemer",MAKERGB(115,0,0), MAKERGB(0,0,0), GAME_Heretic, "mapinfo/heretic.txt" },
{ "Chex(R) Quest", "Chex1", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex.txt" },
{ "Chex(R) Quest 3", "Chex3", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex3.txt" },
{ "Action Doom 2: Urban Brawl", "UrbanBrawl",MAKERGB(168,168,0), MAKERGB(168,0,0), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Harmony", "Harmony", MAKERGB(110,180,230), MAKERGB(69,79,126), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
//{ "ZDoom Engine", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168) },
};
@ -104,8 +107,12 @@ static const char *IWADNames[] =
"freedoom1.wad",
"freedoomu.wad",
"freedm.wad",
"blasphem.wad",
"blasphemer.wad",
"chex.wad",
"chex3.wad",
"action2.wad",
"harm1.wad",
#ifdef unix
"DOOM2.WAD", // Also look for all-uppercase names
"PLUTONIA.WAD",
@ -124,8 +131,12 @@ static const char *IWADNames[] =
"FREEDOOM1.WAD",
"FREEDOOMU.WAD",
"FREEDM.WAD",
"BLASPHEM.WAD",
"BLASPHEMER.WAD",
"CHEX.WAD",
"CHEX3.WAD",
"ACTION2.WAD",
"HARM1.WAD",
#endif
NULL
};
@ -141,6 +152,7 @@ static EIWADType ScanIWAD (const char *iwad)
{
static const char checklumps[][8] =
{
"AD2LIB",
"E1M1",
"E4M2",
"MAP01",
@ -154,11 +166,15 @@ static EIWADType ScanIWAD (const char *iwad)
"MAP33",
"INVCURS",
{ 'F','R','E','E','D','O','O','M' },
{ 'B','L','A','S','P','H','E','M' },
"W94_1",
{ 'P','O','S','S','H','0','M','0' },
"CYCLA1",
"FLMBA1",
"MAPINFO",
"0HAWK01",
"0CARA3",
"0NOSE1",
{ 'G','A','M','E','I','N','F','O' },
"E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
@ -166,9 +182,10 @@ static EIWADType ScanIWAD (const char *iwad)
{ 'S','P','I','D','A','1','D','1' },
};
#define NUM_CHECKLUMPS (sizeof(checklumps)/8)
#define NUM_CHECKLUMPS (countof(checklumps))
enum
{
Check_ad2lib,
Check_e1m1,
Check_e4m1,
Check_map01,
@ -182,15 +199,19 @@ static EIWADType ScanIWAD (const char *iwad)
Check_map33,
Check_invcurs,
Check_FreeDoom,
Check_Blasphem,
Check_W94_1,
Check_POSSH0M0,
Check_Cycla1,
Check_Flmba1,
Check_Mapinfo,
Check_Hawk,
Check_Car,
Check_Nose,
Check_Gameinfo,
Check_e2m1
};
int lumpsfound[NUM_CHECKLUMPS];
bool lumpsfound[NUM_CHECKLUMPS];
size_t i;
memset (lumpsfound, 0, sizeof(lumpsfound));
@ -201,10 +222,44 @@ static EIWADType ScanIWAD (const char *iwad)
for(DWORD ii = 0; ii < iwadfile->LumpCount(); ii++)
{
FResourceLump *lump = iwadfile->GetLump(ii);
size_t j;
for (DWORD j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (lump->Name, checklumps[j], 8) == 0)
lumpsfound[j]++;
for (j = 0; j < NUM_CHECKLUMPS; j++)
{
if (!lumpsfound[j])
{
if (strnicmp (lump->Name, checklumps[j], 8) == 0)
{
lumpsfound[j] = true;
break;
}
// Check for maps inside zips, too.
else if (lump->FullName != NULL)
{
if (checklumps[j][0] == 'E' && checklumps[j][2] == 'M' && checklumps[j][4] == '\0')
{
if (strnicmp(lump->FullName, "maps/", 5) == 0 &&
strnicmp(lump->FullName + 5, checklumps[j], 4) == 0 &&
stricmp(lump->FullName + 9, ".wad") == 0)
{
lumpsfound[j] = true;
break;
}
}
else if (checklumps[j][0] == 'M' && checklumps[j][1] == 'A' && checklumps[j][2] == 'P' &&
checklumps[j][5] == '\0')
{
if (strnicmp(lump->FullName, "maps/", 5) == 0 &&
strnicmp(lump->FullName + 5, checklumps[j], 5) == 0 &&
stricmp(lump->FullName + 10, ".wad") == 0)
{
lumpsfound[j] = true;
break;
}
}
}
}
}
}
delete iwadfile;
}
@ -228,16 +283,24 @@ static EIWADType ScanIWAD (const char *iwad)
}
else if (lumpsfound[Check_invcurs])
{
return IWAD_StrifeTeaser2;
return IWAD_StrifeTeaser2; // Strife0.wad from 14 Mar 1996
}
else
{
return IWAD_StrifeTeaser;
return IWAD_StrifeTeaser; // Strife0.wad from 22 Feb 1996
}
}
else if (lumpsfound[Check_map01])
{
if (lumpsfound[Check_FreeDoom])
if (lumpsfound[Check_ad2lib])
{
return IWAD_ActionDoom2;
}
else if (lumpsfound[Check_Hawk] && lumpsfound[Check_Car] && lumpsfound[Check_Nose])
{
return IWAD_Harmony;
}
else if (lumpsfound[Check_FreeDoom])
{
// Is there a 100% reliable way to tell FreeDoom and FreeDM
// apart based solely on the lump names?
@ -287,7 +350,11 @@ static EIWADType ScanIWAD (const char *iwad)
}
else
{
if (lumpsfound[Check_Extended])
if (lumpsfound[Check_Blasphem])
{
return IWAD_Blasphemer;
}
else if (lumpsfound[Check_Extended])
{
return IWAD_HereticExtended;
}
@ -379,8 +446,7 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
FString iwad;
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
FixPathSeperator (iwad.LockBuffer());
iwad.UnlockBuffer();
FixPathSeperator (iwad);
if (FileExists (iwad))
{
wads[i].Type = ScanIWAD (iwad);
@ -417,7 +483,7 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
//
//==========================================================================
static EIWADType IdentifyVersion (const char *zdoom_wad)
static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
{
WadStuff wads[countof(IWADNames)];
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
@ -428,10 +494,15 @@ static EIWADType IdentifyVersion (const char *zdoom_wad)
bool iwadparmfound = false;
FString custwad;
if (iwadparm == NULL && iwad != NULL && *iwad != 0)
{
iwadparm = iwad;
}
if (iwadparm)
{
custwad = iwadparm;
FixPathSeperator (custwad.LockBuffer());
FixPathSeperator (custwad);
if (CheckIWAD (custwad, wads))
{ // -iwad parameter was a directory
iwadparm = NULL;
@ -457,8 +528,7 @@ static EIWADType IdentifyVersion (const char *zdoom_wad)
if (stricmp (key, "Path") == 0)
{
FString nice = NicePath(value);
FixPathSeperator(nice.LockBuffer());
nice.UnlockBuffer();
FixPathSeperator(nice);
CheckIWAD(nice, wads);
}
}
@ -563,14 +633,14 @@ static EIWADType IdentifyVersion (const char *zdoom_wad)
exit (0);
// zdoom.pk3 must always be the first file loaded and the IWAD second.
D_AddFile (zdoom_wad);
D_AddFile (wadfiles, zdoom_wad);
if (wads[pickwad].Type == IWAD_HexenDK)
{ // load hexen.wad before loading hexdd.wad
D_AddFile (wads[foundwads[IWAD_Hexen]-1].Path);
D_AddFile (wadfiles, wads[foundwads[IWAD_Hexen]-1].Path);
}
D_AddFile (wads[pickwad].Path);
D_AddFile (wadfiles, wads[pickwad].Path);
if (wads[pickwad].Type == IWAD_Strife)
{ // Try to load voices.wad along with strife1.wad
@ -586,16 +656,16 @@ static EIWADType IdentifyVersion (const char *zdoom_wad)
path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
}
path += "voices.wad";
D_AddFile (path);
D_AddFile (wadfiles, path);
}
return wads[pickwad].Type;
}
const IWADInfo *D_FindIWAD(const char *basewad)
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad)
{
EIWADType iwadType = IdentifyVersion(basewad);
EIWADType iwadType = IdentifyVersion(wadfiles, iwad, basewad);
gameiwad = iwadType;
const IWADInfo *iwad_info = &IWADInfos[iwadType];
I_SetIWADInfo(iwad_info);

View file

@ -45,6 +45,7 @@
#include <time.h>
#include <math.h>
#include <assert.h>
#include <sys/stat.h>
#include "doomerrors.h"
@ -102,6 +103,8 @@
#include "m_cheat.h"
#include "compatibility.h"
#include "m_joy.h"
#include "sc_man.h"
#include "resourcefiles/resourcefile.h"
EXTERN_CVAR(Bool, hud_althud)
void DrawHUD();
@ -118,7 +121,7 @@ extern void R_ExecuteSetViewSize ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
extern bool CheckCheatmode ();
extern const IWADInfo *D_FindIWAD(const char *basewad);
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -182,7 +185,7 @@ CVAR (Int, wipetype, 1, CVAR_ARCHIVE);
CVAR (Int, snd_drawoutput, 0, 0);
bool DrawFSHUD; // [RH] Draw fullscreen HUD?
wadlist_t *wadfiles; // [RH] remove limit on # of loaded wads
TArray<FString> allwads;
bool devparm; // started game with -devparm
const char *D_DrawIcon; // [RH] Patch name of icon to draw on next refresh
int NoWipe; // [RH] Allow wipe? (Needs to be set each time)
@ -204,7 +207,6 @@ cycle_t FrameCycles;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static wadlist_t **wadtail = &wadfiles;
static int demosequence;
static int pagetic;
@ -492,12 +494,12 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
break;
case 1: // Doom2.exe compatible with a few relaxed settings
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF;
break;
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set)
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS;
break;
@ -546,6 +548,7 @@ CVAR (Flag, compat_mushroom, compatflags, COMPATF_MUSHROOM);
CVAR (Flag, compat_mbfmonstermove,compatflags, COMPATF_MBFMONSTERMOVE);
CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS);
CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS);
CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT);
//==========================================================================
//
@ -560,7 +563,7 @@ void D_Display ()
bool wipe;
bool hw2d;
if (nodrawers)
if (nodrawers || screen == NULL)
return; // for comparative timing / profiling
cycle_t cycles;
@ -860,6 +863,9 @@ void D_DoomLoop ()
{
int lasttic = 0;
// Clamp the timer to TICRATE until the playloop has been entered.
r_NoInterpolate = true;
for (;;)
{
try
@ -950,8 +956,7 @@ void D_PageDrawer (void)
if (Page != NULL)
{
screen->DrawTexture (Page, 0, 0,
DTA_VirtualWidth, Page->GetWidth(),
DTA_VirtualHeight, Page->GetHeight(),
DTA_Fullscreen, true,
DTA_Masked, false,
DTA_BilinearFilter, true,
TAG_DONE);
@ -1041,7 +1046,10 @@ void D_DoStrifeAdvanceDemo ()
pagetic = 7 * TICRATE;
pagename = "PANEL1";
S_Sound (CHAN_VOICE | CHAN_UI, voices[0], 1, ATTN_NORM);
S_StartMusic ("d_intro");
// The new Strife teaser has D_FMINTR.
// The full retail Strife has D_INTRO.
// And the old Strife teaser has both. (I do not know which one it actually uses, nor do I care.)
S_StartMusic (gameinfo.flags & GI_TEASER2 ? "d_fmintr" : "d_intro");
break;
case 4:
@ -1239,11 +1247,11 @@ CCMD (endgame)
//
//==========================================================================
void D_AddFile (const char *file, bool check)
bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check, int position)
{
if (file == NULL)
{
return;
return false;
}
if (check && !DirEntryExists (file))
@ -1252,16 +1260,16 @@ void D_AddFile (const char *file, bool check)
if (f == NULL)
{
Printf ("Can't find '%s'\n", file);
return;
return false;
}
file = f;
}
wadlist_t *wad = (wadlist_t *)M_Malloc (sizeof(*wad) + strlen(file));
*wadtail = wad;
wad->next = NULL;
strcpy (wad->name, file);
wadtail = &wad->next;
FString f = file;
FixPathSeperator(f);
if (position == -1) wadfiles.Push(f);
else wadfiles.Insert(position, f);
return true;
}
//==========================================================================
@ -1270,13 +1278,13 @@ void D_AddFile (const char *file, bool check)
//
//==========================================================================
void D_AddWildFile (const char *value)
void D_AddWildFile (TArray<FString> &wadfiles, const char *value)
{
const char *wadfile = BaseFileSearch (value, ".wad");
if (wadfile != NULL)
{
D_AddFile (wadfile);
D_AddFile (wadfiles, wadfile);
}
else
{ // Try pattern matching
@ -1306,12 +1314,12 @@ void D_AddWildFile (const char *value)
{
if (sep == NULL)
{
D_AddFile (I_FindName (&findstate));
D_AddFile (wadfiles, I_FindName (&findstate));
}
else
{
strcpy (sep+1, I_FindName (&findstate));
D_AddFile (path);
D_AddFile (wadfiles, path);
}
}
} while (I_FindNext (handle, &findstate) == 0);
@ -1328,7 +1336,7 @@ void D_AddWildFile (const char *value)
//
//==========================================================================
void D_AddConfigWads (const char *section)
void D_AddConfigWads (TArray<FString> &wadfiles, const char *section)
{
if (GameConfig->SetSection (section))
{
@ -1342,7 +1350,7 @@ void D_AddConfigWads (const char *section)
{
// D_AddWildFile resets GameConfig's position, so remember it
GameConfig->GetPosition (pos);
D_AddWildFile (value);
D_AddWildFile (wadfiles, value);
// Reset GameConfig's position to get next wad
GameConfig->SetPosition (pos);
}
@ -1358,7 +1366,7 @@ void D_AddConfigWads (const char *section)
//
//==========================================================================
static void D_AddDirectory (const char *dir)
static void D_AddDirectory (TArray<FString> &wadfiles, const char *dir)
{
char curdir[PATH_MAX];
@ -1388,7 +1396,7 @@ static void D_AddDirectory (const char *dir)
if (!(I_FindAttr (&findstate) & FA_DIREC))
{
strcpy (skindir + stuffstart, I_FindName (&findstate));
D_AddFile (skindir);
D_AddFile (wadfiles, skindir);
}
} while (I_FindNext (handle, &findstate) == 0);
I_FindClose (handle);
@ -1483,9 +1491,9 @@ bool ConsiderPatches (const char *arg, const char *ext)
for (i = 0; i < files->NumArgs(); ++i)
{
if ( (f = BaseFileSearch (files->GetArg (i), ".deh")) )
DoDehPatch (f, false);
D_LoadDehFile(f);
else if ( (f = BaseFileSearch (files->GetArg (i), ".bex")) )
DoDehPatch (f, false);
D_LoadDehFile(f);
}
noDef = true;
}
@ -1581,6 +1589,161 @@ void D_MultiExec (DArgs *list, bool usePullin)
}
}
static void GetCmdLineFiles(TArray<FString> &wadfiles)
{
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
if (gameinfo.flags & GI_SHAREWARE)
{
I_FatalError ("You cannot -file with the shareware version. Register!");
}
// the files gathered are wadfile/lump names
for (int i = 0; i < files->NumArgs(); i++)
{
D_AddWildFile (wadfiles, files->GetArg (i));
}
for (int i = 0; i < files1->NumArgs(); i++)
{
D_AddWildFile (wadfiles, files1->GetArg (i));
}
for (int i = 0; i < files2->NumArgs(); i++)
{
D_AddWildFile (wadfiles, files2->GetArg (i));
}
for (int i = 0; i < files3->NumArgs(); i++)
{
D_AddWildFile (wadfiles, files3->GetArg (i));
}
}
files->Destroy();
files1->Destroy();
files2->Destroy();
files3->Destroy();
}
static void CopyFiles(TArray<FString> &to, TArray<FString> &from)
{
unsigned int ndx = to.Reserve(from.Size());
for(unsigned i=0;i<from.Size(); i++)
{
to[ndx+i] = from[i];
}
}
static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char *data, int size)
{
FScanner sc;
FString iwad;
int pos = 0;
const char *lastSlash = strrchr (fn, '/');
sc.OpenMem("GAMEINFO", data, size);
while(sc.GetToken())
{
sc.TokenMustBe(TK_Identifier);
FString nextKey = sc.String;
sc.MustGetToken('=');
if (!nextKey.CompareNoCase("IWAD"))
{
sc.MustGetString();
iwad = sc.String;
}
else if (!nextKey.CompareNoCase("LOAD"))
{
do
{
sc.MustGetString();
// Try looking for the wad in the same directory as the .wad
// before looking for it in the current directory.
if (lastSlash != NULL)
{
FString checkpath(fn, (lastSlash - fn) + 1);
checkpath += sc.String;
if (!FileExists (checkpath))
{
pos += D_AddFile(pwads, sc.String, true, pos);
}
else
{
pos += D_AddFile(pwads, checkpath, true, pos);
}
}
}
while (sc.CheckToken(','));
}
}
return iwad;
}
static FString CheckGameInfo(TArray<FString> & pwads)
{
DWORD t = I_FPSTime();
// scan the list of WADs backwards to find the last one that contains a GAMEINFO lump
for(int i=pwads.Size()-1; i>=0; i--)
{
bool isdir = false;
FileReader *wadinfo;
FResourceFile *resfile;
const char *filename = pwads[i];
// Does this exist? If so, is it a directory?
struct stat info;
if (stat(pwads[i], &info) != 0)
{
Printf(TEXTCOLOR_RED "Could not stat %s\n", filename);
continue;
}
isdir = (info.st_mode & S_IFDIR) != 0;
if (!isdir)
{
try
{
wadinfo = new FileReader(filename);
}
catch (CRecoverableError &)
{
// Didn't find file
continue;
}
resfile = FResourceFile::OpenResourceFile(filename, wadinfo, true);
}
else
resfile = FResourceFile::OpenDirectory(filename, true);
if (resfile != NULL)
{
DWORD cnt = resfile->LumpCount();
for(int i=cnt-1; i>=0; i--)
{
FResourceLump *lmp = resfile->GetLump(i);
if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "GAMEINFO"))
{
// Found one!
FString iwad = ParseGameInfo(pwads, resfile->Filename, (const char*)lmp->CacheLump(), lmp->LumpSize);
delete resfile;
return iwad;
}
}
delete resfile;
}
}
t = I_FPSTime() - t;
Printf("Gameinfo scan took %d ms\n", t);
return "";
}
//==========================================================================
//
// D_DoomMain
@ -1593,8 +1756,7 @@ void D_DoomMain (void)
char *v;
const char *wad;
DArgs *execFiles;
srand(I_MSTime());
TArray<FString> pwads;
// Set the FPU precision to 53 significant bits. This is the default
// for Visual C++, but not for GCC, so some slight math variances
@ -1635,11 +1797,15 @@ void D_DoomMain (void)
{
I_FatalError ("Cannot find " BASEWAD);
}
FString basewad = wad;
// Load zdoom.pk3 alone so that we can get access to the internal gameinfos before
// the IWAD is known.
const IWADInfo *iwad_info = D_FindIWAD(wad);
GetCmdLineFiles(pwads);
FString iwad = CheckGameInfo(pwads);
const IWADInfo *iwad_info = D_FindIWAD(allwads, iwad, basewad);
gameinfo.gametype = iwad_info->gametype;
gameinfo.flags = iwad_info->flags;
@ -1656,7 +1822,7 @@ void D_DoomMain (void)
// it for something else, so this gets to stay here.
wad = BaseFileSearch ("zvox.wad", NULL);
if (wad)
D_AddFile (wad);
D_AddFile (allwads, wad);
// [RH] Add any .wad files in the skins directory
#ifdef unix
@ -1665,27 +1831,27 @@ void D_DoomMain (void)
file = progdir;
#endif
file += "skins";
D_AddDirectory (file);
D_AddDirectory (allwads, file);
#ifdef unix
file = NicePath("~/" GAME_DIR "/skins");
D_AddDirectory (file);
D_AddDirectory (allwads, file);
#endif
// Add common (global) wads
D_AddConfigWads ("Global.Autoload");
D_AddConfigWads (allwads, "Global.Autoload");
// Add game-specific wads
file = GameNames[gameinfo.gametype];
file += ".Autoload";
D_AddConfigWads (file);
D_AddConfigWads (allwads, file);
// Add IWAD-specific wads
if (iwad_info->Autoname != NULL)
{
file = iwad_info->Autoname;
file += ".Autoload";
D_AddConfigWads(file);
D_AddConfigWads(allwads, file);
}
}
@ -1700,39 +1866,11 @@ void D_DoomMain (void)
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);
if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0)
{
// Check for -file in shareware
if (gameinfo.flags & GI_SHAREWARE)
{
I_FatalError ("You cannot -file with the shareware version. Register!");
}
// the files gathered are wadfile/lump names
for (int i = 0; i < files->NumArgs(); i++)
{
D_AddWildFile (files->GetArg (i));
}
for (int i = 0; i < files1->NumArgs(); i++)
{
D_AddWildFile (files1->GetArg (i));
}
for (int i = 0; i < files2->NumArgs(); i++)
{
D_AddWildFile (files2->GetArg (i));
}
for (int i = 0; i < files3->NumArgs(); i++)
{
D_AddWildFile (files3->GetArg (i));
}
}
CopyFiles(allwads, pwads);
Printf ("W_Init: Init WADfiles.\n");
Wads.InitMultipleFiles (&wadfiles);
Wads.InitMultipleFiles (allwads);
allwads.Clear();
// [RH] Initialize localizable strings.
GStrings.LoadStrings (false);
@ -1941,13 +2079,12 @@ void D_DoomMain (void)
DecalLibrary.Clear ();
DecalLibrary.ReadAllDecals ();
// [RH] Try adding .deh and .bex files on the command line.
// [RH] Add any .deh and .bex files on the command line.
// If there are none, try adding any in the config file.
// Note that the command line overrides defaults from the config.
if (!ConsiderPatches ("-deh", ".deh") &&
!ConsiderPatches ("-bex", ".bex") &&
(gameinfo.gametype == GAME_Doom) &&
GameConfig->SetSection ("Doom.DefaultDehacked"))
if ((ConsiderPatches("-deh", ".deh") | ConsiderPatches("-bex", ".bex")) == 0 &&
gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked"))
{
const char *key;
const char *value;
@ -1957,17 +2094,19 @@ void D_DoomMain (void)
if (stricmp (key, "Path") == 0 && FileExists (value))
{
Printf ("Applying patch %s\n", value);
DoDehPatch (value, true);
D_LoadDehFile(value);
}
}
}
DoDehPatch (NULL, true); // See if there's a patch in a PWAD
FinishDehPatch (); // Create replacements for dehacked pickups
// Load embedded Dehacked patches
D_LoadDehLumps();
// Create replacements for dehacked pickups
FinishDehPatch();
FActorInfo::StaticSetActorNums ();
// [RH] User-configurable startup strings. Because BOOM does.
static const char *startupString[5] = {
"STARTUP1", "STARTUP2", "STARTUP3", "STARTUP4", "STARTUP5"
@ -2035,7 +2174,7 @@ void D_DoomMain (void)
V_Init2();
files = Args->GatherFiles ("-playdemo", ".lmp", false);
DArgs *files = Args->GatherFiles ("-playdemo", ".lmp", false);
if (files->NumArgs() > 0)
{
singledemo = true; // quit after one demo
@ -2065,7 +2204,10 @@ void D_DoomMain (void)
if (autostart || netgame)
{
// Do not do any screenwipes when autostarting a game.
NoWipe = 35;
if (!Args->CheckParm("-warpwipe"))
{
NoWipe = TICRATE;
}
CheckWarpTransMap (startmap, true);
if (demorecording)
G_BeginRecording (startmap);

View file

@ -49,7 +49,7 @@ void D_PageTicker (void);
void D_PageDrawer (void);
void D_AdvanceDemo (void);
void D_StartTitle (void);
void D_AddFile (const char *file, bool check = true);
bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true, int position = -1);
// [RH] Set this to something to draw an icon during the next screen refresh.
@ -77,8 +77,11 @@ enum EIWADType
IWAD_FreeDoomU,
IWAD_FreeDoom1,
IWAD_FreeDM,
IWAD_Blasphemer,
IWAD_ChexQuest,
IWAD_ChexQuest3,
IWAD_ActionDoom2,
IWAD_Harmony,
IWAD_Custom,
NUM_IWAD_TYPES

View file

@ -2100,9 +2100,9 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_SUMMONFOE2:
{
const PClass *typeinfo;
int angle;
SWORD tid;
BYTE special;
int angle = 0;
SWORD tid = 0;
BYTE special = 0;
int args[5];
s = ReadString (stream);
@ -2367,8 +2367,10 @@ void Net_DoCommand (int type, BYTE **stream, int player)
}
break;
case DEM_CONVERSATION:
P_ConversationCommand (player, stream);
case DEM_CONVREPLY:
case DEM_CONVCLOSE:
case DEM_CONVNULL:
P_ConversationCommand (type, player, stream);
break;
case DEM_SETSLOT:
@ -2500,29 +2502,8 @@ void Net_SkipCommand (int type, BYTE **stream)
skip = 3 + *(*stream + 2) * 4;
break;
case DEM_CONVERSATION:
{
t = **stream;
skip = 1;
switch (t)
{
case CONV_ANIMATE:
skip += 1;
break;
case CONV_GIVEINVENTORY:
skip += strlen ((char *)(*stream + skip)) + 1;
break;
case CONV_TAKEINVENTORY:
skip += strlen ((char *)(*stream + skip)) + 3;
break;
default:
break;
}
}
case DEM_CONVREPLY:
skip = 3;
break;
case DEM_SETSLOT:

View file

@ -276,6 +276,7 @@ public:
bool centering;
BYTE turnticks;
bool attackdown;
bool usedown;
DWORD oldbuttons;
int health; // only used between levels, mo->health
// is used during levels
@ -414,9 +415,6 @@ void P_CheckPlayerSprites();
#define CROUCHSPEED (FRACUNIT/12)
#define MAX_DN_ANGLE 56 // Max looking down angle
#define MAX_UP_ANGLE 32 // Max looking up angle
// [GRB] Custom player classes
enum

View file

@ -147,14 +147,17 @@ enum EDemoCommand
DEM_ADDCONTROLLER, // 48 Player to add to the controller list.
DEM_DELCONTROLLER, // 49 Player to remove from the controller list.
DEM_KILLCLASSCHEAT, // 50 String: Class to kill.
DEM_CONVERSATION, // 51 Make conversations work.
DEM_UNDONE11, // 51
DEM_SUMMON2, // 52 String: Thing to fabricate, WORD: angle offset
DEM_SUMMONFRIEND2, // 53
DEM_SUMMONFOE2, // 54
DEM_ADDSLOTDEFAULT, // 55
DEM_ADDSLOT, // 56
DEM_SETSLOT, // 57
DEM_SUMMONMBF,
DEM_SUMMONMBF, // 58
DEM_CONVREPLY, // 59 Word: Dialogue node, Byte: Reply number
DEM_CONVCLOSE, // 60
DEM_CONVNULL, // 61
};
// The following are implemented by cht_DoCheat in m_cheat.cpp

View file

@ -508,6 +508,88 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
return changed;
}
void DObject::SerializeUserVars(FArchive &arc)
{
PSymbolTable *symt;
FName varname;
DWORD count, j;
int *varloc;
if (SaveVersion < 1933)
{
return;
}
symt = &GetClass()->Symbols;
if (arc.IsStoring())
{
// Write all user variables.
for (; symt != NULL; symt = symt->ParentSymbolTable)
{
for (unsigned i = 0; i < symt->Symbols.Size(); ++i)
{
PSymbol *sym = symt->Symbols[i];
if (sym->SymbolType == SYM_Variable)
{
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
if (var->bUserVar)
{
count = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
arc << var->SymbolName;
arc.WriteCount(count);
for (j = 0; j < count; ++j)
{
arc << varloc[j];
}
}
}
}
}
// Write terminator.
varname = NAME_None;
arc << varname;
}
else
{
// Read user variables until 'None' is encountered.
arc << varname;
while (varname != NAME_None)
{
PSymbol *sym = symt->FindSymbol(varname, true);
DWORD wanted = 0;
if (sym != NULL && sym->SymbolType == SYM_Variable)
{
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
if (var->bUserVar)
{
wanted = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
}
}
count = arc.ReadCount();
for (j = 0; j < MIN(wanted, count); ++j)
{
arc << varloc[j];
}
if (wanted < count)
{
// Ignore remaining values from archive.
for (; j < count; ++j)
{
int foo;
arc << foo;
}
}
arc << varname;
}
}
}
void DObject::Serialize (FArchive &arc)
{
ObjectFlags |= OF_SerialSuccess;

View file

@ -455,6 +455,7 @@ public:
inline bool IsKindOf (const PClass *base) const;
inline bool IsA (const PClass *type) const;
void SerializeUserVars(FArchive &arc);
virtual void Serialize (FArchive &arc);
// For catching Serialize functions in derived classes

View file

@ -37,6 +37,7 @@
#include "actor.h"
#include "templates.h"
#include "autosegs.h"
#include "v_text.h"
IMPLEMENT_POINTY_CLASS(PClass)
DECLARE_POINTER(ParentClass)
@ -134,7 +135,7 @@ void PClass::StaticFreeData (PClass *type)
{
if (type->Defaults != NULL)
{
delete[] type->Defaults;
M_Free(type->Defaults);
type->Defaults = NULL;
}
type->FreeStateList ();
@ -211,7 +212,7 @@ void PClass::InsertIntoHash ()
else if (lexx == 0)
{ // This type has already been inserted
// ... but there is no need whatsoever to make it a fatal error!
Printf ("Tried to register class '%s' more than once.\n", TypeName.GetChars());
Printf (TEXTCOLOR_RED"Tried to register class '%s' more than once.\n", TypeName.GetChars());
break;
}
else
@ -307,7 +308,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
type->Meta = Meta;
// Set up default instance of the new class.
type->Defaults = new BYTE[size];
type->Defaults = (BYTE *)M_Malloc(size);
memcpy (type->Defaults, Defaults, Size);
if (size > Size)
{
@ -341,6 +342,19 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
return type;
}
// Add <extension> bytes to the end of this class. Returns the
// previous size of the class.
unsigned int PClass::Extend(unsigned int extension)
{
assert(this->bRuntimeClass);
unsigned int oldsize = Size;
Size += extension;
Defaults = (BYTE *)M_Realloc(Defaults, Size);
memset(Defaults + oldsize, 0, extension);
return oldsize;
}
// Like FindClass but creates a placeholder if no class
// is found. CreateDerivedClass will automatcally fill in
// the placeholder when the actual class is defined.

View file

@ -55,8 +55,9 @@ class PSymbolVariable : public PSymbol
DECLARE_CLASS(PSymbolVariable, PSymbol);
public:
FExpressionType ValueType;
int size;
//int size;
intptr_t offset;
bool bUserVar;
PSymbolVariable(FName name) : PSymbol(name, SYM_Variable) {}
PSymbolVariable() : PSymbol(NAME_None, SYM_Variable) {}
@ -142,6 +143,8 @@ struct PSymbolTable
private:
PSymbolTable *ParentSymbolTable;
TArray<PSymbol *> Symbols;
friend class DObject;
};
// Meta-info for every class derived from DObject ---------------------------
@ -177,6 +180,7 @@ public:
void InsertIntoHash ();
DObject *CreateNew () const;
PClass *CreateDerivedClass (FName name, unsigned int size);
unsigned int Extend(unsigned int extension);
void InitializeActorInfo ();
void BuildFlatPointers ();
void FreeStateList();

View file

@ -324,6 +324,7 @@ enum
COMPATF_MBFMONSTERMOVE = 1 << 24, // Monsters are affected by friction and pushers/pullers.
COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs.
COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines.
COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance
};
// Emulate old bugs for select maps. These are not exposed by a cvar

View file

@ -27,10 +27,12 @@
#include "p_local.h"
#include "p_3dmidtex.h"
#include "r_interpolate.h"
#include "statnums.h"
IMPLEMENT_CLASS (DSectorEffect)
DSectorEffect::DSectorEffect ()
: DThinker(STAT_SECTOREFFECT)
{
m_Sector = NULL;
}

View file

@ -203,7 +203,7 @@ void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
// before the crash - which is not the case with all other options.
//DestroyAllThinkers();
I_FatalError(err.GetMessage());
I_FatalError("%s", err.GetMessage());
throw;
}
bSerialOverride = false;

View file

@ -36,6 +36,7 @@
#include <stdlib.h>
#include "dobject.h"
#include "statnums.h"
class AActor;
class player_t;
@ -62,7 +63,7 @@ class DThinker : public DObject
{
DECLARE_CLASS (DThinker, DObject)
public:
DThinker (int statnum = MAX_STATNUM) throw();
DThinker (int statnum = STAT_DEFAULT) throw();
void Destroy ();
virtual ~DThinker ();
virtual void Tick ();

View file

@ -809,8 +809,8 @@ void F_DemonScroll ()
int yval;
FTexture *final1 = TexMan(tex1);
FTexture *final2 = TexMan(tex2);
int fwidth = final1->GetWidth();
int fheight = final1->GetHeight();
int fwidth = final1->GetScaledWidth();
int fheight = final1->GetScaledHeight();
if (FinaleCount < 70)
{
@ -884,10 +884,7 @@ void F_DrawUnderwater(void)
// intentional fall-through
case 2:
pic = TexMan("E2END");
screen->DrawTexture (pic, 0, 0,
DTA_VirtualWidth, pic->GetWidth(),
DTA_VirtualHeight, pic->GetHeight(),
TAG_DONE);
screen->DrawTexture (pic, 0, 0, DTA_Fullscreen, true, TAG_DONE);
screen->FillBorder (NULL);
paused = false;
menuactive = MENU_Off;
@ -907,10 +904,7 @@ void F_DrawUnderwater(void)
screen->UpdatePalette ();
pic = TexMan("TITLE");
screen->DrawTexture (pic, 0, 0,
DTA_VirtualWidth, pic->GetWidth(),
DTA_VirtualHeight, pic->GetHeight(),
TAG_DONE);
screen->DrawTexture (pic, 0, 0, DTA_Fullscreen, true, TAG_DONE);
screen->FillBorder (NULL);
NoWipe = 0;
break;
@ -960,8 +954,8 @@ void F_BunnyScroll (void)
V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
tex = TexMan(tex1);
fwidth = tex->GetWidth();
fheight = tex->GetHeight();
fwidth = tex->GetScaledWidth();
fheight = tex->GetScaledHeight();
scrolled = clamp (((signed)FinaleCount-230)*fwidth/640, 0, fwidth);
@ -1315,25 +1309,24 @@ void F_Drawer (void)
if (picname != NULL)
{
FTexture *pic = TexMan[picname];
screen->DrawTexture (pic, 0, 0,
DTA_VirtualWidth, pic->GetWidth(),
DTA_VirtualHeight, pic->GetHeight(),
TAG_DONE);
screen->DrawTexture (pic, 0, 0, DTA_Fullscreen, true, TAG_DONE);
screen->FillBorder (NULL);
if (FinaleStage >= 14)
{ // Chess pic, draw the correct character graphic
double w = pic->GetScaledWidthDouble();
double h = pic->GetScaledHeightDouble();
if (multiplayer)
{
screen->DrawTexture (TexMan["CHESSALL"], 20, 0,
DTA_VirtualWidth, pic->GetWidth(),
DTA_VirtualHeight, pic->GetHeight(), TAG_DONE);
DTA_VirtualWidth, w,
DTA_VirtualHeight, h, TAG_DONE);
}
else if (players[consoleplayer].CurrentPlayerClass > 0)
{
picname = players[consoleplayer].CurrentPlayerClass == 1 ? "CHESSC" : "CHESSM";
screen->DrawTexture (TexMan[picname], 60, 0,
DTA_VirtualWidth, pic->GetWidth(),
DTA_VirtualHeight, pic->GetHeight(), TAG_DONE);
DTA_VirtualWidth, w,
DTA_VirtualHeight, h, TAG_DONE);
}
}
}

View file

@ -3,7 +3,7 @@
** Implements an archiver for DObject serialization.
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** Copyright 1998-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -1074,6 +1074,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
WriteClass (type);
// Printf ("Make class %s (%u)\n", type->Name, m_File->Tell());
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
}
@ -1105,6 +1106,7 @@ FArchive &FArchive::WriteObject (DObject *obj)
WriteCount (m_TypeMap[type->ClassIndex].toArchive);
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
}
@ -1160,6 +1162,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
// stored in the archive.
AActor *tempobj = static_cast<AActor *>(type->CreateNew ());
MapObject (obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars (*this);
tempobj->Serialize (*this);
tempobj->CheckIfSerialized ();
// If this player is not present anymore, keep the new body
@ -1187,6 +1190,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
// Printf ("New class: %s (%u)\n", type->Name, m_File->Tell());
obj = type->CreateNew ();
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
break;
@ -1201,6 +1205,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
AActor *tempobj = static_cast<AActor *>(type->CreateNew ());
MapObject (obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars (*this);
tempobj->Serialize (*this);
tempobj->CheckIfSerialized ();
if (obj != NULL)
@ -1225,6 +1230,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
// Printf ("Use class: %s (%u)\n", type->Name, m_File->Tell());
obj = type->CreateNew ();
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
break;
@ -1389,7 +1395,7 @@ const PClass *FArchive::ReadClass ()
FName zaname(typeName.val, true);
if (zaname != NAME_None)
{
for (unsigned int i = 0; i < PClass::m_Types.Size(); i++)
for (unsigned int i = PClass::m_Types.Size(); i-- > 0; )
{
if (PClass::m_Types[i]->TypeName == zaname)
{

View file

@ -114,6 +114,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
// spawn brain missile
spit = P_SpawnMissile (self, targ, spawntype);
// Boss cubes should move freely to their destination so it's
// probably best to disable all collision detection for them.
if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION;
if (spit != NULL)
{
spit->target = targ;

View file

@ -141,7 +141,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
// use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
P_LineAttack (self, angle, MELEERANGE+1,
P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
GetDefaultByType(pufftype)->DamageType, pufftype);
NAME_None, pufftype);
if (!linetarget)
{
@ -272,7 +272,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2)
{
PARAM_ACTION_PROLOGUE;
S_Sound (self, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);
CALL_ACTION(A_ReFire, self);
A_ReFire (self);
return 0;
}

View file

@ -124,7 +124,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3)
// Original idea: Linguica
//
AActor * P_OldSpawnMissile(AActor * source, AActor * dest, const PClass *type);
AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const PClass *type);
enum
{
MSF_Standard = 0,
MSF_Classic = 1,
MSF_DontHurt = 2,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
{
@ -140,14 +147,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
if (n == 0) n = self->Damage; // GetMissileDamage (0, 1);
if (spawntype == NULL) spawntype = PClass::FindClass("FatShot");
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true);
if (self->z <= self->floorz + (128<<FRACBITS))
{
P_HitFloor (self);
}
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, !(flags & MSF_DontHurt));
P_CheckSplash(self, 128<<FRACBITS);
// Now launch mushroom cloud
AActor *target = Spawn("Mapspot", 0, 0, 0, NO_REPLACE); // We need something to aim at.
AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self;
target->height = self->height;
for (i = -n; i <= n; i += 8)
{
@ -157,13 +162,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
target->x = self->x + (i << FRACBITS); // Aim in many directions from source
target->y = self->y + (j << FRACBITS);
target->z = self->z + (P_AproxDistance(i,j) * vrange); // Aim up fairly high
if (flags == 0 && (!(self->state->DefineFlags & SDF_DEHACKED) || !(i_compatflags & COMPATF_MUSHROOM)))
{
mo = P_SpawnMissile (self, target, spawntype); // Launch fireball
if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options
(flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM)))
{ // Use old function for MBF compatibility
mo = P_OldSpawnMissile (self, master, target, spawntype);
}
else
else // Use normal function
{
mo = P_OldSpawnMissile (self, target, spawntype); // Launch fireball
mo = P_SpawnMissile(self, target, spawntype, master);
}
if (mo != NULL)
{ // Slow it down a bit

View file

@ -19,7 +19,6 @@
// SkullAttack
// Fly at the player like a missile.
//
#define SKULLSPEED (20*FRACUNIT)
void A_SkullAttack(AActor *self, fixed_t speed)
{
@ -57,8 +56,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack)
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack)
{
PARAM_ACTION_PROLOGUE;

View file

@ -31,9 +31,6 @@ static const PClass *GetSpawnType(VMValue *param)
}
#define SKULLSPEED (20*FRACUNIT)
void A_SkullAttack(AActor *self, fixed_t speed);
//
// A_PainShootSkull
// Spawn a lost soul and launch it at the target

View file

@ -97,14 +97,6 @@ void AScriptedMarine::BeginPlay ()
}
}
}
// Copy the standard player's scaling
AActor * playerdef = GetDefaultByName("DoomPlayer");
if (playerdef != NULL)
{
scaleX = playerdef->scaleX;
scaleY = playerdef->scaleY;
}
}
void AScriptedMarine::Tick ()
@ -112,7 +104,7 @@ void AScriptedMarine::Tick ()
Super::Tick ();
// Override the standard sprite, if desired
if (SpriteOverride != 0 && sprite == GetClass()->ActorInfo->OwnedStates[0].sprite)
if (SpriteOverride != 0 && sprite == SpawnState->sprite)
{
sprite = SpriteOverride;
}
@ -474,7 +466,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
P_LineAttack (self, angle, MISSILERANGE,
pitch + (pr_m_fireshotgun2.Random2() * 332063), damage,
NAME_None, PClass::FindClass(NAME_BulletPuff));
NAME_None, NAME_BulletPuff);
}
self->special1 = level.maptime;
return 0;
@ -648,14 +640,12 @@ void AScriptedMarine::SetSprite (const PClass *source)
if (source == NULL || source->ActorInfo == NULL)
{ // A valid actor class wasn't passed, so use the standard sprite
SpriteOverride = sprite = GetClass()->ActorInfo->OwnedStates[0].sprite;
// Copy the standard player's scaling
AActor * playerdef = GetDefaultByName("DoomPlayer");
if (playerdef == NULL) playerdef = GetDefaultByType(RUNTIME_CLASS(AScriptedMarine));
scaleX = playerdef->scaleX;
scaleY = playerdef->scaleY;
// Copy the standard scaling
scaleX = GetDefault()->scaleX;
scaleY = GetDefault()->scaleY;
}
else
{ // Use the same sprite the passed class spawns with
{ // Use the same sprite and scaling the passed class spawns with
SpriteOverride = sprite = GetDefaultByType (source)->SpawnState->sprite;
scaleX = GetDefaultByType(source)->scaleX;
scaleY = GetDefaultByType(source)->scaleY;

View file

@ -1316,7 +1316,7 @@ void G_PlayerReborn (int player)
p->skill = b_skill; //Added by MC:
p->oldbuttons = ~0, p->attackdown = true; // don't do anything immediately
p->oldbuttons = ~0, p->attackdown = true; p->usedown = true; // don't do anything immediately
p->original_oldbuttons = ~0;
p->playerstate = PST_LIVE;
@ -1475,10 +1475,8 @@ void G_DeathMatchSpawnPlayer (int playernum)
{
if (playernum < 4)
spot->type = playernum+1;
else if (gameinfo.gametype != GAME_Hexen)
spot->type = playernum+4001-4; // [RH] > 4 players
else
spot->type = playernum+9100-4;
else
spot->type = playernum + gameinfo.player5start - 4;
}
AActor *mo = P_SpawnPlayer (spot);
@ -1506,6 +1504,7 @@ static void G_QueueBody (AActor *body)
{
*translationtables[TRANSLATION_PlayerCorpses][modslot] = *TranslationToTable(body->Translation);
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot);
translationtables[TRANSLATION_PlayerCorpses][modslot]->UpdateNative();
}
bodyqueslot++;
@ -1568,17 +1567,13 @@ void G_DoReborn (int playernum, bool freshbot)
// fake as other player
// [RH] These numbers should be common across all games. Or better yet, not
// used at all outside P_SpawnMapThing().
if (playernum < 4 || gameinfo.gametype == GAME_Strife)
if (playernum < 4)
{
playerstarts[i].type = playernum + 1;
}
else if (gameinfo.gametype == GAME_Hexen)
{
playerstarts[i].type = playernum + 9100 - 4;
}
else
{
playerstarts[i].type = playernum + 4001 - 4;
playerstarts[i].type = playernum + gameinfo.player5start - 4;
}
AActor *mo = P_SpawnPlayer (&playerstarts[i]);
if (mo != NULL) P_PlayerStartStomp(mo);
@ -1850,14 +1845,11 @@ FString G_BuildSaveName (const char *prefix, int slot)
{
leader = save_dir;
}
if (leader.IsEmpty())
{
#ifdef unix
if (leader.IsEmpty())
{
leader = "~/" GAME_DIR;
}
#elif defined(__APPLE__)
if (leader.IsEmpty())
{
char cpath[PATH_MAX];
FSRef folder;
@ -1866,8 +1858,10 @@ FString G_BuildSaveName (const char *prefix, int slot)
{
leader << cpath << "/" GAME_DIR "/Savegames/";
}
}
#else
leader = progdir;
#endif
}
}
size_t len = leader.Len();
if (leader[0] != '\0' && leader[len-1] != '\\' && leader[len-1] != '/')

View file

@ -53,10 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
self->RenderStyle = STYLE_Add;
self->alpha = FRACUNIT;
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true);
if (self->z <= self->floorz + (128<<FRACBITS))
{
P_HitFloor (self);
}
P_CheckSplash(self, 128<<FRACBITS);
return 0;
}

View file

@ -9,8 +9,29 @@
#include "thingdef/thingdef.h"
*/
static FRandom pr_impmsatk ("ImpMsAttack");
static FRandom pr_imp ("ImpExplode");
//----------------------------------------------------------------------------
//
// PROC A_ImpMsAttack
//
//----------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack)
{
PARAM_ACTION_PROLOGUE;
if (!self->target || pr_impmsatk() > 64)
{
self->SetState (self->SeeState);
return 0;
}
A_SkullAttack(self, 12 * FRACUNIT);
return 0;
}
//----------------------------------------------------------------------------
//
// PROC A_ImpExplode

View file

@ -65,7 +65,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
if (mo != NULL)
{
mo->tracer = self->target;
mo->special2 = 16; // High word == x/y, Low word == z
}
self->special1--;
return 0;
@ -81,25 +80,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{
PARAM_ACTION_PROLOGUE;
fixed_t newX, newY;
int weaveXY, weaveZ;
int angle;
if (self->special2 == 0) self->special2 = 16;
weaveXY = self->special2 >> 16;
weaveZ = self->special2 & 0xFFFF;
angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
newX = self->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
newY = self->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
weaveXY = (weaveXY + 2) & 63;
newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
P_TryMove (self, newX, newY, true);
self->z -= FloatBobOffsets[weaveZ];
weaveZ = (weaveZ + 2) & 63;
self->z += FloatBobOffsets[weaveZ];
self->special2 = weaveZ + (weaveXY<<16);
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT);
return 0;
}

View file

@ -8,87 +8,21 @@
#include "s_sound.h"
*/
/* For reference, the default values:
#define BLAST_RADIUS_DIST 255*FRACUNIT
#define BLAST_SPEED 20*FRACUNIT
#define BLAST_FULLSTRENGTH 255
*/
// Disc of Repulsion --------------------------------------------------------
class AArtiBlastRadius : public AInventory
{
DECLARE_CLASS (AArtiBlastRadius, AInventory)
public:
bool Use (bool pickup);
protected:
void BlastActor (AActor *victim, fixed_t strength);
};
IMPLEMENT_CLASS (AArtiBlastRadius)
//==========================================================================
//
// AArtiBlastRadius :: Activate
//
// Blast all actors away
//
//==========================================================================
bool AArtiBlastRadius::Use (bool pickup)
{
AActor *mo;
TThinkerIterator<AActor> iterator;
fixed_t dist;
S_Sound (Owner, CHAN_AUTO, "BlastRadius", 1, ATTN_NORM);
P_NoiseAlert (Owner, Owner);
while ( (mo = iterator.Next ()) )
{
if ((mo == Owner) || (mo->flags2 & MF2_BOSS))
{ // Not a valid monster
continue;
}
if ((mo->flags & MF_ICECORPSE) || (mo->flags3 & MF3_CANBLAST))
{
// Let these special cases go
}
else if ((mo->flags3 & MF3_ISMONSTER) && (mo->health <= 0))
{
continue;
}
else if (!(mo->flags3 & MF3_ISMONSTER) &&
!(mo->player) &&
!(mo->flags & MF_MISSILE) &&
!(mo->flags3 & MF3_CANBLAST) &&
!(mo->flags6 & MF6_TOUCHY))
{ // Must be monster, player, missile, or touchy
continue;
}
if (mo->flags2 & MF2_DORMANT)
{
continue; // no dormant creatures
}
if (mo->flags3 & MF3_DONTBLAST)
{ // A few things that would normally be blastable should not be blasted
continue;
}
dist = P_AproxDistance (Owner->x - mo->x, Owner->y - mo->y);
if (dist > BLAST_RADIUS_DIST)
{ // Out of range
continue;
}
BlastActor (mo, BLAST_FULLSTRENGTH);
}
return true;
}
//==========================================================================
//
// AArtiBlastRadius :: BlastActor
//
//==========================================================================
void AArtiBlastRadius::BlastActor (AActor *victim, fixed_t strength)
void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor * Owner, const PClass * blasteffect)
{
angle_t angle,ang;
AActor *mo;
@ -101,72 +35,121 @@ void AArtiBlastRadius::BlastActor (AActor *victim, fixed_t strength)
angle = R_PointToAngle2 (Owner->x, Owner->y, victim->x, victim->y);
angle >>= ANGLETOFINESHIFT;
if (strength < BLAST_FULLSTRENGTH)
victim->velx = FixedMul (speed, finecosine[angle]);
victim->vely = FixedMul (speed, finesine[angle]);
// Spawn blast puff
ang = R_PointToAngle2 (victim->x, victim->y, Owner->x, Owner->y);
ang >>= ANGLETOFINESHIFT;
x = victim->x + FixedMul (victim->radius+FRACUNIT, finecosine[ang]);
y = victim->y + FixedMul (victim->radius+FRACUNIT, finesine[ang]);
z = victim->z - victim->floorclip + (victim->height>>1);
mo = Spawn (blasteffect, x, y, z, ALLOW_REPLACE);
if (mo)
{
victim->velx = FixedMul (strength, finecosine[angle]);
victim->vely = FixedMul (strength, finesine[angle]);
if (victim->player)
mo->velx = victim->velx;
mo->vely = victim->vely;
}
if (victim->flags & MF_MISSILE)
{
// [RH] Floor and ceiling huggers should not be blasted vertically.
if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{
// Players handled automatically
}
else
{
victim->flags2 |= MF2_BLASTED;
victim->velz = 8*FRACUNIT;
mo->velz = victim->velz;
}
}
else // full strength blast from artifact
else
{
if (victim->flags & MF_MISSILE)
{
#if 0
if (victim->IsKindOf (RUNTIME_CLASS(AMageStaffFX2)))
{ // Reflect to originator
victim->special1 = (int)victim->target;
victim->target = Owner;
}
#endif
}
victim->velx = FixedMul (BLAST_SPEED, finecosine[angle]);
victim->vely = FixedMul (BLAST_SPEED, finesine[angle]);
// Spawn blast puff
ang = R_PointToAngle2 (victim->x, victim->y, Owner->x, Owner->y);
ang >>= ANGLETOFINESHIFT;
x = victim->x + FixedMul (victim->radius+FRACUNIT, finecosine[ang]);
y = victim->y + FixedMul (victim->radius+FRACUNIT, finesine[ang]);
z = victim->z - victim->floorclip + (victim->height>>1);
mo = Spawn ("BlastEffect", x, y, z, ALLOW_REPLACE);
if (mo)
{
mo->velx = victim->velx;
mo->vely = victim->vely;
}
if (victim->flags & MF_MISSILE)
{
// [RH] Floor and ceiling huggers should not be blasted vertically.
if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{
victim->velz = 8*FRACUNIT;
mo->velz = victim->velz;
}
}
else
{
victim->velz = (1000 / victim->Mass) << FRACBITS;
}
if (victim->player)
{
// Players handled automatically
}
else
{
victim->flags2 |= MF2_BLASTED;
}
if (victim->flags6 & MF6_TOUCHY)
{ // Touchy objects die when blasted
victim->flags6 &= ~MF6_ARMED; // Disarm
P_DamageMobj(victim, Owner, Owner, victim->health, NAME_Melee, DMG_FORCED);
}
victim->velz = (1000 / victim->Mass) << FRACBITS;
}
if (victim->player)
{
// Players handled automatically
}
else
{
victim->flags2 |= MF2_BLASTED;
}
if (victim->flags6 & MF6_TOUCHY)
{ // Touchy objects die when blasted
victim->flags6 &= ~MF6_ARMED; // Disarm
P_DamageMobj(victim, Owner, Owner, victim->health, NAME_Melee, DMG_FORCED);
}
}
enum
{
BF_USEAMMO = 1,
BF_DONTWARN = 2,
BF_AFFECTBOSSES = 4,
};
//==========================================================================
//
// AArtiBlastRadius :: Activate
//
// Blast all actors away
//
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
{
PARAM_ACTION_PROLOGUE;
PARAM_INT_OPT (blastflags) { blastflags = 0; }
PARAM_FIXED_OPT (strength) { strength = 255; }
PARAM_FIXED_OPT (radius) { radius = 255; }
PARAM_FIXED_OPT (speed) { speed = 20; }
PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindClass("BlastEffect"); }
PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; }
AActor *mo;
TThinkerIterator<AActor> iterator;
fixed_t dist;
if (self->player && (blastflags & BF_USEAMMO))
{
AWeapon *weapon = self->player->ReadyWeapon;
if (!weapon->DepleteAmmo(weapon->bAltFire))
{
return 0;
}
}
S_Sound (self, CHAN_AUTO, blastsound, 1, ATTN_NORM);
if (!(blastflags & BF_DONTWARN))
{
P_NoiseAlert (self, self);
}
while ( (mo = iterator.Next ()) )
{
if ((mo == self) || ((mo->flags2 & MF2_BOSS) && !(blastflags & BF_AFFECTBOSSES))
|| (mo->flags2 & MF2_DORMANT) || (mo->flags3 & MF3_DONTBLAST))
{ // Not a valid monster: originator, boss, dormant, or otherwise protected
continue;
}
if ((mo->flags & MF_ICECORPSE) || (mo->flags3 & MF3_CANBLAST))
{
// Let these special cases go
}
else if ((mo->flags3 & MF3_ISMONSTER) && (mo->health <= 0))
{
continue;
}
else if (!(mo->player) &&
!(mo->flags & MF_MISSILE) &&
!(mo->flags3 & (MF3_ISMONSTER|MF3_CANBLAST)) &&
!(mo->flags6 & (MF6_TOUCHY|MF6_VULNERABLE)))
{ // Must be monster, player, missile, touchy or vulnerable
continue;
}
dist = P_AproxDistance (self->x - mo->x, self->y - mo->y);
if (dist > radius)
{ // Out of range
continue;
}
BlastActor (mo, strength, speed, self, blasteffect);
}
return 0;
}

View file

@ -145,36 +145,6 @@ bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength)
return true;
}
bool AHolySpirit::IsOkayToAttack (AActor *link)
{
if ((link->flags3&MF3_ISMONSTER ||
(link->player && link != target))
&& !(link->flags2&MF2_DORMANT))
{
if (target != NULL && link->IsFriend(target))
{
return false;
}
if (!(link->flags & MF_SHOOTABLE))
{
return false;
}
if (multiplayer && !deathmatch && link->player && target != NULL && target->player)
{
return false;
}
if (link == target)
{
return false;
}
else if (P_CheckSight (this, link))
{
return true;
}
}
return false;
}
//============================================================================
//
// A_CHolyAttack2

View file

@ -48,9 +48,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
{
PARAM_ACTION_PROLOGUE;
AActor *pmo;
APlayerPawn *pmo;
int damage;
int newLife;
int newLife, max;
angle_t angle;
int slope;
int i;
@ -65,6 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
pmo = player->mo;
damage = 20+(pr_staffcheck()&15);
max = pmo->GetMaxHealth();
for (i = 0; i < 3; i++)
{
angle = pmo->angle+i*(ANG45/16);
@ -78,7 +79,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
&& (!(linetarget->flags2&(MF2_DORMANT+MF2_INVULNERABLE))))
{
newLife = player->health+(damage>>3);
newLife = newLife > 100 ? 100 : newLife;
newLife = newLife > max ? max : newLife;
if (newLife > player->health)
{
pmo->health = player->health = newLife;
@ -101,7 +102,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER)
{
newLife = player->health+(damage>>4);
newLife = newLife > 100 ? 100 : newLife;
newLife = newLife > max ? max : newLife;
pmo->health = player->health = newLife;
P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain"));
}
@ -139,12 +140,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15));
if (mo)
{
mo->special2 = 32;
mo->WeaveIndexXY = 32;
}
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15));
if (mo)
{
mo->special2 = 0;
mo->WeaveIndexXY = 0;
}
S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM);
return 0;
@ -160,19 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
{
PARAM_ACTION_PROLOGUE;
fixed_t newX, newY;
int weaveXY;
int angle;
weaveXY = self->special2;
angle = (self->angle+ANG90)>>ANGLETOFINESHIFT;
newX = self->x-FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
newY = self->y-FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
weaveXY = (weaveXY+3)&63;
newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
P_TryMove (self, newX, newY, true);
self->special2 = weaveXY;
A_Weave(self, 3, 0, FRACUNIT, 0);
return 0;
}

View file

@ -104,21 +104,38 @@ bool AArtiPoisonBag3::Use (bool pickup)
{
AActor *mo;
mo = Spawn ("ThrowingBomb", Owner->x, Owner->y,
mo = Spawn("ThrowingBomb", Owner->x, Owner->y,
Owner->z-Owner->floorclip+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0), ALLOW_REPLACE);
if (mo)
{
angle_t pitch = (angle_t)Owner->pitch >> ANGLETOFINESHIFT;
mo->angle = Owner->angle + (((pr_poisonbag()&7) - 4) << 24);
/* Original flight code from Hexen
* mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4));
* mo->z += player->lookdir<<(FRACBITS-4);
* P_ThrustMobj(mo, mo->angle, mo->info->speed);
* mo->momx += player->mo->momx>>1;
* mo->momy += player->mo->momy>>1;
*/
// When looking straight ahead, it uses a z velocity of 4 while the xy velocity
// is as set by the projectile. To accomodate this with a proper trajectory, we
// aim the projectile ~20 degrees higher than we're looking at and increase the
// speed we fire at accordingly.
angle_t orgpitch = angle_t(-Owner->pitch) >> ANGLETOFINESHIFT;
angle_t modpitch = angle_t(0xDC00000 - Owner->pitch) >> ANGLETOFINESHIFT;
angle_t angle = mo->angle >> ANGLETOFINESHIFT;
fixed_t speed = fixed_t(sqrt((double)mo->Speed*mo->Speed + (4.0*65536*4*65536)));
fixed_t xyscale = FixedMul(speed, finecosine[modpitch]);
mo->velz = FixedMul(speed, finesine[modpitch]);
mo->velx = FixedMul(xyscale, finecosine[angle]) + (Owner->velx >> 1);
mo->vely = FixedMul(xyscale, finesine[angle]) + (Owner->vely >> 1);
mo->z += FixedMul(mo->Speed, finesine[orgpitch]);
mo->angle = Owner->angle+(((pr_poisonbag()&7)-4)<<24);
mo->velz = 4*FRACUNIT + 2*finesine[pitch];
mo->z += 2*finesine[pitch];
P_ThrustMobj (mo, mo->angle, mo->Speed);
mo->velx += Owner->velx >> 1;
mo->vely += Owner->vely >> 1;
mo->target = Owner;
mo->tics -= pr_poisonbag()&3;
P_CheckMissileSpawn (mo);
P_CheckMissileSpawn(mo);
return true;
}
return false;

View file

@ -9,7 +9,6 @@ class AHolySpirit : public AActor
public:
bool Slam (AActor *thing);
bool SpecialBlastHandling (AActor *source, fixed_t strength);
bool IsOkayToAttack (AActor *link);
};
class AFighterWeapon : public AWeapon

View file

@ -44,7 +44,6 @@
#include "a_magecone.cpp"
#include "a_magelightning.cpp"
#include "a_magestaff.cpp"
#include "a_magewand.cpp"
#include "a_pig.cpp"
#include "a_serpent.cpp"
#include "a_spike.cpp"

View file

@ -383,6 +383,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset2)
self->flags |= MF_SHOOTABLE;
self->flags &= ~MF_CORPSE;
self->flags6 &= ~MF6_KILLED;
self->health = 5;
return 0;
}

View file

@ -215,8 +215,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
{
PARAM_ACTION_PROLOGUE;
const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None));
if (lightning == NULL) lightning = PClass::FindClass("LightningZap");
const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap));
AActor *mo;
fixed_t deltaZ;
@ -339,9 +338,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic)
DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
{
PARAM_ACTION_PROLOGUE;
const PClass *lightning = PClass::FindClass(ENamedName(self->GetClass()->Meta.GetMetaInt(ACMETA_MissileName, NAME_None)));
if (lightning == NULL) lightning = PClass::FindClass("LightningZap");
const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap));
AActor *mo;

View file

@ -88,7 +88,6 @@ class AMageStaffFX2 : public AActor
DECLARE_CLASS(AMageStaffFX2, AActor)
public:
int SpecialMissileHit (AActor *victim);
bool IsOkayToAttack (AActor *link);
bool SpecialBlastHandling (AActor *source, fixed_t strength);
};
@ -106,41 +105,6 @@ int AMageStaffFX2::SpecialMissileHit (AActor *victim)
return -1;
}
bool AMageStaffFX2::IsOkayToAttack (AActor *link)
{
if (((link->flags3 & MF3_ISMONSTER) || link->player) && !(link->flags2 & MF2_DORMANT))
{
if (!(link->flags & MF_SHOOTABLE))
{
return false;
}
if (multiplayer && !deathmatch && link->player && target->player)
{
return false;
}
if (link == target)
{
return false;
}
if (target != NULL && target->IsFriend(link))
{
return false;
}
if (P_CheckSight (this, link))
{
AActor *master = target;
angle_t angle = R_PointToAngle2 (master->x, master->y,
link->x, link->y) - master->angle;
angle >>= 24;
if (angle>226 || angle<30)
{
return true;
}
}
}
return false;
}
bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength)
{
// Reflect to originator

View file

@ -1,61 +0,0 @@
/*
#include "actor.h"
#include "gi.h"
#include "m_random.h"
#include "s_sound.h"
#include "d_player.h"
#include "a_action.h"
#include "p_local.h"
#include "a_action.h"
#include "p_pspr.h"
#include "gstrings.h"
#include "a_hexenglobal.h"
#include "thingdef/thingdef.h"
*/
static FRandom pr_smoke ("MWandSmoke");
void A_MWandAttack (AActor *actor);
// Wand Missile -------------------------------------------------------------
class AMageWandMissile : public AFastProjectile
{
DECLARE_CLASS(AMageWandMissile, AFastProjectile)
public:
void Effect ();
};
IMPLEMENT_CLASS (AMageWandMissile)
void AMageWandMissile::Effect ()
{
fixed_t hitz;
//if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent
{
hitz = z-8*FRACUNIT;
if (hitz < floorz)
{
hitz = floorz;
}
Spawn ("MageWandSmoke", x, y, hitz, ALLOW_REPLACE);
}
}
//============================================================================
//
// A_MWandAttack
//
//============================================================================
DEFINE_ACTION_FUNCTION(AActor, A_MWandAttack)
{
PARAM_ACTION_PROLOGUE;
AActor *mo;
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(AMageWandMissile));
S_Sound (self, CHAN_WEAPON, "MageWandFire", 1, ATTN_NORM);
return 0;
}

View file

@ -84,6 +84,18 @@
#include "g_hub.h"
#ifndef STAT
#define STAT_NEW(map)
#define STAT_END(newl)
#define STAT_READ(png)
#define STAT_WRITE(f)
#else
void STAT_NEW(const char *lev);
void STAT_END(const char *newl);
void STAT_READ(PNGHandle *png);
void STAT_WRITE(FILE *f);
#endif
EXTERN_CVAR (Float, sv_gravity)
EXTERN_CVAR (Float, sv_aircontrol)
EXTERN_CVAR (Int, disableautosave)
@ -168,7 +180,7 @@ static void SetEndSequence (char *nextmap, int type)
newseq.EndType = type;
seqnum = (int)EndSequences.Push (newseq);
}
mysnprintf(nextmap, sizeof(nextmap), "enDSeQ%04x", (WORD)seqnum);
mysnprintf(nextmap, 11, "enDSeQ%04x", (WORD)seqnum);
}
//==========================================================================
@ -495,6 +507,8 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
// force players to be initialized upon first level load
for (i = 0; i < MAXPLAYERS; i++)
players[i].playerstate = PST_ENTER; // [BC]
STAT_NEW(mapname);
}
usergame = !bTitleLevel; // will be set false if a demo
@ -556,18 +570,24 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
return;
}
nextlevel = levelname;
if (strncmp(levelname, "enDSeQ", 6))
if (strncmp(levelname, "enDSeQ", 6) != 0)
{
nextinfo = FindLevelInfo (nextlevel)->CheckLevelRedirect ();
if (nextinfo)
nextinfo = FindLevelInfo (nextlevel);
if (nextinfo != NULL)
{
nextlevel = nextinfo->mapname;
level_info_t *nextredir = nextinfo->CheckLevelRedirect();
if (nextredir != NULL)
{
nextinfo = nextredir;
levelname = nextinfo->mapname;
}
}
}
if (nextSkill != -1) NextSkill = nextSkill;
nextlevel = levelname;
if (nextSkill != -1)
NextSkill = nextSkill;
g_nomonsters = nomonsters;
@ -596,6 +616,8 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
unloading = false;
STAT_END(nextlevel);
if (thiscluster && (thiscluster->flags & CLUSTER_HUB))
{
if ((level.flags & LEVEL_NOINTERMISSION) || (nextcluster == thiscluster))
@ -1389,6 +1411,8 @@ void G_AirControlChanged ()
void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
int i = level.totaltime;
screen->StartSerialize(arc);
arc << level.flags
<< level.flags2
@ -1507,6 +1531,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
}
}
}
screen->EndSerialize(arc);
}
//==========================================================================
@ -1627,6 +1652,7 @@ void G_WriteSnapshots (FILE *file)
{
unsigned int i;
STAT_WRITE(file);
for (i = 0; i < wadlevelinfos.Size(); i++)
{
if (wadlevelinfos[i].snapshot)
@ -1777,6 +1803,7 @@ void G_ReadSnapshots (PNGHandle *png)
arc << pnum;
}
}
STAT_READ(png);
png->File->ResetFilePtr();
}

View file

@ -85,7 +85,9 @@ level_info_t *FindLevelInfo (const char *mapname)
int i;
if ((i = FindWadLevelInfo (mapname)) > -1)
{
return &wadlevelinfos[i];
}
else
{
if (TheDefaultLevelInfo.LevelName.IsEmpty())
@ -1359,6 +1361,7 @@ MapFlagHandlers[] =
{ "compat_mbfmonstermove", MITYPE_COMPATFLAG, COMPATF_MBFMONSTERMOVE},
{ "compat_corpsegibs", MITYPE_COMPATFLAG, COMPATF_CORPSEGIBS},
{ "compat_noblockfriends", MITYPE_COMPATFLAG, COMPATF_NOBLOCKFRIENDS},
{ "compat_spritesort", MITYPE_COMPATFLAG, COMPATF_SPRITESORT},
{ "cd_start_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end1_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end2_track", MITYPE_EATNEXT, 0, 0 },
@ -1461,6 +1464,10 @@ void FMapInfoParser::ParseMapDefinition(level_info_t &info)
{
if (sc.Compare(((FMapOptInfo *)(*probe))->name))
{
if (!((FMapOptInfo *)(*probe))->old && format_type != FMT_New)
{
sc.ScriptError("MAPINFO option '%s' requires the new MAPINFO format", sc.String);
}
((FMapOptInfo *)(*probe))->handler(*this, &info);
success = true;
break;

View file

@ -82,49 +82,6 @@ void AMinotaurFriend::Serialize (FArchive &arc)
arc << StartTime;
}
bool AMinotaurFriend::IsOkayToAttack (AActor *link)
{
if ((link->flags3 & MF3_ISMONSTER) && (link != tracer))
{
if (!((link->flags ^ flags) & MF_FRIENDLY))
{ // Don't attack friends
if (link->flags & MF_FRIENDLY)
{
if (!deathmatch || link->FriendPlayer == 0 || FriendPlayer == 0 ||
link->FriendPlayer != FriendPlayer)
{
return false;
}
}
else
{
return false;
}
}
if (!(link->flags&MF_SHOOTABLE))
{
return false;
}
if (link->flags2&MF2_DORMANT)
{
return false;
}
if ((link->flags5 & MF5_SUMMONEDMONSTER) && (link->tracer == tracer))
{
return false;
}
if (multiplayer && !deathmatch && link->player)
{
return false;
}
if (P_CheckSight (this, link))
{
return true;
}
}
return false;
}
void AMinotaurFriend::Die (AActor *source, AActor *inflictor)
{
Super::Die (source, inflictor);

View file

@ -20,7 +20,6 @@ class AMinotaurFriend : public AMinotaur
public:
int StartTime;
bool IsOkayToAttack (AActor *target);
void Die (AActor *source, AActor *inflictor);
bool OkayToSwitchTarget (AActor *other);
void BeginPlay ();

View file

@ -183,6 +183,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
self->flags2 |= MF2_PUSHABLE|MF2_TELESTOMP|MF2_PASSMOBJ|MF2_SLIDE;
self->flags3 |= MF3_CRASHED;
self->height = self->GetDefault()->height;
// Remove fuzz effects from frozen actors.
if (self->RenderStyle.BlendOp >= STYLEOP_Fuzz && self->RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
{
self->RenderStyle = STYLE_Normal;
}
S_Sound (self, CHAN_BODY, "misc/freeze", 1, ATTN_NORM);
// [RH] Andy Baker's stealth monsters
@ -198,7 +204,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath)
self->player->poisoncount = 0;
self->player->bonuscount = 0;
}
else if (self->flags3&MF3_ISMONSTER && self->special)
else if (self->flags3 & MF3_ISMONSTER && self->special)
{ // Initiate monster death actions
LineSpecials [self->special] (NULL, self, false, self->args[0],
self->args[1], self->args[2], self->args[3], self->args[4]);
@ -261,18 +267,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
int numChunks;
AActor *mo;
if (self->velx || self->vely || self->velz)
if ((self->velx || self->vely || self->velz) && !(self->flags6 & MF6_SHATTERING))
{
self->tics = 3*TICRATE;
return 0;
}
self->velx = self->vely = self->velz = 0;
S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM);
// [RH] In Hexen, this creates a random number of shards (range [24,56])
// with no relation to the size of the self shattering. I think it should
// base the number of shards on the size of the dead thing, so bigger
// things break up into more shards than smaller things.
// An self with radius 20 and height 64 creates ~40 chunks.
// An actor with radius 20 and height 64 creates ~40 chunks.
numChunks = MAX<int> (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32);
i = (pr_freeze.Random2()) % (numChunks/4);
for (i = MAX (24, numChunks + i); i >= 0; i--)

View file

@ -298,6 +298,13 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor
else return FNullTextureID();
CalcFracPos (wall, x, y);
FTexture *texture = TexMan[tex];
if (texture == NULL || texture->bNoDecals)
{
return FNullTextureID();
}
return tex;
}
@ -412,7 +419,7 @@ static fixed_t Length (fixed_t dx, fixed_t dy)
static side_t *NextWall (const side_t *wall)
{
line_t *line = wall->linedef;;
line_t *line = wall->linedef;
if (line->sidedef[0] == wall)
{
@ -546,11 +553,18 @@ DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_
DBaseDecal *decal = new DBaseDecal(iz);
if (decal != NULL)
{
decal->StickToWall (wall, ix, iy, ffloor);
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
{
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
}
else
{
decal->Destroy();
return NULL;
}
}
return decal;
}
@ -641,26 +655,23 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
{
if (tpl->LowerDecal)
{
int lowercolor = color;
int lowercolor;
const FDecalTemplate * tpl_low = tpl->LowerDecal->GetDecal();
// If the default color of the lower decal is the same as the main decal's
// apply the custom color as well.
if (tpl->ShadeColor == tpl_low->ShadeColor) lowercolor=0;
if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0;
else lowercolor = color;
StaticCreate (tpl_low, x, y, z, wall, ffloor, lowercolor);
}
DImpactDecal::CheckMax();
decal = new DImpactDecal (z);
FTextureID stickypic = decal->StickToWall (wall, x, y, ffloor);
FTexture *tex = TexMan[stickypic];
if (tex != NULL && tex->bNoDecals)
if (decal == NULL)
{
return NULL;
}
if (decal == NULL)
if (!decal->StickToWall (wall, x, y, ffloor).isValid())
{
return NULL;
}
@ -684,15 +695,27 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_t iy, fixed_t iz, side_t *wall, F3DFloor * ffloor) const
{
if (wall->Flags & WALLF_NOAUTODECALS)
{
return NULL;
}
DImpactDecal::CheckMax();
DImpactDecal *decal = new DImpactDecal(iz);
if (decal != NULL)
{
decal->StickToWall (wall, ix, iy, ffloor);
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
{
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
}
else
{
decal->Destroy();
return NULL;
}
}
return decal;
}

View file

@ -2,6 +2,8 @@
#include "a_sharedglobal.h"
#include "p_local.h"
#include "g_level.h"
#include "r_sky.h"
#include "p_lnspec.h"
IMPLEMENT_CLASS(AFastProjectile)
@ -26,6 +28,7 @@ void AFastProjectile::Tick ()
PrevX = x;
PrevY = y;
PrevZ = z;
PrevAngle = angle;
if (!(flags5 & MF5_NOTIMEFREEZE))
{
@ -71,6 +74,26 @@ void AFastProjectile::Tick ()
if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm))
{ // Blocked move
if (!(flags3 & MF3_SKYEXPLODE))
{
if (tm.ceilingline &&
tm.ceilingline->backsector &&
tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum &&
z >= tm.ceilingline->backsector->ceilingplane.ZatPoint (x, y))
{
// Hack to prevent missiles exploding against the sky.
// Does not handle sky floors.
Destroy ();
return;
}
// [RH] Don't explode on horizon lines.
if (BlockingLine != NULL && BlockingLine->special == Line_Horizon)
{
Destroy ();
return;
}
}
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
@ -78,6 +101,15 @@ void AFastProjectile::Tick ()
z += zfrac;
if (z <= floorz)
{ // Hit the floor
if (floorpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE))
{
// [RH] Just remove the missile without exploding it
// if this is a sky floor.
Destroy ();
return;
}
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
@ -85,6 +117,13 @@ void AFastProjectile::Tick ()
}
if (z + height > ceilingz)
{ // Hit the ceiling
if (ceilingpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE))
{
Destroy ();
return;
}
z = ceilingz - height;
P_ExplodeMissile (this, NULL, NULL);
return;
@ -99,7 +138,7 @@ void AFastProjectile::Tick ()
// Advance the state
if (tics != -1)
{
tics--;
if (tics > 0) tics--;
while (!tics)
{
if (!SetState (state->GetNextState ()))
@ -113,5 +152,27 @@ void AFastProjectile::Tick ()
void AFastProjectile::Effect()
{
//if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent
{
FName name = (ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None);
if (name != NAME_None)
{
fixed_t hitz = z-8*FRACUNIT;
if (hitz < floorz)
{
hitz = floorz;
}
const PClass *trail = PClass::FindClass(name);
if (trail != NULL)
{
AActor *act = Spawn (trail, x, y, hitz, ALLOW_REPLACE);
if (act != NULL)
{
act->angle = this->angle;
}
}
}
}
}

View file

@ -177,7 +177,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
{
AWeapon *beastweap;
APlayerPawn *mo;
AActor *pmo;
APlayerPawn *pmo;
angle_t angle;
pmo = player->mo;
@ -192,7 +192,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
return false;
}
bool DeliberateUnmorphIsOkay = !!(player->MorphStyle & unmorphflag);
bool DeliberateUnmorphIsOkay = !!(MORPH_STANDARDUNDOING & unmorphflag);
if ((pmo->flags2 & MF2_INVULNERABLE) // If the player is invulnerable
&& ((player != activator) // and either did not decide to unmorph,
@ -314,7 +314,10 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
}
angle = mo->angle >> ANGLETOFINESHIFT;
Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE);
if (exit_flash != NULL)
{
Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE);
}
mo->SetupWeaponSlots(); // Use original class's weapon slots.
beastweap = player->ReadyWeapon;
if (player->PremorphWeapon != NULL)
@ -327,7 +330,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
}
if (correctweapon)
{ // Better "lose morphed weapon" semantics
const PClass *morphweapon = PClass::FindClass (mo->MorphWeapon);
const PClass *morphweapon = PClass::FindClass (pmo->MorphWeapon);
if (morphweapon != NULL && morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon)))
{
AWeapon *OriginalMorphWeapon = static_cast<AWeapon *>(mo->FindInventory (morphweapon));

View file

@ -23,6 +23,9 @@ enum
MORPH_UNDOBYDEATH = 0x00000200, // Actor unmorphs when killed and (unless MORPH_UNDOBYDEATHSAVES) stays dead
MORPH_UNDOBYDEATHFORCED = 0x00000400, // Actor (if unmorphed when killed) forces unmorph (not very useful with UNDOBYDEATHSAVES)
MORPH_UNDOBYDEATHSAVES = 0x00000800, // Actor (if unmorphed when killed) regains their health and doesn't die
MORPH_UNDOBYTIMEOUT = 0x00001000, // Player unmorphs once countdown expires
MORPH_STANDARDUNDOING = MORPH_UNDOBYTOMEOFPOWER | MORPH_UNDOBYCHAOSDEVICE | MORPH_UNDOBYTIMEOUT,
};
class PClass;

View file

@ -507,6 +507,7 @@ class AActorMover : public APathFollower
{
DECLARE_CLASS (AActorMover, APathFollower)
public:
void BeginPlay();
void PostBeginPlay ();
void Activate (AActor *activator);
void Deactivate (AActor *activator);
@ -516,6 +517,11 @@ protected:
IMPLEMENT_CLASS (AActorMover)
void AActorMover::BeginPlay()
{
ChangeStatNum(STAT_ACTORMOVER);
}
void AActorMover::PostBeginPlay ()
{
Super::PostBeginPlay ();
@ -585,6 +591,7 @@ void AActorMover::Activate (AActor *activator)
tracer->PrevX = tracer->x;
tracer->PrevY = tracer->y;
tracer->PrevZ = tracer->z;
tracer->PrevAngle = tracer->angle;
}
void AActorMover::Deactivate (AActor *activator)

View file

@ -1202,7 +1202,7 @@ bool AInventory::TryPickup (AActor *&toucher)
ItemFlags &= ~IF_PICKUPGOOD;
GoAwayAndDie ();
}
else if (MaxAmount == 0)
else if (MaxAmount == 0 && !IsKindOf(RUNTIME_CLASS(AAmmo)))
{
// Special case: If an item's MaxAmount is 0, you can still pick it
// up if it is autoactivate-able.
@ -1581,7 +1581,7 @@ void ABackpackItem::Serialize (FArchive &arc)
AInventory *ABackpackItem::CreateCopy (AActor *other)
{
// Find every unique type of ammo. Give it to the player if
// he doesn't have it already, and double it's maximum capacity.
// he doesn't have it already, and double its maximum capacity.
for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
{
const PClass *type = PClass::m_Types[i];
@ -1600,7 +1600,14 @@ AInventory *ABackpackItem::CreateCopy (AActor *other)
{ // The player did not have the ammo. Add it.
ammo = static_cast<AAmmo *>(Spawn (type, 0, 0, 0, NO_REPLACE));
ammo->Amount = bDepleted ? 0 : amount;
if (ammo->BackpackMaxAmount > ammo->MaxAmount) ammo->MaxAmount = ammo->BackpackMaxAmount;
if (ammo->BackpackMaxAmount > ammo->MaxAmount)
{
ammo->MaxAmount = ammo->BackpackMaxAmount;
}
if (ammo->Amount > ammo->MaxAmount)
{
ammo->Amount = ammo->MaxAmount;
}
ammo->AttachToOwner (other);
}
else
@ -1643,7 +1650,7 @@ bool ABackpackItem::HandlePickup (AInventory *item)
{
if (probe->GetClass()->ParentClass == RUNTIME_CLASS(AAmmo))
{
if (probe->Amount < probe->MaxAmount)
if (probe->Amount < probe->MaxAmount || sv_unlimited_pickup)
{
int amount = static_cast<AAmmo*>(probe->GetDefault())->BackpackAmount;
// extra ammo in baby mode and nightmare mode
@ -1652,7 +1659,7 @@ bool ABackpackItem::HandlePickup (AInventory *item)
amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor));
}
probe->Amount += amount;
if (probe->Amount > probe->MaxAmount)
if (probe->Amount > probe->MaxAmount && !sv_unlimited_pickup)
{
probe->Amount = probe->MaxAmount;
}

View file

@ -33,14 +33,14 @@ DEarthquake::DEarthquake()
//==========================================================================
DEarthquake::DEarthquake (AActor *center, int intensity, int duration,
int damrad, int tremrad)
int damrad, int tremrad, FSoundID quakesound)
: DThinker(STAT_EARTHQUAKE)
{
m_QuakeSFX = "world/quake";
m_QuakeSFX = quakesound;
m_Spot = center;
// Radii are specified in tile units (64 pixels)
m_DamageRadius = damrad << (FRACBITS+6);
m_TremorRadius = tremrad << (FRACBITS+6);
m_DamageRadius = damrad << (FRACBITS);
m_TremorRadius = tremrad << (FRACBITS);
m_Intensity = intensity;
m_Countdown = duration;
}
@ -56,7 +56,15 @@ void DEarthquake::Serialize (FArchive &arc)
Super::Serialize (arc);
arc << m_Spot << m_Intensity << m_Countdown
<< m_TremorRadius << m_DamageRadius;
m_QuakeSFX = "world/quake";
if (SaveVersion >= 1912)
{
arc << m_QuakeSFX;
}
else
{
m_QuakeSFX = "world/quake";
}
}
//==========================================================================
@ -158,7 +166,7 @@ int DEarthquake::StaticGetQuakeIntensity (AActor *victim)
//
//==========================================================================
bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad)
bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx)
{
AActor *center;
bool res = false;
@ -169,7 +177,7 @@ bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int
{
if (activator != NULL)
{
new DEarthquake(activator, intensity, duration, damrad, tremrad);
new DEarthquake(activator, intensity, duration, damrad, tremrad, quakesfx);
return true;
}
}
@ -179,7 +187,7 @@ bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int
while ( (center = iterator.Next ()) )
{
res = true;
new DEarthquake (center, intensity, duration, damrad, tremrad);
new DEarthquake (center, intensity, duration, damrad, tremrad, quakesfx);
}
}

View file

@ -67,20 +67,29 @@ class ARandomSpawner : public AActor
else if (pr_randomspawn() <= di->probability) // prob 255 = always spawn, prob 0 = never spawn.
{
// Handle replacement here so as to get the proper speed and flags for missiles
const PClass * cls; PClass * rep;
const PClass *cls;
cls = PClass::FindClass(di->Name);
if (cls) rep = cls->ActorInfo->GetReplacement()->Class;
if (rep) cls = rep;
if (cls)
if (cls != NULL)
{
const PClass *rep = cls->ActorInfo->GetReplacement()->Class;
if (rep != NULL)
{
cls = rep;
}
}
if (cls != NULL)
{
Species = cls->TypeName;
AActor * defmobj = GetDefaultByType(cls);
AActor *defmobj = GetDefaultByType(cls);
this->Speed = defmobj->Speed;
this->flags |= (defmobj->flags & MF_MISSILE);
this->flags2 |= (defmobj->flags2 & MF2_SEEKERMISSILE);
this->flags4 |= (defmobj->flags4 & MF4_SPECTRAL);
}
else Species = NAME_None;
else
{
Species = NAME_None;
}
}
}
}
@ -152,7 +161,7 @@ class ARandomSpawner : public AActor
boss = true;
// If a replaced actor has either of those same flags, it's also a boss.
AActor * rep = GetDefaultByType(GetClass()->ActorInfo->GetReplacee()->Class);
if (rep && (rep->flags4 & MF4_BOSSDEATH) || (rep->flags2 & MF2_BOSS))
if (rep && ((rep->flags4 & MF4_BOSSDEATH) || (rep->flags2 & MF2_BOSS)))
boss = true;
}
if (boss) this->tracer = newmobj;

View file

@ -89,16 +89,24 @@ public:
class ASkyViewpoint : public AActor
{
DECLARE_CLASS (ASkyViewpoint, AActor)
HAS_OBJECT_POINTERS
public:
void Serialize (FArchive &arc);
void BeginPlay ();
void Destroy ();
bool bInSkybox;
bool bAlways;
ASkyViewpoint *Mate;
TObjPtr<ASkyViewpoint> Mate;
fixed_t PlaneAlpha;
};
class AStackPoint : public ASkyViewpoint
{
DECLARE_CLASS (AStackPoint, ASkyViewpoint)
public:
void BeginPlay ();
};
class DFlashFader : public DThinker
{
DECLARE_CLASS (DFlashFader, DThinker)
@ -128,7 +136,7 @@ class DEarthquake : public DThinker
DECLARE_CLASS (DEarthquake, DThinker)
HAS_OBJECT_POINTERS
public:
DEarthquake (AActor *center, int intensity, int duration, int damrad, int tremrad);
DEarthquake (AActor *center, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx);
void Serialize (FArchive &arc);
void Tick ();

View file

@ -35,10 +35,13 @@
#include "actor.h"
#include "a_sharedglobal.h"
#include "p_local.h"
#include "p_lnspec.h"
// arg0 = Visibility*4 for this skybox
IMPLEMENT_CLASS (ASkyViewpoint)
IMPLEMENT_POINTY_CLASS (ASkyViewpoint)
DECLARE_POINTER(Mate)
END_POINTERS
// If this actor has no TID, make it the default sky box
void ASkyViewpoint::BeginPlay ()
@ -86,6 +89,64 @@ void ASkyViewpoint::Destroy ()
Super::Destroy();
}
// For an RR compatible linedef based definition. This searches the viewpoint's sector
// for a skybox line special, gets its tag and transfers the skybox to all tagged sectors.
class ASkyCamCompat : public ASkyViewpoint
{
DECLARE_CLASS (ASkyCamCompat, ASkyViewpoint)
public:
void BeginPlay ();
};
IMPLEMENT_CLASS (ASkyCamCompat)
extern FTextureID skyflatnum;
void ASkyCamCompat::BeginPlay ()
{
if (Sector == NULL)
{
Printf("Sector not initialized for SkyCamCompat\n");
Sector = P_PointInSector(x, y);
}
if (Sector)
{
line_t * refline = NULL;
for (short i = 0; i < Sector->linecount; i++)
{
refline = Sector->lines[i];
if (refline->special == Sector_SetPortal && refline->args[1] == 2)
{
// We found the setup linedef for this skybox, so let's use it for our init.
int skybox_id = refline->args[0];
// Then, change the alpha
alpha = refline->args[4];
// Finally, skyboxify all tagged sectors
// This involves changing their texture to the sky flat, because while
// EE works with any texture for its skybox portals, ZDoom doesn't.
for (int secnum =-1; (secnum = P_FindSectorFromTag (skybox_id, secnum)) != -1; )
{
// plane: 0=floor, 1=ceiling, 2=both
if (refline->args[2] == 1 || refline->args[2] == 2)
{
sectors[secnum].CeilingSkyBox = this;
sectors[secnum].SetTexture(sector_t::ceiling, skyflatnum, false);
}
if (refline->args[2] == 0 || refline->args[2] == 2)
{
sectors[secnum].FloorSkyBox = this;
sectors[secnum].SetTexture(sector_t::floor, skyflatnum, false);
}
}
}
}
}
// Do not call the SkyViewpoint's super method because it would trash our setup
AActor::BeginPlay();
}
//---------------------------------------------------------------------------
// arg0 = tid of matching SkyViewpoint
@ -144,13 +205,6 @@ void ASkyPicker::PostBeginPlay ()
// arg0 = opacity of plane; 0 = invisible, 255 = fully opaque
class AStackPoint : public ASkyViewpoint
{
DECLARE_CLASS (AStackPoint, ASkyViewpoint)
public:
void BeginPlay ();
};
IMPLEMENT_CLASS (AStackPoint)
void AStackPoint::BeginPlay ()
@ -161,50 +215,6 @@ void AStackPoint::BeginPlay ()
bAlways = true;
}
//---------------------------------------------------------------------------
// Upper stacks go in the top sector. Lower stacks go in the bottom sector.
class AUpperStackLookOnly : public AStackPoint
{
DECLARE_CLASS (AUpperStackLookOnly, AStackPoint)
public:
void PostBeginPlay ();
};
class ALowerStackLookOnly : public AStackPoint
{
DECLARE_CLASS (ALowerStackLookOnly, AStackPoint)
public:
void PostBeginPlay ();
};
IMPLEMENT_CLASS (AUpperStackLookOnly)
IMPLEMENT_CLASS (ALowerStackLookOnly)
void AUpperStackLookOnly::PostBeginPlay ()
{
Super::PostBeginPlay ();
TActorIterator<ALowerStackLookOnly> it (tid);
Sector->FloorSkyBox = it.Next();
if (Sector->FloorSkyBox != NULL)
{
Sector->FloorSkyBox->Mate = this;
Sector->FloorSkyBox->PlaneAlpha = Scale (args[0], OPAQUE, 255);
}
}
void ALowerStackLookOnly::PostBeginPlay ()
{
Super::PostBeginPlay ();
TActorIterator<AUpperStackLookOnly> it (tid);
Sector->CeilingSkyBox = it.Next();
if (Sector->CeilingSkyBox != NULL)
{
Sector->CeilingSkyBox->Mate = this;
Sector->CeilingSkyBox->PlaneAlpha = Scale (args[0], OPAQUE, 255);
}
}
//---------------------------------------------------------------------------
class ASectorSilencer : public AActor

View file

@ -32,6 +32,9 @@
**
*/
#ifndef __SBAR_H__
#define __SBAR_H__
#include "dobject.h"
#include "v_collection.h"
#include "v_text.h"
@ -195,22 +198,37 @@ private:
};
class player_t;
struct FMugShot
class FMugShot
{
FMugShot();
void Tick(player_t *player);
bool SetState(const char *state_name, bool wait_till_done=false, bool reset=false);
int UpdateState(player_t *player, int stateflags=0);
FTexture *GetFace(player_t *player, const char *default_face, int accuracy, int stateflags=0);
public:
enum StateFlags
{
STANDARD = 0x0,
FMugShotState *CurrentState;
int RampageTimer;
int LastDamageAngle;
int FaceHealth;
bool bEvilGrin;
bool bDamageFaceActive;
bool bNormal;
bool bOuchActive;
XDEATHFACE = 0x1,
ANIMATEDGODMODE = 0x2,
DISABLEGRIN = 0x4,
DISABLEOUCH = 0x8,
DISABLEPAIN = 0x10,
DISABLERAMPAGE = 0x20,
};
FMugShot();
void Grin(bool grin=true) { bEvilGrin = grin; }
void Tick(player_t *player);
bool SetState(const char *state_name, bool wait_till_done=false, bool reset=false);
int UpdateState(player_t *player, StateFlags stateflags=STANDARD);
FTexture *GetFace(player_t *player, const char *default_face, int accuracy, StateFlags stateflags=STANDARD);
private:
FMugShotState *CurrentState;
int RampageTimer;
int LastDamageAngle;
int FaceHealth;
bool bEvilGrin;
bool bDamageFaceActive;
bool bNormal;
bool bOuchActive;
};
extern TArray<FMugShotState> MugShotStates;
@ -369,3 +387,5 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0);
void ST_LoadCrosshair(bool alwaysload=false);
extern FTexture *CrosshairImage;
#endif /* __SBAR_H__ */

View file

@ -324,7 +324,7 @@ bool FMugShot::SetState(const char *state_name, bool wait_till_done, bool reset)
//
//===========================================================================
int FMugShot::UpdateState(player_t *player, int stateflags)
int FMugShot::UpdateState(player_t *player, StateFlags stateflags)
{
int i;
angle_t badguyangle;
@ -333,7 +333,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
if (player->health > 0)
{
if (bEvilGrin && !(stateflags & DRAWMUGSHOT_DISABLEGRIN))
if (bEvilGrin && !(stateflags & DISABLEGRIN))
{
if (player->bonuscount)
{
@ -348,7 +348,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
if (player->damagecount &&
// Now go in if pain is disabled but we think ouch will be shown (and ouch is not disabled!)
(!(stateflags & DRAWMUGSHOT_DISABLEPAIN) || (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DRAWMUGSHOT_DISABLEOUCH))))
(!(stateflags & DISABLEPAIN) || (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH))))
{
int damage_angle = 1;
if (player->attacker && player->attacker != player->mo)
@ -380,7 +380,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
}
}
bool use_ouch = false;
if (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DRAWMUGSHOT_DISABLEOUCH))
if (((FaceHealth != -1 && FaceHealth - player->health > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH))
{
use_ouch = true;
full_state_name = "ouch.";
@ -407,7 +407,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
else
{
bool use_ouch = false;
if (((FaceHealth != -1 && player->health - FaceHealth > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DRAWMUGSHOT_DISABLEOUCH))
if (((FaceHealth != -1 && player->health - FaceHealth > ST_MUCHPAIN) || bOuchActive) && !(stateflags & DISABLEOUCH))
{
use_ouch = true;
full_state_name = "ouch.";
@ -425,7 +425,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
}
}
if (RampageTimer == ST_RAMPAGEDELAY && !(stateflags & DRAWMUGSHOT_DISABLERAMPAGE))
if (RampageTimer == ST_RAMPAGEDELAY && !(stateflags & DISABLERAMPAGE))
{
SetState("rampage", !bNormal); //If we have nothing better to show, use the rampage face.
return 0;
@ -436,7 +436,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
bool good;
if ((player->cheats & CF_GODMODE) || (player->mo != NULL && player->mo->flags2 & MF2_INVULNERABLE))
{
good = SetState((stateflags & DRAWMUGSHOT_ANIMATEDGODMODE) ? "godanimated" : "god");
good = SetState((stateflags & ANIMATEDGODMODE) ? "godanimated" : "god");
}
else
{
@ -450,7 +450,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
}
else
{
if (!(stateflags & DRAWMUGSHOT_XDEATHFACE) || !(player->cheats & CF_EXTREMELYDEAD))
if (!(stateflags & XDEATHFACE) || !(player->cheats & CF_EXTREMELYDEAD))
{
full_state_name = "death.";
}
@ -473,7 +473,7 @@ int FMugShot::UpdateState(player_t *player, int stateflags)
//
//===========================================================================
FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accuracy, int stateflags)
FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accuracy, StateFlags stateflags)
{
int angle = UpdateState(player, stateflags);
int level = 0;

1320
src/g_shared/sbarinfo.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -37,57 +37,24 @@
#define __SBarInfo_SBAR_H__
#include "tarray.h"
#include "v_collection.h"
#define NUMHUDS 9
#define NUMPOPUPS 3
class FBarTexture;
class FScanner;
/**
* This class is used to help prevent errors that may occur from adding or
* subtracting from coordinates.
*
* In order to provide the maximum flexibility, coordinates are packed into
* an int with one bit reserved for relCenter.
*/
class SBarInfoCoordinate
{
public:
SBarInfoCoordinate &Add(int add);
int Coordinate() const { return value; }
bool RelCenter() const { return relCenter; }
void Set(int coord, bool center) { value = coord; relCenter = center; }
void SetCoord(int coord) { value = coord; }
void SetRelCenter(bool center) { relCenter = center; }
int operator* () const { return Coordinate(); }
SBarInfoCoordinate operator+ (int add) const { return SBarInfoCoordinate(*this).Add(add); }
SBarInfoCoordinate operator+ (const SBarInfoCoordinate &other) const { return SBarInfoCoordinate(*this).Add(other.Coordinate()); }
SBarInfoCoordinate operator- (int sub) const { return SBarInfoCoordinate(*this).Add(-sub); }
SBarInfoCoordinate operator- (const SBarInfoCoordinate &other) const { return SBarInfoCoordinate(*this).Add(-other.Coordinate()); }
void operator+= (int add) { Add(add); }
void operator-= (int sub) { Add(-sub); }
protected:
unsigned relCenter:1;
int value:31;
};
struct SBarInfoCommand; //we need to be able to use this before it is defined.
struct MugShotState;
class SBarInfoMainBlock;
//Popups!
enum PopupTransition
{
TRANSITION_NONE,
TRANSITION_SLIDEINBOTTOM,
TRANSITION_FADE,
};
struct Popup
{
enum PopupTransition
{
TRANSITION_NONE,
TRANSITION_SLIDEINBOTTOM,
TRANSITION_FADE,
};
PopupTransition transition;
bool opened;
bool moving;
@ -110,54 +77,10 @@ struct Popup
int getAlpha(int maxAlpha=FRACUNIT);
};
//SBarInfo
struct SBarInfoBlock
{
TArray<SBarInfoCommand> commands;
bool forceScaled;
bool fullScreenOffsets;
int alpha;
SBarInfoBlock();
};
struct SBarInfoCommand
{
SBarInfoCommand();
~SBarInfoCommand();
void setString(FScanner &sc, const char* source, int strnum, int maxlength=-1, bool exact=false);
int type;
int special;
union
{
int special2;
SBarInfoCoordinate sbcoord2;
};
union
{
int special3;
SBarInfoCoordinate sbcoord3;
};
int special4;
int flags;
SBarInfoCoordinate x;
SBarInfoCoordinate y;
int value;
int image_index;
FTextureID sprite_index;
FString string[2];
FFont *font;
EColorRange translation;
EColorRange translation2;
EColorRange translation3;
SBarInfoBlock subBlock; //for type SBarInfo_CMD_GAMEMODE
};
struct SBarInfo
{
TArray<FString> Images;
SBarInfoBlock huds[NUMHUDS];
SBarInfoMainBlock *huds[NUMHUDS];
Popup popups[NUMPOPUPS];
bool automapbar;
bool interpolateHealth;
@ -169,16 +92,14 @@ struct SBarInfo
int armorInterpolationSpeed;
int height;
int gameType;
FMugShot MugShot;
int GetGameType() { return gameType; }
void ParseSBarInfo(int lump);
void ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block);
void ParseMugShotBlock(FScanner &sc, FMugShotState &state);
void getCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y); //retrieves the next two arguments as x and y.
int getSignedInteger(FScanner &sc); //returns a signed integer.
void ResetHuds();
int newImage(const char* patchname);
void Init();
EColorRange GetTranslation(FScanner &sc, const char* translation);
SBarInfo();
SBarInfo(int lumpnum);
~SBarInfo();
@ -190,243 +111,4 @@ struct SBarInfo
#define SCRIPT_DEFAULT 1
extern SBarInfo *SBarInfoScript[2];
// Enums used between the parser and the display
enum //gametype flags
{
GAMETYPE_SINGLEPLAYER = 1,
GAMETYPE_COOPERATIVE = 2,
GAMETYPE_DEATHMATCH = 4,
GAMETYPE_TEAMGAME = 8,
};
enum //drawimage flags
{
DRAWIMAGE_PLAYERICON = 0x1,
DRAWIMAGE_AMMO1 = 0x2,
DRAWIMAGE_AMMO2 = 0x4,
DRAWIMAGE_INVENTORYICON = 0x8,
DRAWIMAGE_TRANSLATABLE = 0x10,
DRAWIMAGE_WEAPONSLOT = 0x20,
DRAWIMAGE_SWITCHABLE_AND = 0x40,
DRAWIMAGE_INVULNERABILITY = 0x80,
DRAWIMAGE_OFFSET_CENTER = 0x100,
DRAWIMAGE_OFFSET_CENTERBOTTOM = 0x200,
DRAWIMAGE_ARMOR = 0x800,
DRAWIMAGE_WEAPONICON = 0x1000,
DRAWIMAGE_SIGIL = 0x2000,
DRAWIMAGE_KEYSLOT = 0x4000,
DRAWIMAGE_HEXENARMOR = 0x8000,
DRAWIMAGE_OFFSET = DRAWIMAGE_OFFSET_CENTER|DRAWIMAGE_OFFSET_CENTERBOTTOM,
};
enum //drawnumber flags
{
DRAWNUMBER_HEALTH = 0x1,
DRAWNUMBER_ARMOR = 0x2,
DRAWNUMBER_AMMO1 = 0x4,
DRAWNUMBER_AMMO2 = 0x8,
DRAWNUMBER_AMMO = 0x10,
DRAWNUMBER_AMMOCAPACITY = 0x20,
DRAWNUMBER_FRAGS = 0x40,
DRAWNUMBER_INVENTORY = 0x80,
DRAWNUMBER_KILLS = 0x100,
DRAWNUMBER_MONSTERS = 0x200,
DRAWNUMBER_ITEMS = 0x400,
DRAWNUMBER_TOTALITEMS = 0x800,
DRAWNUMBER_SECRETS = 0x1000,
DRAWNUMBER_TOTALSECRETS = 0x2000,
DRAWNUMBER_ARMORCLASS = 0x4000,
DRAWNUMBER_GLOBALVAR = 0x8000,
DRAWNUMBER_GLOBALARRAY = 0x10000,
DRAWNUMBER_FILLZEROS = 0x20000,
DRAWNUMBER_WHENNOTZERO = 0x40000,
DRAWNUMBER_POWERUPTIME = 0x80000,
DRAWNUMBER_DRAWSHADOW = 0x100000,
DRAWNUMBER_AIRTIME = 0x200000,
};
enum //drawbar flags (will go into special2)
{
DRAWBAR_HORIZONTAL = 1,
DRAWBAR_REVERSE = 2,
DRAWBAR_COMPAREDEFAULTS = 4,
};
enum //drawselectedinventory flags
{
DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY = 0x1,
DRAWSELECTEDINVENTORY_ARTIFLASH = 0x2,
DRAWSELECTEDINVENTORY_ALWAYSSHOWCOUNTER = 0x4,
DRAWSELECTEDINVENTORY_CENTER = 0x8,
DRAWSELECTEDINVENTORY_CENTERBOTTOM = 0x10,
DRAWSELECTEDINVENTORY_DRAWSHADOW = 0x20,
};
enum //drawinventorybar flags
{
DRAWINVENTORYBAR_ALWAYSSHOW = 0x1,
DRAWINVENTORYBAR_NOARTIBOX = 0x2,
DRAWINVENTORYBAR_NOARROWS = 0x4,
DRAWINVENTORYBAR_ALWAYSSHOWCOUNTER = 0x8,
DRAWINVENTORYBAR_TRANSLUCENT = 0x10,
DRAWINVENTORYBAR_VERTICAL = 0x20,
};
enum //drawgem flags
{
DRAWGEM_WIGGLE = 1,
DRAWGEM_TRANSLATABLE = 2,
DRAWGEM_ARMOR = 4,
DRAWGEM_REVERSE = 8,
};
enum //drawshader flags
{
DRAWSHADER_VERTICAL = 1,
DRAWSHADER_REVERSE = 2,
};
enum //drawmugshot flags
{
DRAWMUGSHOT_XDEATHFACE = 0x1,
DRAWMUGSHOT_ANIMATEDGODMODE = 0x2,
DRAWMUGSHOT_DISABLEGRIN = 0x4,
DRAWMUGSHOT_DISABLEOUCH = 0x8,
DRAWMUGSHOT_DISABLEPAIN = 0x10,
DRAWMUGSHOT_DISABLERAMPAGE = 0x20,
};
enum //drawkeybar flags
{
DRAWKEYBAR_VERTICAL = 0x1,
DRAWKEYBAR_REVERSEROWS = 0x2,
};
enum //event flags
{
SBARINFOEVENT_NOT = 1,
SBARINFOEVENT_OR = 2,
SBARINFOEVENT_AND = 4,
};
enum //aspect ratios
{
ASPECTRATIO_4_3 = 0,
ASPECTRATIO_16_9 = 1,
ASPECTRATIO_16_10 = 2,
ASPECTRATIO_5_4 = 4,
};
enum //Key words
{
SBARINFO_BASE,
SBARINFO_HEIGHT,
SBARINFO_INTERPOLATEHEALTH,
SBARINFO_INTERPOLATEARMOR,
SBARINFO_COMPLETEBORDER,
SBARINFO_MONOSPACEFONTS,
SBARINFO_LOWERHEALTHCAP,
SBARINFO_STATUSBAR,
SBARINFO_MUGSHOT,
SBARINFO_CREATEPOPUP,
};
enum //Bar types
{
STBAR_NONE,
STBAR_FULLSCREEN,
STBAR_NORMAL,
STBAR_AUTOMAP,
STBAR_INVENTORY,
STBAR_INVENTORYFULLSCREEN,
STBAR_POPUPLOG,
STBAR_POPUPKEYS,
STBAR_POPUPSTATUS,
};
enum //Bar key words
{
SBARINFO_DRAWIMAGE,
SBARINFO_DRAWNUMBER,
SBARINFO_DRAWSWITCHABLEIMAGE,
SBARINFO_DRAWMUGSHOT,
SBARINFO_DRAWSELECTEDINVENTORY,
SBARINFO_DRAWINVENTORYBAR,
SBARINFO_DRAWBAR,
SBARINFO_DRAWGEM,
SBARINFO_DRAWSHADER,
SBARINFO_DRAWSTRING,
SBARINFO_DRAWKEYBAR,
SBARINFO_GAMEMODE,
SBARINFO_PLAYERCLASS,
SBARINFO_ASPECTRATIO,
SBARINFO_ISSELECTED,
SBARINFO_USESAMMO,
SBARINFO_USESSECONDARYAMMO,
SBARINFO_HASWEAPONPIECE,
SBARINFO_INVENTORYBARNOTVISIBLE,
SBARINFO_WEAPONAMMO,
SBARINFO_ININVENTORY,
};
//All this so I can change the mugshot state in ACS...
class FBarShader : public FTexture
{
public:
FBarShader(bool vertical, bool reverse);
const BYTE *GetColumn(unsigned int column, const Span **spans_out);
const BYTE *GetPixels();
void Unload();
private:
BYTE Pixels[512];
Span DummySpan[2];
};
class DSBarInfo : public DBaseStatusBar
{
DECLARE_CLASS(DSBarInfo, DBaseStatusBar)
public:
DSBarInfo(SBarInfo *script=NULL);
~DSBarInfo();
void Draw(EHudState state);
void NewGame();
void AttachToPlayer(player_t *player);
void Tick();
void ReceivedWeapon (AWeapon *weapon);
void FlashItem(const PClass *itemtype);
void ShowPop(int popnum);
void SetMugShotState(const char* stateName, bool waitTillDone=false, bool reset=false);
private:
void doCommands(SBarInfoBlock &block, int xOffset=0, int yOffset=0, int alpha=FRACUNIT);
void DrawGraphic(FTexture* texture, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool translate=false, bool dim=false, int offsetflags=0);
void DrawString(const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false);
void DrawNumber(int num, int len, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool fillzeros=false, bool drawshadow=false);
void DrawFace(const char *defaultFace, int accuracy, int stateflags, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets);
int updateState(bool xdth, bool animatedgodmode);
void DrawInventoryBar(int type, int num, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow,
SBarInfoCoordinate counterx, SBarInfoCoordinate countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter, int bgalpha, bool vertical);
void DrawGem(FTexture* chain, FTexture* gem, int value, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize,
bool wiggle, bool translate);
FRemapTable* getTranslation();
SBarInfo *script;
FImageCollection Images;
FPlayerSkin *oldSkin;
FFont *drawingFont;
int oldHealth;
int oldArmor;
int mugshotHealth;
int chainWiggle;
int artiflash;
int pendingPopup;
int currentPopup;
unsigned int invBarOffset;
FBarShader shader_horz_normal;
FBarShader shader_horz_reverse;
FBarShader shader_vert_normal;
FBarShader shader_vert_reverse;
FMugShot MugShot;
};
#endif //__SBarInfo_SBAR_H__

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -67,6 +67,7 @@ CVAR (Bool, hud_showsecrets, true,CVAR_ARCHIVE); // Show secrets on HUD
CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD
CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD
CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy.
CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score
CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red
CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green
@ -98,6 +99,7 @@ static FTexture * fragpic; // Frags icon
static FTexture * invgems[4]; // Inventory arrows
static int hudwidth, hudheight; // current width/height for HUD display
static int statspace;
void AM_GetPosition(fixed_t & x, fixed_t & y);
@ -158,15 +160,20 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans
static void DrawHudText(FFont *font, int color, char * text, int x, int y, int trans=0xc000)
{
int zerowidth = font->GetCharWidth('0');
int zerowidth;
FTexture *tex_zero = font->GetChar('0', &zerowidth);
x+=zerowidth/2;
for(int i=0;text[i];i++)
{
int width;
FTexture *texc = font->GetChar(text[i], &width);
int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight();
screen->DrawChar(font, color, x, y, text[i],
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans,
DTA_CenterBottomOffset, 1, TAG_DONE);
DTA_LeftOffset, width/2, DTA_TopOffset, offset,
/*DTA_CenterBottomOffset, 1,*/ TAG_DONE);
x+=zerowidth;
}
}
@ -193,37 +200,35 @@ static void DrawHudNumber(FFont *font, int color, int num, int x, int y, int tra
//
//===========================================================================
static void DrawStatLine(int x, int &y, const char *prefix, const char *string)
{
y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, prefix,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
screen->DrawText(SmallFont, hudcolor_stats, x+statspace, y, string,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
}
static void DrawStatus(player_t * CPlayer, int x, int y)
{
char tempstr[50];
int space;
if (hud_showscore)
{
mysnprintf(tempstr, countof(tempstr), "%i ", CPlayer->mo->Score);
DrawStatLine(x, y, "Sc:", tempstr);
}
if (hud_showstats)
{
space = SmallFont->StringWidth("Ac: ");
y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, "Ac:",
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
mysnprintf(tempstr, countof(tempstr), "%i ", CPlayer->accuracy);
screen->DrawText(SmallFont, hudcolor_stats, x+space, y, tempstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
y-=SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, "St:",
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
DrawStatLine(x, y, "Ac:", tempstr);
mysnprintf(tempstr, countof(tempstr), "%i ", CPlayer->stamina);
screen->DrawText(SmallFont, hudcolor_stats, x+space, y, tempstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
DrawStatLine(x, y, "St:", tempstr);
}
else
space=SmallFont->StringWidth("K: ");
if (!deathmatch)
{
@ -231,41 +236,20 @@ static void DrawStatus(player_t * CPlayer, int x, int y)
// work in cooperative hub games
if (hud_showsecrets)
{
y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, "S:",
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->secretcount : level.found_secrets, level.total_secrets);
screen->DrawText(SmallFont, hudcolor_stats, x+space, y, tempstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
DrawStatLine(x, y, "S:", tempstr);
}
if (hud_showitems)
{
y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, "I:",
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->itemcount : level.found_items, level.total_items);
screen->DrawText(SmallFont, hudcolor_stats, x+space, y, tempstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
DrawStatLine(x, y, "I:", tempstr);
}
if (hud_showmonsters)
{
y -= SmallFont->GetHeight()-1;
screen->DrawText(SmallFont, hudcolor_statnames, x, y, "K:",
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
mysnprintf(tempstr, countof(tempstr), "%i/%i ", multiplayer? CPlayer->killcount : level.killed_monsters, level.total_monsters);
screen->DrawText(SmallFont, hudcolor_stats, x+space, y, tempstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0xc000, TAG_DONE);
DrawStatLine(x, y, "K:", tempstr);
}
}
}
@ -926,6 +910,10 @@ void HUD_InitHud()
KeyTypes.Clear();
UnassignedKeyTypes.Clear();
statspace = SmallFont->StringWidth("Ac:");
// Now read custom icon overrides
int lump, lastlump = 0;

View file

@ -40,6 +40,7 @@
#include "gi.h"
#include "templates.h"
#include "v_font.h"
#include "m_fixed.h"
TArray<FSkillInfo> AllSkills;
int DefaultSkill = -1;

View file

@ -1,35 +0,0 @@
/*
#include "actor.h"
#include "m_random.h"
#include "a_action.h"
#include "p_local.h"
#include "s_sound.h"
#include "a_strifeglobal.h"
*/
// Macil (version 2) ---------------------------------------------------------
class AMacil1 : public AActor
{
DECLARE_CLASS (AMacil1, AActor)
public:
int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
};
IMPLEMENT_CLASS (AMacil1)
//============================================================================
//
// AMacil2 :: TakeSpecialDamage
//
// Macil is invulnerable to the first stage Sigil.
//
//============================================================================
int AMacil1::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype)
{
if (inflictor != NULL && inflictor->GetClass()->TypeName == NAME_SpectralLightningV1)
return -1;
return Super::TakeSpecialDamage(inflictor, source, damage, damagetype);
}

View file

@ -7,16 +7,6 @@
#include "thingdef/thingdef.h"
*/
class AOracle : public AActor
{
DECLARE_CLASS (AOracle, AActor)
public:
int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
};
IMPLEMENT_CLASS (AOracle)
DEFINE_ACTION_FUNCTION(AActor, A_WakeOracleSpectre)
{
@ -34,18 +24,3 @@ DEFINE_ACTION_FUNCTION(AActor, A_WakeOracleSpectre)
return 0;
}
//============================================================================
//
// AOracle :: TakeSpecialDamage
//
// The Oracle is invulnerable to the first stage Sigil.
//
//============================================================================
int AOracle::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype)
{
if (inflictor != NULL && inflictor->GetClass()->TypeName == NAME_SpectralLightningV1)
return -1;
return Super::TakeSpecialDamage(inflictor, source, damage, damagetype);
}

View file

@ -100,8 +100,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
}
if (owner != NULL)
{
// Rebels are the same color as their owner
rebel->Translation = owner->Translation;
// Rebels are the same color as their owner (but only in multiplayer)
if (multiplayer)
{
rebel->Translation = owner->Translation;
}
rebel->FriendPlayer = owner->player != NULL ? BYTE(owner->player - players + 1) : 0;
// Set the rebel's target to whatever last hurt the player, so long as it's not
// one of the player's other rebels.

View file

@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning)
x = self->x + pr_zap5.Random2(3) * FRACUNIT * 50;
y = self->y + pr_zap5.Random2(3) * FRACUNIT * 50;
flash = Spawn (self->threshold > 25 ? PClass::FindClass("SpectralLightningV2") :
PClass::FindClass("SpectralLightningV1"), x, y, ONCEILINGZ, ALLOW_REPLACE);
flash = Spawn (self->threshold > 25 ? PClass::FindClass(NAME_SpectralLightningV2) :
PClass::FindClass(NAME_SpectralLightningV1), x, y, ONCEILINGZ, ALLOW_REPLACE);
flash->target = self->target;
flash->velz = -18*FRACUNIT;
flash->health = self->health;
flash = Spawn("SpectralLightningV2", self->x, self->y, ONCEILINGZ, ALLOW_REPLACE);
flash = Spawn(NAME_SpectralLightningV2, self->x, self->y, ONCEILINGZ, ALLOW_REPLACE);
flash->target = self->target;
flash->velz = -18*FRACUNIT;

View file

@ -21,19 +21,19 @@
// Include all the other Strife stuff here to reduce compile time
#include "a_acolyte.cpp"
#include "a_spectral.cpp"
#include "a_alienspectres.cpp"
#include "a_coin.cpp"
#include "a_crusader.cpp"
#include "a_entityboss.cpp"
#include "a_inquisitor.cpp"
#include "a_loremaster.cpp"
#include "a_macil.cpp"
//#include "a_macil.cpp"
#include "a_oracle.cpp"
#include "a_programmer.cpp"
#include "a_reaver.cpp"
#include "a_rebels.cpp"
#include "a_sentinel.cpp"
#include "a_spectral.cpp"
#include "a_stalker.cpp"
#include "a_strifeitems.cpp"
#include "a_strifeweapons.cpp"

View file

@ -459,7 +459,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler1)
// it should use a different puff. ZDoom's default range is longer
// than this, so let's not handicap it by being too faithful to the
// original.
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Disintegrate, NAME_MaulerPuff);
P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_None, NAME_MaulerPuff);
}
return 0;
}

View file

@ -32,7 +32,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_TemplarAttack)
damage = (pr_templar() & 4) * 2;
angle = self->angle + (pr_templar.Random2() << 19);
pitchdiff = pr_templar.Random2() * 332063;
P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_Disintegrate, NAME_MaulerPuff);
P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_None, NAME_MaulerPuff);
}
return 0;
}

View file

@ -86,10 +86,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode512)
{
self->target->player->extralight = 5;
}
if (self->z <= self->floorz + (512<<FRACBITS))
{
P_HitFloor (self);
}
P_CheckSplash(self, 512<<FRACBITS);
// Strife didn't do this next part, but it looks good
self->RenderStyle = STYLE_Add;

View file

@ -161,6 +161,8 @@ FGameConfigFile::FGameConfigFile ()
// Create auto-load sections, so users know what's available.
// Note that this totem pole is the reverse of the order that
// they will appear in the file.
CreateSectionAtStart("Harmony.Autoload");
CreateSectionAtStart("UrbanBrawl.Autoload");
CreateSectionAtStart("Chex3.Autoload");
CreateSectionAtStart("Chex.Autoload");
CreateSectionAtStart("Strife.Autoload");
@ -269,8 +271,8 @@ void FGameConfigFile::DoGlobalSetup ()
SetValueForKey ("9", "use ArtiBlastRadius");
SetValueForKey ("8", "use ArtiTeleport");
SetValueForKey ("7", "use ArtiTeleportOther");
SetValueForKey ("6", "use ArtiEgg");
SetValueForKey ("5", "use ArtiInvulnerability");
SetValueForKey ("6", "use ArtiPork");
SetValueForKey ("5", "use ArtiInvulnerability2");
}
}
if (last < 204)
@ -328,6 +330,15 @@ void FGameConfigFile::DoGlobalSetup ()
dim->ResetToDefault ();
}
}
if (last < 210)
{
if (SetSection ("Hexen.Bindings"))
{
// These 2 were misnamed in earlier versions
SetValueForKey ("6", "use ArtiPork");
SetValueForKey ("5", "use ArtiInvulnerability2");
}
}
}
}
}

View file

@ -29,7 +29,7 @@
#define alloca __builtin_alloca
#endif
inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
static inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
{
SDWORD result, dummy;
@ -47,7 +47,7 @@ inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
return result;
}
inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
static inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
{
SDWORD result, dummy;
@ -65,7 +65,7 @@ inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
}
#define MAKECONSTMulScale(s) \
inline SDWORD MulScale##s (SDWORD a, SDWORD b) { return ((SQWORD)a * b) >> s; }
static inline SDWORD MulScale##s (SDWORD a, SDWORD b) { return ((SQWORD)a * b) >> s; }
MAKECONSTMulScale(1)
MAKECONSTMulScale(2)
@ -101,8 +101,10 @@ MAKECONSTMulScale(31)
MAKECONSTMulScale(32)
#undef MAKECONSTMulScale
static inline DWORD UMulScale16(DWORD a, DWORD b) { return ((QWORD)a * b) >> 16; }
#define MAKECONSTDMulScale(s) \
inline SDWORD DMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d) \
static inline SDWORD DMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d) \
{ \
return (((SQWORD)a * b) + ((SQWORD)c * d)) >> s; \
}
@ -142,7 +144,7 @@ MAKECONSTDMulScale(32)
#undef MAKECONSTDMulScale
#define MAKECONSTTMulScale(s) \
inline SDWORD TMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD ee) \
static inline SDWORD TMulScale##s (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD e, SDWORD ee) \
{ \
return (((SQWORD)a * b) + ((SQWORD)c * d) + ((SQWORD)e * ee)) >> s; \
}
@ -181,7 +183,7 @@ MAKECONSTTMulScale(31)
MAKECONSTTMulScale(32)
#undef MAKECONSTTMulScale
inline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
static inline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
{
union {
long long big;
@ -195,7 +197,7 @@ inline SDWORD BoundMulScale (SDWORD a, SDWORD b, SDWORD c)
return u.l;
}
inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
{
SDWORD result, dummy;
SDWORD lo = a << c;
@ -212,7 +214,7 @@ inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
return result;
}
inline SDWORD DivScale1 (SDWORD a, SDWORD b)
static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
{
SDWORD result, dummy;
@ -229,7 +231,7 @@ inline SDWORD DivScale1 (SDWORD a, SDWORD b)
}
#define MAKECONSTDivScale(s) \
inline SDWORD DivScale##s (SDWORD a, SDWORD b) \
static inline SDWORD DivScale##s (SDWORD a, SDWORD b) \
{ \
SDWORD result, dummy; \
asm volatile \
@ -275,7 +277,7 @@ MAKECONSTDivScale(30)
MAKECONSTDivScale(31)
#undef MAKECONSTDivScale
inline SDWORD DivScale32 (SDWORD a, SDWORD b)
static inline SDWORD DivScale32 (SDWORD a, SDWORD b)
{
SDWORD result, dummy;
@ -290,7 +292,7 @@ inline SDWORD DivScale32 (SDWORD a, SDWORD b)
return result;
}
inline void clearbuf (void *buff, int count, SDWORD clear)
static inline void clearbuf (void *buff, int count, SDWORD clear)
{
int dummy1, dummy2;
asm volatile
@ -303,7 +305,7 @@ inline void clearbuf (void *buff, int count, SDWORD clear)
);
}
inline void clearbufshort (void *buff, unsigned int count, WORD clear)
static inline void clearbufshort (void *buff, unsigned int count, WORD clear)
{
asm volatile
("shr $1,%%ecx\n\t"
@ -315,7 +317,7 @@ inline void clearbufshort (void *buff, unsigned int count, WORD clear)
:"%cc");
}
inline SDWORD ksgn (SDWORD a)
static inline SDWORD ksgn (SDWORD a)
{
SDWORD result, dummy;
@ -329,27 +331,3 @@ inline SDWORD ksgn (SDWORD a)
:"%cc");
return result;
}
inline int toint (float v)
{
volatile QWORD result;
asm volatile
("fistpq %0"
:"=m" (result)
:"t" (v)
:"%st");
return result;
}
inline int quickertoint (float v)
{
volatile int result;
asm volatile
("fistpl %0"
:"=m" (result)
:"t" (v)
:"%st");
return result;
}

View file

@ -281,6 +281,7 @@ void FMapInfoParser::ParseGameInfo()
GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime")
GAMEINFOKEY_INT(defaultdropstyle, "defaultdropstyle")
GAMEINFOKEY_CSTRING(Endoom, "endoom", 8)
GAMEINFOKEY_INT(player5start, "player5start")
else
{
// ignore unkown keys.

View file

@ -42,6 +42,7 @@
#define GI_SHAREWARE 0x00000002
#define GI_MENUHACK_EXTENDED 0x00000004 // (Heretic)
#define GI_TEASER2 0x00000008 // Alternate version of the Strife Teaser
#define GI_COMPATSHORTTEX 0x00000010 // always force COMPAT_SHORTTEX for IWAD maps.
#include "gametype.h"
@ -103,6 +104,7 @@ struct gameinfo_t
int definventorymaxamount;
int defaultrespawntime;
int defaultdropstyle;
int player5start;
const char *GetFinalePage(unsigned int num) const;
};

View file

@ -46,6 +46,9 @@
# include <unistd.h>
# include <netdb.h>
# include <sys/ioctl.h>
# ifdef __sun
# include <fcntl.h>
# endif
#endif
#include "doomtype.h"
@ -422,7 +425,11 @@ void StartNetwork (bool autoPort)
// create communication socket
mysocket = UDPsocket ();
BindToLocalPort (mysocket, autoPort ? 0 : DOOMPORT);
#ifndef __sun
ioctlsocket (mysocket, FIONBIO, &trueval);
#else
fcntl(mysocket, F_SETFL, trueval | O_NONBLOCK);
#endif
}
void SendAbort (void)

View file

@ -39,6 +39,8 @@
#include "m_fixed.h"
#include "c_dispatch.h"
#include "d_net.h"
#include "v_text.h"
#include "gi.h"
#include "vm.h"
#include "actor.h"
@ -156,15 +158,26 @@ void FActorInfo::StaticSetActorNums ()
void FActorInfo::RegisterIDs ()
{
const PClass *cls = PClass::FindClass(Class->TypeName);
bool set = false;
if (GameFilter == GAME_Any || (GameFilter & gameinfo.gametype))
{
if (SpawnID != 0)
{
SpawnableThings[SpawnID] = Class;
SpawnableThings[SpawnID] = cls;
if (cls != Class)
{
Printf(TEXTCOLOR_RED"Spawn ID %d refers to hidden class type '%s'\n", SpawnID, cls->TypeName.GetChars());
}
}
if (DoomEdNum != -1)
{
DoomEdMap.AddType (DoomEdNum, Class);
DoomEdMap.AddType (DoomEdNum, cls);
if (cls != Class)
{
Printf(TEXTCOLOR_RED"Editor number %d refers to hidden class type '%s'\n", DoomEdNum, cls->TypeName.GetChars());
}
}
}
// Fill out the list for Chex Quest with Doom's actors
@ -172,6 +185,10 @@ void FActorInfo::RegisterIDs ()
(GameFilter & GAME_Doom))
{
DoomEdMap.AddType (DoomEdNum, Class, true);
if (cls != Class)
{
Printf(TEXTCOLOR_RED"Editor number %d refers to hidden class type '%s'\n", DoomEdNum, cls->TypeName.GetChars());
}
}
}
@ -182,17 +199,22 @@ void FActorInfo::RegisterIDs ()
FActorInfo *FActorInfo::GetReplacement (bool lookskill)
{
FName skillrepname = AllSkills[gameskill].GetReplacement(this->Class->TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
FName skillrepname;
if (lookskill && AllSkills.Size() > (unsigned)gameskill)
{
Printf("Warning: incorrect actor name in definition of skill %s: \n\
class %s is replaced by inexistent class %s\n\
Skill replacement will be ignored for this actor.\n",
AllSkills[gameskill].Name.GetChars(),
this->Class->TypeName.GetChars(), skillrepname.GetChars());
AllSkills[gameskill].SetReplacement(this->Class->TypeName, NAME_None);
AllSkills[gameskill].SetReplacedBy(skillrepname, NAME_None);
lookskill = false; skillrepname = NAME_None;
skillrepname = AllSkills[gameskill].GetReplacement(this->Class->TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
{
Printf("Warning: incorrect actor name in definition of skill %s: \n"
"class %s is replaced by non-existent class %s\n"
"Skill replacement will be ignored for this actor.\n",
AllSkills[gameskill].Name.GetChars(),
this->Class->TypeName.GetChars(), skillrepname.GetChars());
AllSkills[gameskill].SetReplacement(this->Class->TypeName, NAME_None);
AllSkills[gameskill].SetReplacedBy(skillrepname, NAME_None);
lookskill = false; skillrepname = NAME_None;
}
}
if (Replacement == NULL && (!lookskill || skillrepname == NAME_None))
{
@ -225,17 +247,22 @@ FActorInfo *FActorInfo::GetReplacement (bool lookskill)
FActorInfo *FActorInfo::GetReplacee (bool lookskill)
{
FName skillrepname = AllSkills[gameskill].GetReplacedBy(this->Class->TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
FName skillrepname;
if (lookskill && AllSkills.Size() > (unsigned)gameskill)
{
Printf("Warning: incorrect actor name in definition of skill %s: \
inexistent class %s is replaced by class %s\n\
Skill replacement will be ignored for this actor.\n",
AllSkills[gameskill].Name.GetChars(),
skillrepname.GetChars(), this->Class->TypeName.GetChars());
AllSkills[gameskill].SetReplacedBy(this->Class->TypeName, NAME_None);
AllSkills[gameskill].SetReplacement(skillrepname, NAME_None);
lookskill = false;
skillrepname = AllSkills[gameskill].GetReplacedBy(this->Class->TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
{
Printf("Warning: incorrect actor name in definition of skill %s: \n"
"non-existent class %s is replaced by class %s\n"
"Skill replacement will be ignored for this actor.\n",
AllSkills[gameskill].Name.GetChars(),
skillrepname.GetChars(), this->Class->TypeName.GetChars());
AllSkills[gameskill].SetReplacedBy(this->Class->TypeName, NAME_None);
AllSkills[gameskill].SetReplacement(skillrepname, NAME_None);
lookskill = false;
}
}
if (Replacee == NULL && (!lookskill || skillrepname == NAME_None))
{

View file

@ -60,6 +60,7 @@ struct FState
long Misc2; // Was changed to BYTE, reverted to long for MBF compat
BYTE Frame;
BYTE DefineFlags; // Unused byte so let's use it during state creation.
short Light;
FState *NextState;
VMFunction *ActionFunc;
@ -188,6 +189,7 @@ extern FDoomEdMap DoomEdMap;
int GetSpriteIndex(const char * spritename);
TArray<FName> &MakeStateNameList(const char * fname);
void AddStateLight(FState *state, const char *lname);
// Standard parameters for all action functons
// self - Actor this action is to operate on (player if a weapon)

View file

@ -52,11 +52,14 @@
#endif
#if defined(__APPLE__)
#define _msize(p) malloc_size(p)
#elif defined(__sun)
#define _msize(p) (*((size_t*)(p)-1))
#elif !defined(_WIN32)
#define _msize(p) malloc_usable_size(p) // from glibc/FreeBSD
#endif
#ifndef _DEBUG
#if !defined(__sun)
void *M_Malloc(size_t size)
{
void *block = malloc(size);
@ -83,10 +86,50 @@ void *M_Realloc(void *memblock, size_t size)
return block;
}
#else
void *M_Malloc(size_t size)
{
void *block = malloc(size+sizeof(size_t));
if (block == NULL)
I_FatalError("Could not malloc %zu bytes", size);
size_t *sizeStore = (size_t *) block;
*sizeStore = size;
block = sizeStore+1;
GC::AllocBytes += _msize(block);
return block;
}
void *M_Realloc(void *memblock, size_t size)
{
if(memblock == NULL)
return M_Malloc(size);
if (memblock != NULL)
{
GC::AllocBytes -= _msize(memblock);
}
void *block = realloc(((size_t*) memblock)-1, size+sizeof(size_t));
if (block == NULL)
{
I_FatalError("Could not realloc %zu bytes", size);
}
size_t *sizeStore = (size_t *) block;
*sizeStore = size;
block = sizeStore+1;
GC::AllocBytes += _msize(block);
return block;
}
#endif
#else
#ifdef _MSC_VER
#include <crtdbg.h>
#endif
#if !defined(__sun)
void *M_Malloc_Dbg(size_t size, const char *file, int lineno)
{
void *block = _malloc_dbg(size, _NORMAL_BLOCK, file, lineno);
@ -112,8 +155,49 @@ void *M_Realloc_Dbg(void *memblock, size_t size, const char *file, int lineno)
GC::AllocBytes += _msize(block);
return block;
}
#else
void *M_Malloc_Dbg(size_t size, const char *file, int lineno)
{
void *block = _malloc_dbg(size+sizeof(size_t), _NORMAL_BLOCK, file, lineno);
if (block == NULL)
I_FatalError("Could not malloc %zu bytes", size);
size_t *sizeStore = (size_t *) block;
*sizeStore = size;
block = sizeStore+1;
GC::AllocBytes += _msize(block);
return block;
}
void *M_Realloc_Dbg(void *memblock, size_t size, const char *file, int lineno)
{
if(memblock == NULL)
return M_Malloc_Dbg(size, file, lineno);
if (memblock != NULL)
{
GC::AllocBytes -= _msize(memblock);
}
void *block = _realloc_dbg(((size_t*) memblock)-1, size+sizeof(size_t), _NORMAL_BLOCK, file, lineno);
if (block == NULL)
{
I_FatalError("Could not realloc %zu bytes", size);
}
size_t *sizeStore = (size_t *) block;
*sizeStore = size;
block = sizeStore+1;
GC::AllocBytes += _msize(block);
return block;
}
#endif
#endif
#if !defined(__sun)
void M_Free (void *block)
{
if (block != NULL)
@ -122,3 +206,14 @@ void M_Free (void *block)
free(block);
}
}
#else
void M_Free (void *block)
{
if(block != NULL)
{
GC::AllocBytes -= _msize(block);
free(((size_t*) block)-1);
}
}
#endif

View file

@ -631,10 +631,14 @@ void cht_Give (player_t *player, const char *name, int amount)
}
else
{
if (player->mo)
player->mo->health = deh.GodHealth;
player->health = deh.GodHealth;
if (player->mo != NULL)
{
player->health = player->mo->health = player->mo->GetMaxHealth();
}
else
{
player->health = deh.GodHealth;
}
}
if (!giveall)

View file

@ -20,6 +20,8 @@
#include "basicinlines.h"
#endif
#include "xs_Float.h"
#define MAKESAFEDIVSCALE(x) \
inline SDWORD SafeDivScale##x (SDWORD a, SDWORD b) \
{ \
@ -134,4 +136,8 @@ inline SDWORD ModDiv (SDWORD num, SDWORD den, SDWORD *dmval)
return num % den;
}
#define FLOAT2FIXED(f) xs_Fix<16>::ToFix(f)
#define FIXED2FLOAT(f) ((f) / float(65536))
#endif

View file

@ -82,6 +82,9 @@
#define KEY_REPEAT_DELAY (TICRATE*5/12)
#define KEY_REPEAT_RATE (3)
#define INPUTGRID_WIDTH 13
#define INPUTGRID_HEIGHT 5
// TYPES -------------------------------------------------------------------
struct FSaveGameNode : public Node
@ -171,6 +174,8 @@ static void M_DrawFiles ();
void M_DrawFrame (int x, int y, int width, int height);
static void M_DrawSaveLoadBorder (int x,int y, int len);
static void M_DrawSaveLoadCommon ();
static void M_DrawInputGrid();
static void M_SetupNextMenu (oldmenu_t *menudef);
static void M_StartMessage (const char *string, void(*routine)(int));
static void M_EndMessage (int key);
@ -235,6 +240,7 @@ static int saveSlot; // which slot to save in
static size_t saveCharIndex; // which char we're editing
static int LINEHEIGHT;
static const int PLAYERSETUP_LINEHEIGHT = 16;
static char savegamestring[SAVESTRINGSIZE];
static FString EndString;
@ -275,6 +281,18 @@ static int epi; // Selected episode
static const char *saved_playerclass = NULL;
// Heretic and Hexen do not, by default, come with glyphs for all of these
// characters. Oh well. Doom and Strife do.
static const char InputGridChars[INPUTGRID_WIDTH * INPUTGRID_HEIGHT] =
"ABCDEFGHIJKLM"
"NOPQRSTUVWXYZ"
"0123456789+-="
".,!?@'\":;[]()"
"<>^#$%&*/_ \b";
static int InputGridX = INPUTGRID_WIDTH - 1;
static int InputGridY = INPUTGRID_HEIGHT - 1;
static bool InputGridOkay; // Last input was with a controller.
// PRIVATE MENU DEFINITIONS ------------------------------------------------
//
@ -2120,8 +2138,29 @@ static void M_PlayerSetupTicker (void)
}
}
static void M_DrawPlayerSlider (int x, int y, int cur)
{
const int range = 255;
x = (x - 160) * CleanXfac + screen->GetWidth() / 2;
y = (y - 100) * CleanYfac + screen->GetHeight() / 2;
screen->DrawText (ConFont, CR_WHITE, x, y,
"\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
screen->DrawText (ConFont, CR_ORANGE, x + (5 + (int)((cur * 78) / range)) * CleanXfac, y,
"\x13",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
}
static void M_PlayerSetupDrawer ()
{
const int LINEHEIGHT = PLAYERSETUP_LINEHEIGHT;
int x, xo, yo;
EColorRange label, value;
DWORD color;
@ -2251,9 +2290,9 @@ static void M_PlayerSetupDrawer ()
x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x;
color = players[consoleplayer].userinfo.color;
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, 0.0f, 255.0f, float(RPART(color)), -1);
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, 0.0f, 255.0f, float(GPART(color)), -1);
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, 0.0f, 255.0f, float(BPART(color)), -1);
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color));
// [GRB] Draw class setting
int pclass = players[consoleplayer].userinfo.PlayerClass;
@ -2851,14 +2890,6 @@ bool M_Responder (event_t *ev)
// This code previously listened for EV_GUI_KeyRepeat to handle repeating
// in the menus, but that doesn't work with gamepads, so now we combine
// the multiple inputs into buttons and handle the repetition manually.
//
// FIXME: genStringEnter and messageToPrint do not play well with game
// controllers. In fact, you can still interact with the rest of
// the menu using a controller while the menu waits for input. Especially
// bad if you, say, select quit from the main menu. (Ideally,
// genStringEnter will pop up a keypad if it detects a controller is
// being used to navigate the menu. At the very least, it should
// disable the controller.)
if (ev->type == EV_GUI_Event)
{
// Save game and player name string input
@ -2866,8 +2897,9 @@ bool M_Responder (event_t *ev)
{
if (ev->subtype == EV_GUI_Char)
{
InputGridOkay = false;
if (saveCharIndex < genStringLen &&
(genStringEnter == 2 || (size_t)SmallFont->StringWidth(savegamestring) < (genStringLen-1)*8))
(genStringEnter == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(savegamestring) < (genStringLen-1)*8))
{
savegamestring[saveCharIndex] = (char)ev->data1;
savegamestring[++saveCharIndex] = 0;
@ -2875,8 +2907,7 @@ bool M_Responder (event_t *ev)
return true;
}
ch = ev->data1;
if ((ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) &&
ch == '\b')
if ((ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) && ch == '\b')
{
if (saveCharIndex > 0)
{
@ -2944,48 +2975,68 @@ bool M_Responder (event_t *ev)
{
mkey = MKEY_Clear;
}
else if (!keyup && !OptionsActive)
else if (!keyup)
{
ch = tolower (ch);
if (messageToPrint)
if (OptionsActive)
{
// Take care of any messages that need input
ch = tolower (ch);
assert(messageRoutine != NULL);
if (ch != ' ' && ch != 'n' && ch != 'y')
{
return false;
}
D_RemoveNextCharEvent();
M_EndMessage(ch);
return true;
M_OptResponder(ev);
}
else
{
// Search for a menu item associated with the pressed key.
for (i = (itemOn + 1) % currentMenu->numitems;
i != itemOn;
i = (i + 1) % currentMenu->numitems)
ch = tolower (ch);
if (messageToPrint)
{
// Take care of any messages that need input
ch = tolower (ch);
assert(messageRoutine != NULL);
if (ch != ' ' && ch != 'n' && ch != 'y')
{
return false;
}
D_RemoveNextCharEvent();
M_EndMessage(ch);
return true;
}
else
{
// Search for a menu item associated with the pressed key.
for (i = (itemOn + 1) % currentMenu->numitems;
i != itemOn;
i = (i + 1) % currentMenu->numitems)
{
if (currentMenu->menuitems[i].alphaKey == ch)
{
break;
}
}
if (currentMenu->menuitems[i].alphaKey == ch)
{
break;
itemOn = i;
S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
return true;
}
}
if (currentMenu->menuitems[i].alphaKey == ch)
{
itemOn = i;
S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", 1, ATTN_NONE);
return true;
}
}
}
break;
}
if (!keyup)
{
InputGridOkay = false;
}
}
else if (ev->type == EV_KeyDown || ev->type == EV_KeyUp)
{
keyup = ev->type == EV_KeyUp;
// If this is a button down, it's okay to show the input grid if the
// next action causes us to enter genStringEnter mode. If we are
// already in that mode, then we let M_ButtonHandler() turn it on so
// that it will know if a button press happened while the input grid
// was turned off.
if (!keyup && !genStringEnter)
{
InputGridOkay = true;
}
ch = ev->data1;
switch (ch)
{
@ -3116,6 +3167,74 @@ void M_ButtonHandler(EMenuKey key, bool repeat)
}
return;
}
if (genStringEnter)
{
int ch;
switch (key)
{
case MKEY_Down:
InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT;
break;
case MKEY_Up:
InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT;
break;
case MKEY_Right:
InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH;
break;
case MKEY_Left:
InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH;
break;
case MKEY_Clear:
if (saveCharIndex > 0)
{
savegamestring[--saveCharIndex] = 0;
}
break;
case MKEY_Enter:
assert(unsigned(InputGridX) < INPUTGRID_WIDTH && unsigned(InputGridY) < INPUTGRID_HEIGHT);
if (InputGridOkay)
{
ch = InputGridChars[InputGridX + InputGridY * INPUTGRID_WIDTH];
if (ch == 0) // end
{
if (savegamestring[0] != '\0')
{
genStringEnter = 0;
if (messageToPrint)
{
M_ClearMenus();
}
genStringEnd(SelSaveGame);
}
}
else if (ch == '\b') // bs
{
if (saveCharIndex > 0)
{
savegamestring[--saveCharIndex] = 0;
}
}
else if (saveCharIndex < genStringLen &&
(genStringEnter == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(savegamestring) < (genStringLen-1)*8))
{
savegamestring[saveCharIndex] = ch;
savegamestring[++saveCharIndex] = 0;
}
}
break;
default:
break; // Keep GCC quiet
}
InputGridOkay = true;
return;
}
if (currentMenu == &SaveDef || currentMenu == &LoadDef)
{
M_SaveLoadButtonHandler(key);
@ -3330,6 +3449,12 @@ static void M_SaveSelect (const FSaveGameNode *file)
}
else
{
// If we are naming a new save, don't start the cursor on "end".
if (InputGridX == INPUTGRID_WIDTH - 1 && InputGridY == INPUTGRID_HEIGHT - 1)
{
InputGridX = 0;
InputGridY = 0;
}
savegamestring[0] = 0;
}
saveCharIndex = strlen (savegamestring);
@ -3443,7 +3568,13 @@ void M_Drawer ()
screen->DrawText(SmallFont, CR_UNTRANSLATED, 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE);
if (skullAnimCounter < 6)
{
M_DrawConText(CR_RED, 150, y + (fontheight + 1) * messageSelection, "\xd");
screen->DrawText(ConFont, CR_RED,
(150 - 160) * CleanXfac + screen->GetWidth() / 2,
(y + (fontheight + 1) * messageSelection - 100) * CleanYfac + screen->GetHeight() / 2,
"\xd",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
}
}
}
@ -3516,7 +3647,7 @@ void M_Drawer ()
if (skullAnimCounter < 6)
{
screen->DrawText (ConFont, CR_RED, x - 16,
currentMenu->y + itemOn*LINEHEIGHT +
currentMenu->y + itemOn*PLAYERSETUP_LINEHEIGHT +
(!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd",
DTA_Clean, true, TAG_DONE);
}
@ -3542,6 +3673,10 @@ void M_Drawer ()
}
}
}
if (genStringEnter && InputGridOkay)
{
M_DrawInputGrid();
}
}
}
@ -3567,6 +3702,77 @@ static void M_ClearSaveStuff ()
}
}
static void M_DrawInputGrid()
{
const int cell_width = 18 * CleanXfac;
const int cell_height = 12 * CleanYfac;
const int top_padding = cell_height / 2 - SmallFont->GetHeight() * CleanYfac / 2;
// Darken the background behind the character grid.
// Unless we frame it with a border, I think it looks better to extend the
// background across the full width of the screen.
screen->Dim(0, 0.8f,
0 /*screen->GetWidth()/2 - 13 * cell_width / 2*/,
screen->GetHeight() - 5 * cell_height,
screen->GetWidth() /*13 * cell_width*/,
5 * cell_height);
// Highlight the background behind the selected character.
screen->Dim(MAKERGB(255,248,220), 0.6f,
InputGridX * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2,
InputGridY * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight(),
cell_width, cell_height);
for (int y = 0; y < INPUTGRID_HEIGHT; ++y)
{
const int yy = y * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight();
for (int x = 0; x < INPUTGRID_WIDTH; ++x)
{
int width;
const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2;
const int ch = InputGridChars[y * INPUTGRID_WIDTH + x];
FTexture *pic = SmallFont->GetChar(ch, &width);
EColorRange color;
FRemapTable *remap;
// The highlighted character is yellow; the rest are dark gray.
color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY;
remap = SmallFont->GetColorTranslation(color);
if (pic != NULL)
{
// Draw a normal character.
screen->DrawTexture(pic, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding,
DTA_Translation, remap,
DTA_CleanNoMove, true,
TAG_DONE);
}
else if (ch == ' ')
{
// Draw the space as a box outline. We also draw it 50% wider than it really is.
const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4;
const int x2 = x1 + width * 3 * CleanXfac / 2;
const int y1 = yy + top_padding;
const int y2 = y1 + SmallFont->GetHeight() * CleanYfac;
const int palentry = remap->Remap[remap->NumEntries*2/3];
const uint32 palcolor = remap->Palette[remap->NumEntries*2/3];
screen->Clear(x1, y1, x2, y1+CleanYfac, palentry, palcolor); // top
screen->Clear(x1, y2, x2, y2+CleanYfac, palentry, palcolor); // bottom
screen->Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palentry, palcolor); // left
screen->Clear(x2-CleanXfac, y1+CleanYfac, x2, y2, palentry, palcolor); // right
}
else if (ch == '\b' || ch == 0)
{
// Draw the backspace and end "characters".
const char *const str = ch == '\b' ? "BS" : "ED";
screen->DrawText(SmallFont, color,
xx + cell_width/2 - SmallFont->StringWidth(str)*CleanXfac/2,
yy + top_padding, str, DTA_CleanNoMove, true, TAG_DONE);
}
}
}
}
//
// M_ClearMenus
//

View file

@ -84,9 +84,6 @@ void M_DeactivateMenuInput ();
void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
// Draw a slider. Set fracdigits negative to not display the current value numerically.
void M_DrawSlider (int x, int y, double min, double max, double cur, int fracdigits=1);
//
// MENU TYPEDEFS
//
@ -181,7 +178,7 @@ struct menu_t {
int scrolltop;
int scrollpos;
int y;
void (*PreDraw)(void);
bool (*PreDraw)(void);
bool DontDim;
void (*EscapeHandler)(void);
};
@ -267,6 +264,7 @@ extern menustack_t MenuStack[16];
extern int MenuStackDepth;
extern bool OptionsActive;
extern int skullAnimCounter;
extern menu_t *CurrentMenu;
extern int CurrentItem;

View file

@ -94,6 +94,7 @@ EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, compatmode)
EXTERN_CVAR (Bool, vid_vsync)
EXTERN_CVAR(Bool, displaynametags)
EXTERN_CVAR (Int, snd_channels)
//
// defaulted values
@ -106,8 +107,6 @@ CVAR (Bool, show_obituaries, true, CVAR_ARCHIVE)
EXTERN_CVAR (Bool, longsavemessages)
EXTERN_CVAR (Bool, screenshot_quiet)
extern int skullAnimCounter;
EXTERN_CVAR (Bool, cl_run)
EXTERN_CVAR (Int, crosshair)
EXTERN_CVAR (Bool, freelook)
@ -346,7 +345,7 @@ menu_t JoystickConfigMenu =
*
*=======================================*/
static menuitem_t ControlsItems[] =
menuitem_t ControlsItems[] =
{
{ redtext,"ENTER to change, BACKSPACE to clear", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
@ -610,6 +609,7 @@ EXTERN_CVAR (Color, am_ovtelecolor)
EXTERN_CVAR (Color, am_intralevelcolor)
EXTERN_CVAR (Color, am_interlevelcolor)
EXTERN_CVAR (Color, am_secretsectorcolor)
EXTERN_CVAR (Color, am_ovsecretsectorcolor)
EXTERN_CVAR (Color, am_thingcolor_friend)
EXTERN_CVAR (Color, am_thingcolor_monster)
EXTERN_CVAR (Color, am_thingcolor_item)
@ -645,6 +645,7 @@ static menuitem_t MapColorsItems[] = {
{ colorpicker, "2-sided walls (overlay)", {&am_ovotherwallscolor},{0}, {0}, {0}, {0} },
{ colorpicker, "Not-yet-seen walls (overlay)", {&am_ovunseencolor}, {0}, {0}, {0}, {0} },
{ colorpicker, "Teleporter (overlay)", {&am_ovtelecolor}, {0}, {0}, {0}, {0} },
{ colorpicker, "Secret sector (overlay)", {&am_ovsecretsectorcolor}, {0}, {0}, {0}, {0} },
{ colorpicker, "Actors (overlay) (for cheat)", {&am_ovthingcolor}, {0}, {0}, {0}, {0} },
{ colorpicker, "Monsters (overlay) (for cheat)", {&am_ovthingcolor_monster}, {0}, {0}, {0}, {0} },
{ colorpicker, "Friends (overlay) (for cheat)", {&am_ovthingcolor_friend}, {0}, {0}, {0}, {0} },
@ -1112,6 +1113,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "Monster movement is affected by effects", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MBFMONSTERMOVE} },
{ bitflag, "Crushed monsters can be resurrected", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_CORPSEGIBS} },
{ bitflag, "Friendly monsters aren't blocked", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOBLOCKFRIENDS} },
{ bitflag, "Invert sprite sorting", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SPRITESORT} },
{ discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} },
};
@ -1251,6 +1253,7 @@ static menuitem_t SoundItems[] =
{ discrete, "Underwater reverb", {&snd_waterreverb}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ slider, "Underwater cutoff", {&snd_waterlp}, {0.0}, {2000.0},{50.0}, {NULL} },
{ discrete, "Randomize pitches", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ slider, "Sound channels", {&snd_channels}, {8.0}, {256.0}, {8.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ more, "Restart sound", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
@ -1491,11 +1494,9 @@ void M_DrawConText (int color, int x, int y, const char *str)
{
int len = (int)strlen(str);
x = (x - 160) * CleanXfac + screen->GetWidth() / 2;
y = (y - 100) * CleanYfac + screen->GetHeight() / 2;
screen->DrawText (ConFont, color, x, y, str,
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
DTA_CellX, 8 * CleanXfac_1,
DTA_CellY, 8 * CleanYfac_1,
TAG_DONE);
}
@ -1555,21 +1556,22 @@ bool M_StartOptionsMenu (void)
return true;
}
void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits)
// Draw a slider. Set fracdigits negative to not display the current value numerically.
static void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits)
{
double range;
range = max - min;
cur = clamp(cur, min, max) - min;
double ccur = clamp(cur, min, max) - min;
M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
M_DrawConText(CR_ORANGE, x + 5 + (int)((cur * 78) / range), y, "\x13");
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), y, "\x13");
if (fracdigits >= 0)
{
char textbuf[16];
mysnprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur);
screen->DrawText(SmallFont, CR_DARKGRAY, x + 12*8 + 4, y, textbuf, DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, CR_DARKGRAY, x + (12*8 + 4) * CleanXfac_1, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -1640,6 +1642,7 @@ void M_OptDrawer ()
DWORD overlay;
int labelofs;
int indent;
int cursorspace;
if (!CurrentMenu->DontDim)
{
@ -1648,7 +1651,7 @@ void M_OptDrawer ()
if (CurrentMenu->PreDraw != NULL)
{
CurrentMenu->PreDraw ();
if (CurrentMenu->PreDraw ()) return;
}
if (CurrentMenu->y != 0)
@ -1660,9 +1663,9 @@ void M_OptDrawer ()
if (BigFont && CurrentMenu->texttitle)
{
screen->DrawText (BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-BigFont->StringWidth (CurrentMenu->texttitle)/2, 10,
CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE);
y = 15 + BigFont->GetHeight ();
(screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2, 10*CleanYfac_1,
CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE);
y = 15 + BigFont->GetHeight();
}
else
{
@ -1671,7 +1674,7 @@ void M_OptDrawer ()
}
if (gameinfo.gametype & GAME_Raven)
{
labelofs = 2;
labelofs = 2 * CleanXfac_1;
y -= 2;
fontheight = 9;
}
@ -1680,9 +1683,13 @@ void M_OptDrawer ()
labelofs = 0;
fontheight = 8;
}
ytop = y + CurrentMenu->scrolltop * 8;
cursorspace = 14 * CleanXfac_1;
y *= CleanYfac_1;
fontheight *= CleanYfac_1;
ytop = y + CurrentMenu->scrolltop * 8 * CleanYfac_1;
int lastrow = screen->GetHeight() - SmallFont->GetHeight() * CleanYfac_1;
for (i = 0; i < CurrentMenu->numitems && y <= 200 - SmallFont->GetHeight(); i++, y += fontheight)
for (i = 0; i < CurrentMenu->numitems && y <= lastrow; i++, y += fontheight)
{
if (i == CurrentMenu->scrolltop)
{
@ -1693,15 +1700,30 @@ void M_OptDrawer ()
overlay = 0;
if (item->type == discrete && item->c.discretecenter == 1)
{
indent = 160;
indent = screen->GetWidth() / 2;
}
else if (item->type == joymore)
{
indent = 4;
indent = 4 * CleanXfac_1;
}
else
{
indent = CurrentMenu->indent;
if (indent > 280)
{ // kludge for the compatibility options with their extremely long labels
if (indent + 40 <= CleanWidth_1)
{
indent = (screen->GetWidth() - ((indent + 40) * CleanXfac_1)) / 2 + indent * CleanXfac_1;
}
else
{
indent = screen->GetWidth() - 40 * CleanXfac_1;
}
}
else
{
indent = (indent - 160) * CleanXfac_1 + screen->GetWidth() / 2;
}
}
if (item->type != screenres)
@ -1724,7 +1746,7 @@ void M_OptDrawer ()
label = somestring;
}
}
width = SmallFont->StringWidth(label);
width = SmallFont->StringWidth(label) * CleanXfac_1;
switch (item->type)
{
case more:
@ -1734,34 +1756,34 @@ void M_OptDrawer ()
break;
case joymore:
x = 20;
x = 20 * CleanXfac_1;
color = MoreColor;
break;
case numberedmore:
case rsafemore:
case rightmore:
x = indent + 14;
x = indent + cursorspace;
color = item->type != rightmore ? CR_GREEN : MoreColor;
break;
case redtext:
x = 160 - width / 2;
x = screen->GetWidth() / 2 - width / 2;
color = LabelColor;
break;
case whitetext:
x = 160 - width / 2;
x = screen->GetWidth() / 2 - width / 2;
color = CR_GOLD;//ValueColor;
break;
case listelement:
x = indent + 14;
x = indent + cursorspace;
color = LabelColor;
break;
case colorpicker:
x = indent + 14;
x = indent + cursorspace;
color = MoreColor;
break;
@ -1778,7 +1800,7 @@ void M_OptDrawer ()
? CR_YELLOW : LabelColor;
break;
}
screen->DrawText (SmallFont, color, x, y, label, DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
screen->DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
switch (item->type)
{
@ -1788,8 +1810,8 @@ void M_OptDrawer ()
char tbuf[16];
mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position);
x = indent - SmallFont->StringWidth (tbuf);
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE);
x = indent - SmallFont->StringWidth (tbuf) * CleanXfac_1;
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
@ -1805,14 +1827,14 @@ void M_OptDrawer ()
if (v == vals)
{
screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown",
DTA_CleanNoMove_1, true, TAG_DONE);
}
else
{
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
indent + 14, y, item->e.values[v].name,
DTA_Clean, true, TAG_DONE);
indent + cursorspace, y, item->e.values[v].name,
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -1862,15 +1884,15 @@ void M_OptDrawer ()
if (v == vals)
{
screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown",
DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
}
else
{
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
indent + 14, y,
indent + cursorspace, y,
item->type != discretes ? item->e.values[v].name : item->e.valuestrings[v].name.GetChars(),
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
}
}
@ -1882,18 +1904,18 @@ void M_OptDrawer ()
value = item->a.cvar->GetGenericRep (CVAR_String);
v = M_FindCurVal(value.String, item->e.enumvalues, (int)item->b.numvalues);
screen->DrawText(SmallFont, ValueColor, indent + 14, y, v, DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y, v, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
case nochoice:
screen->DrawText (SmallFont, CR_GOLD, indent + 14, y,
(item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, indent + cursorspace, y,
(item->e.values[(int)item->b.min]).name, DTA_CleanNoMove_1, true, TAG_DONE);
break;
case joy_sens:
value.Float = SELECTED_JOYSTICK->GetSensitivity();
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1);
break;
case joy_slider:
@ -1906,29 +1928,29 @@ void M_OptDrawer ()
assert(item->e.joyslidernum == 1);
value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection);
}
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3);
break;
case joy_inverter:
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
screen->DrawText(SmallFont, ValueColor, indent + 14, y,
screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y,
(value.Float < 0) ? "Yes" : "No",
DTA_Clean, true, TAG_DONE);
DTA_CleanNoMove_1, true, TAG_DONE);
break;
case slider:
value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1);
break;
case absslider:
value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1);
break;
case intslider:
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, item->a.fval, 0);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, item->a.fval, 0);
break;
case control:
@ -1938,12 +1960,12 @@ void M_OptDrawer ()
C_NameKeys (description, item->b.key1, item->c.key2);
if (description[0])
{
M_DrawConText(CR_WHITE, indent + 14, y-1+labelofs, description);
M_DrawConText(CR_WHITE, indent + cursorspace, y-1+labelofs, description);
}
else
{
screen->DrawText(SmallFont, CR_BLACK, indent + 14, y + labelofs, "---",
DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, CR_BLACK, indent + cursorspace, y + labelofs, "---",
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
break;
@ -1951,9 +1973,9 @@ void M_OptDrawer ()
case colorpicker:
{
int box_x, box_y;
box_x = (indent - 35 - 160) * CleanXfac + screen->GetWidth()/2;
box_y = (y - ((gameinfo.gametype & GAME_Raven) ? 99 : 100)) * CleanYfac + screen->GetHeight()/2;
screen->Clear (box_x, box_y, box_x + 32*CleanXfac, box_y + (fontheight-1)*CleanYfac,
box_x = indent - 35 * CleanXfac_1;
box_y = (gameinfo.gametype & GAME_Raven) ? y - CleanYfac_1 : y;
screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + fontheight-CleanYfac_1,
item->a.colorcvar->GetIndex(), 0);
}
break;
@ -1962,12 +1984,12 @@ void M_OptDrawer ()
{
int box_x, box_y;
int x1, p;
const int w = fontheight*CleanXfac;
const int h = fontheight*CleanYfac;
const int w = fontheight;
const int h = fontheight;
box_y = (y - 98) * CleanYfac + screen->GetHeight()/2;
box_y = y - 2 * CleanYfac_1;
p = 0;
box_x = (indent - 32 - 160) * CleanXfac + screen->GetWidth()/2;
box_x = indent - 32 * CleanXfac_1;
for (x1 = 0, p = int(item->b.min * 16); x1 < 16; ++p, ++x1)
{
screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0);
@ -2022,7 +2044,7 @@ void M_OptDrawer ()
}
screen->DrawText (SmallFont, ValueColor,
indent + 14, y, str, DTA_Clean, true, TAG_DONE);
indent + cursorspace, y, str, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
@ -2034,12 +2056,13 @@ void M_OptDrawer ()
i == CurrentItem &&
(skullAnimCounter < 6 || menuactive == MENU_WaitKey))
{
M_DrawConText(CR_RED, indent + 3, y-1+labelofs, "\xd");
M_DrawConText(CR_RED, indent + 3 * CleanXfac_1, y-CleanYfac_1+labelofs, "\xd");
}
}
else
{
char *str = NULL;
int colwidth = screen->GetWidth() / 3;
for (x = 0; x < 3; x++)
{
@ -2056,13 +2079,13 @@ void M_OptDrawer ()
else
color = CR_BRICK; //LabelColor;
screen->DrawText (SmallFont, color, 104 * x + 20, y, str, DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, color, colwidth * x + 20 * CleanXfac_1, y, str, DTA_CleanNoMove_1, true, TAG_DONE);
}
}
if (i == CurrentItem && ((item->a.selmode != -1 && (skullAnimCounter < 6 || menuactive == MENU_WaitKey)) || testingmode))
{
M_DrawConText(CR_RED, item->a.selmode * 104 + 8, y-1 + labelofs, "\xd");
M_DrawConText(CR_RED, item->a.selmode * colwidth + 8 * CleanXfac_1, y - CleanYfac_1 + labelofs, "\xd");
}
}
}
@ -2073,11 +2096,11 @@ void M_OptDrawer ()
if (CanScrollUp)
{
M_DrawConText(CR_ORANGE, 3, ytop + labelofs, "\x1a");
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop + labelofs, "\x1a");
}
if (CanScrollDown)
{
M_DrawConText(CR_ORANGE, 3, y - 8 + labelofs, "\x1b");
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1 + labelofs, "\x1b");
}
if (flagsvar)
@ -2100,8 +2123,8 @@ void M_OptDrawer ()
}
}
screen->DrawText (SmallFont, ValueColor,
160 - (SmallFont->StringWidth (flagsblah) >> 1), 0, flagsblah,
DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - SmallFont->StringWidth (flagsblah) * CleanXfac_1) / 2, 0, flagsblah,
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -2120,11 +2143,10 @@ void M_OptResponder(event_t *ev)
CurrentMenu->items[0].label = OldMessage;
CurrentMenu->items[0].type = OldType;
}
else if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_KeyDown && tolower(ev->data1) == 't')
else if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_KeyDown)
{
// Test selected resolution
if (CurrentMenu == &ModesMenu)
{
if (CurrentMenu == &ModesMenu && (ev->data1 == 't' || ev->data1 == 'T'))
{ // Test selected resolution
if (!(item->type == screenres &&
GetSelectedSize (CurrentItem, &NewWidth, &NewHeight)))
{
@ -2140,6 +2162,23 @@ void M_OptResponder(event_t *ev)
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", 1, ATTN_NONE);
SetModesMenu (NewWidth, NewHeight, NewBits);
}
else if (ev->data1 >= '0' && ev->data1 <= '9')
{ // Activate an item of type numberedmore
int i;
int num = ev->data1 == '0' ? 10 : ev->data1 - '0';
for (i = 0; i < CurrentMenu->numitems; ++i)
{
menuitem_t *item = CurrentMenu->items + i;
if (item->type == numberedmore && item->b.position == num)
{
CurrentItem = i;
M_OptButtonHandler(MKEY_Enter, false);
break;
}
}
}
}
}
@ -2254,31 +2293,33 @@ void M_OptButtonHandler(EMenuKey key, bool repeat)
}
if (CurrentItem < 0)
{
int maxitems, rowheight;
int ytop, maxitems, rowheight;
// Figure out how many lines of text fit on the menu
if (CurrentMenu->y != 0)
{
maxitems = CurrentMenu->y;
ytop = CurrentMenu->y;
}
else if (BigFont && CurrentMenu->texttitle)
{
maxitems = 15 + BigFont->GetHeight ();
ytop = 15 + BigFont->GetHeight ();
}
else
{
maxitems = 15;
ytop = 15;
}
if (!(gameinfo.gametype & GAME_DoomChex))
{
maxitems -= 2;
ytop -= 2;
rowheight = 9;
}
else
{
rowheight = 8;
}
maxitems = (200 - SmallFont->GetHeight () - maxitems) / rowheight + 1;
ytop *= CleanYfac_1;
rowheight *= CleanYfac_1;
maxitems = (screen->GetHeight() - SmallFont->GetHeight() - ytop) / rowheight + 1;
CurrentMenu->scrollpos = MAX (0,CurrentMenu->numitems - maxitems + CurrentMenu->scrolltop);
CurrentItem = CurrentMenu->numitems - 1;
@ -2746,35 +2787,7 @@ void M_OptButtonHandler(EMenuKey key, bool repeat)
item->b.key1 = item->c.key2 = 0;
}
break;
/*
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
int lookfor = ch == '0' ? 10 : ch - '0', i;
for (i = 0; i < CurrentMenu->numitems; ++i)
{
if (CurrentMenu->items[i].b.position == lookfor)
{
CurrentItem = i;
item = &CurrentMenu->items[i];
break;
}
}
if (i == CurrentMenu->numitems)
{
break;
}
// Otherwise, fall through to '\r' below
}
*/
case MKEY_Enter:
if (CurrentMenu == &ModesMenu && item->type == screenres)
{
@ -2977,7 +2990,7 @@ static void DefaultCustomColors ()
}
}
static void ColorPickerDrawer ()
static bool ColorPickerDrawer ()
{
DWORD newColor = MAKEARGB(255,
int(ColorPickerItems[2].a.fval),
@ -2986,16 +2999,17 @@ static void ColorPickerDrawer ()
DWORD oldColor = DWORD(*ColorPickerItems[0].a.colorcvar) | 0xFF000000;
int x = screen->GetWidth()*2/3;
int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 90) * CleanYfac + screen->GetHeight()/2;
int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 10) * CleanYfac_1;
screen->Clear (x, y, x + 48*CleanXfac, y + 48*CleanYfac, -1, oldColor);
screen->Clear (x + 48*CleanXfac, y, x + 48*2*CleanXfac, y + 48*CleanYfac, -1, newColor);
screen->Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, -1, oldColor);
screen->Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, -1, newColor);
y += 49*CleanYfac;
screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac, y,
"Old", DTA_CleanNoMove, true, TAG_DONE);
screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac, y,
"New", DTA_CleanNoMove, true, TAG_DONE);
y += 49*CleanYfac_1;
screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac_1, y,
"Old", DTA_CleanNoMove_1, true, TAG_DONE);
screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac_1, y,
"New", DTA_CleanNoMove_1, true, TAG_DONE);
return false;
}
static void SetColorPickerSliders ()
@ -3092,15 +3106,17 @@ CCMD (menu_mouse)
MouseOptions ();
}
static void DrawJoystickConfigMenuHeader()
static bool DrawJoystickConfigMenuHeader()
{
FString joyname = SELECTED_JOYSTICK->GetName();
screen->DrawText(BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-BigFont->StringWidth(CurrentMenu->texttitle)/2, 5,
CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2,
5 * CleanYfac_1,
CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE);
screen->DrawText(SmallFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-SmallFont->StringWidth(joyname)/2, 8 + BigFont->GetHeight(),
joyname, DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - SmallFont->StringWidth(joyname) * CleanXfac_1) / 2, (8 + BigFont->GetHeight()) * CleanYfac_1,
joyname, DTA_CleanNoMove_1, true, TAG_DONE);
return false;
}
static void UpdateJoystickConfigMenu(IJoystickConfig *joy)

View file

@ -82,6 +82,13 @@ __forceinline SDWORD MulScale32 (SDWORD a, SDWORD b)
__asm mov eax,edx
}
__forceinline DWORD UMulScale16(DWORD a, DWORD b)
{
__asm mov eax,a
__asm mul b
__asm shrd eax,edx,16
}
__forceinline SDWORD DMulScale (SDWORD a, SDWORD b, SDWORD c, SDWORD d, SDWORD s)
{
__asm mov eax,a
@ -341,20 +348,4 @@ __forceinline SDWORD ksgn (SDWORD a)
__asm adc eax,0
}
__forceinline int toint (float v)
{
SQWORD res;
__asm fld v;
__asm fistp res;
return (int)res;
}
__forceinline int quickertoint (float v)
{
SDWORD res;
__asm fld v;
__asm fistp res;
return (int)res;
}
#pragma warning (default: 4035)

View file

@ -121,7 +121,8 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
BYTE chanUsed[16];
BYTE lastVel[16];
long trackLen;
bool no_op;
// Do some validation of the MUS file
if (MUSMagic != musHead->Magic)
return false;
@ -178,12 +179,13 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
midStatus = channel;
midArgs = 0; // Most events have two args (0 means 2, 1 means 1)
no_op = false;
switch (event & 0x70)
{
case MUS_NOTEOFF:
midStatus |= MIDI_NOTEOFF;
mid1 = t;
mid1 = t & 127;
mid2 = 64;
break;
@ -192,7 +194,7 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
mid1 = t & 127;
if (t & 128)
{
lastVel[channel] = musBuf[mus_p++];;
lastVel[channel] = musBuf[mus_p++] & 127;
}
mid2 = lastVel[channel];
break;
@ -204,9 +206,16 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
break;
case MUS_SYSEVENT:
midStatus |= MIDI_CTRLCHANGE;
mid1 = CtrlTranslate[t];
mid2 = t == 12 ? LittleShort(musHead->NumChans) : 0;
if (t < 10 || t > 14)
{
no_op = true;
}
else
{
midStatus |= MIDI_CTRLCHANGE;
mid1 = CtrlTranslate[t];
mid2 = t == 12 /* Mono */ ? LittleShort(musHead->NumChans) : 0;
}
break;
case MUS_CTRLCHANGE:
@ -214,27 +223,39 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
{ // program change
midArgs = 1;
midStatus |= MIDI_PRGMCHANGE;
mid1 = musBuf[mus_p++];
mid1 = musBuf[mus_p++] & 127;
mid2 = 0; // Assign mid2 just to make GCC happy
}
else
else if (t > 0 && t < 10)
{
midStatus |= MIDI_CTRLCHANGE;
mid1 = CtrlTranslate[t];
mid2 = musBuf[mus_p++];
}
else
{
no_op = true;
}
break;
case MUS_SCOREEND:
midStatus = 0xff;
mid1 = 0x2f;
mid2 = 0x00;
midStatus = MIDI_META;
mid1 = MIDI_META_EOT;
mid2 = 0;
break;
default:
return false;
}
if (no_op)
{
// A system-specific event with no data is a no-op.
midStatus = MIDI_META;
mid1 = MIDI_META_SSPEC;
mid2 = 0;
}
WriteVarLen (outFile, deltaTime);
if (midStatus != status)

View file

@ -46,6 +46,7 @@
#define MIDI_META ((BYTE)0xFF) // Meta event begin
#define MIDI_META_TEMPO ((BYTE)0x51)
#define MIDI_META_EOT ((BYTE)0x2F) // End-of-track
#define MIDI_META_SSPEC ((BYTE)0x7F) // System-specific event
#define MIDI_NOTEOFF ((BYTE)0x80) // + note + velocity
#define MIDI_NOTEON ((BYTE)0x90) // + note + velocity

Some files were not shown because too many files have changed in this diff Show more