mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 05:01:41 +00:00
- Synced the scripting branch with trunk.
SVN r2166 (scripting)
This commit is contained in:
commit
913555aa4e
284 changed files with 13344 additions and 7516 deletions
642
docs/rh-log.txt
642
docs/rh-log.txt
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
41
src/actor.h
41
src/actor.h
|
@ -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)
|
||||
|
|
200
src/am_map.cpp
200
src/am_map.cpp
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
124
src/d_iwad.cpp
124
src/d_iwad.cpp
|
@ -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);
|
||||
|
|
298
src/d_main.cpp
298
src/d_main.cpp
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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] != '/')
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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--)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
1320
src/g_shared/sbarinfo.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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__
|
||||
|
|
2605
src/g_shared/sbarinfo_commands.cpp
Normal file
2605
src/g_shared/sbarinfo_commands.cpp
Normal file
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
|
@ -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;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "gi.h"
|
||||
#include "templates.h"
|
||||
#include "v_font.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
TArray<FSkillInfo> AllSkills;
|
||||
int DefaultSkill = -1;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
2
src/gi.h
2
src/gi.h
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
71
src/info.cpp
71
src/info.cpp
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
286
src/m_menu.cpp
286
src/m_menu.cpp
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue