mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- Update to latest version in trunk.
SVN r3890 (scripting)
This commit is contained in:
commit
e7efa1d802
117 changed files with 2261 additions and 788 deletions
37
src/actor.h
37
src/actor.h
|
@ -30,9 +30,7 @@
|
|||
#include "dthinker.h"
|
||||
|
||||
|
||||
// States are tied to finite states are
|
||||
// tied to animation frames.
|
||||
// Needs precompiled tables/data structures.
|
||||
// States are tied to finite states are tied to animation frames.
|
||||
#include "info.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
|
@ -40,6 +38,7 @@
|
|||
#include "r_data/renderstyle.h"
|
||||
#include "s_sound.h"
|
||||
#include "memarena.h"
|
||||
#include "g_level.h"
|
||||
|
||||
struct subsector_t;
|
||||
class PClassAmmo;
|
||||
|
@ -550,15 +549,14 @@ public:
|
|||
bool AdjustReflectionAngle (AActor *thing, angle_t &angle);
|
||||
|
||||
// Returns true if this actor is within melee range of its target
|
||||
bool CheckMeleeRange ();
|
||||
bool CheckMeleeRange();
|
||||
|
||||
// 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.
|
||||
virtual void HandleSpawnFlags ();
|
||||
virtual void BeginPlay(); // Called immediately after the actor is created
|
||||
virtual void PostBeginPlay(); // Called immediately before the actor's first tick
|
||||
virtual void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world
|
||||
virtual void HandleSpawnFlags(); // Translates SpawnFlags into in-game flags.
|
||||
|
||||
virtual void MarkPrecacheSounds() const; // Marks sounds used by this actor for precaching.
|
||||
|
||||
virtual void Activate (AActor *activator);
|
||||
virtual void Deactivate (AActor *activator);
|
||||
|
@ -679,9 +677,20 @@ public:
|
|||
// Do I hate the other actor?
|
||||
bool IsHostile (AActor *other);
|
||||
|
||||
inline bool IsNoClip2() const;
|
||||
|
||||
// What species am I?
|
||||
virtual FName GetSpecies();
|
||||
|
||||
|
||||
fixed_t GetBobOffset(fixed_t ticfrac=0) const
|
||||
{
|
||||
if (!(flags2 & MF2_FLOATBOB))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8;
|
||||
}
|
||||
|
||||
// Enter the crash state
|
||||
void Crash();
|
||||
|
||||
|
@ -938,6 +947,7 @@ private:
|
|||
static FSharedStringArena mStringPropertyData;
|
||||
|
||||
friend class FActorIterator;
|
||||
friend bool P_IsTIDUsed(int tid);
|
||||
|
||||
sector_t *LinkToWorldForMapThing ();
|
||||
|
||||
|
@ -1032,6 +1042,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
bool P_IsTIDUsed(int tid);
|
||||
int P_FindUniqueTID(int start_tid, int limit);
|
||||
|
||||
inline AActor *Spawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
||||
{
|
||||
return AActor::StaticSpawn (type, x, y, z, allowreplacement);
|
||||
|
|
|
@ -173,6 +173,15 @@ CCMD (noclip)
|
|||
Net_WriteByte (CHT_NOCLIP);
|
||||
}
|
||||
|
||||
CCMD (noclip2)
|
||||
{
|
||||
if (CheckCheatmode())
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_NOCLIP2);
|
||||
}
|
||||
|
||||
CCMD (powerup)
|
||||
{
|
||||
if (CheckCheatmode ())
|
||||
|
@ -243,7 +252,7 @@ CCMD (chase)
|
|||
else
|
||||
{
|
||||
// Check if we're allowed to use chasecam.
|
||||
if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && CheckCheatmode ()))
|
||||
if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && deathmatch && CheckCheatmode ()))
|
||||
return;
|
||||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
|
@ -947,9 +956,16 @@ CCMD(thaw)
|
|||
//-----------------------------------------------------------------------------
|
||||
CCMD(nextmap)
|
||||
{
|
||||
char * next=NULL;
|
||||
if (netgame)
|
||||
{
|
||||
Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextmap"
|
||||
TEXTCOLOR_NORMAL" is for single-player only.\n");
|
||||
return;
|
||||
}
|
||||
char *next = NULL;
|
||||
|
||||
if (*level.nextmap) next = level.nextmap;
|
||||
if (*level.nextmap)
|
||||
next = level.nextmap;
|
||||
|
||||
if (next != NULL && strncmp(next, "enDSeQ", 6))
|
||||
{
|
||||
|
@ -968,9 +984,16 @@ CCMD(nextmap)
|
|||
//-----------------------------------------------------------------------------
|
||||
CCMD(nextsecret)
|
||||
{
|
||||
char * next=NULL;
|
||||
if (netgame)
|
||||
{
|
||||
Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextsecret"
|
||||
TEXTCOLOR_NORMAL" is for single-player only.\n");
|
||||
return;
|
||||
}
|
||||
char *next = NULL;
|
||||
|
||||
if (*level.secretmap) next = level.secretmap;
|
||||
if (*level.secretmap)
|
||||
next = level.secretmap;
|
||||
|
||||
if (next != NULL && strncmp(next, "enDSeQ", 6))
|
||||
{
|
||||
|
|
|
@ -273,7 +273,9 @@ void CT_Drawer (void)
|
|||
|
||||
if (players[consoleplayer].camera != NULL &&
|
||||
(Button_ShowScores.bDown ||
|
||||
players[consoleplayer].camera->health <= 0))
|
||||
players[consoleplayer].camera->health <= 0) &&
|
||||
// Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp.
|
||||
gamestate != GS_INTERMISSION)
|
||||
{
|
||||
HU_DrawScores (&players[consoleplayer]);
|
||||
}
|
||||
|
|
|
@ -1354,7 +1354,7 @@ static int PatchFrame (int frameNum)
|
|||
|
||||
if (keylen == 8 && stricmp (Line1, "Duration") == 0)
|
||||
{
|
||||
tics = clamp (val, -1, 65534);
|
||||
tics = clamp (val, -1, SHRT_MAX);
|
||||
}
|
||||
else if (keylen == 9 && stricmp (Line1, "Unknown 1") == 0)
|
||||
{
|
||||
|
|
|
@ -804,17 +804,21 @@ void D_Display ()
|
|||
|
||||
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_None);
|
||||
if (DrawFSHUD || automapactive) DrawHUD();
|
||||
StatusBar->DrawTopStuff (HUD_None);
|
||||
}
|
||||
else
|
||||
if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10)
|
||||
{
|
||||
StatusBar->Draw (DrawFSHUD ? HUD_Fullscreen : HUD_None);
|
||||
StatusBar->DrawTopStuff (DrawFSHUD ? HUD_Fullscreen : HUD_None);
|
||||
EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None;
|
||||
StatusBar->DrawBottomStuff (state);
|
||||
StatusBar->Draw (state);
|
||||
StatusBar->DrawTopStuff (state);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_StatusBar);
|
||||
StatusBar->Draw (HUD_StatusBar);
|
||||
StatusBar->DrawTopStuff (HUD_StatusBar);
|
||||
}
|
||||
|
@ -2207,14 +2211,17 @@ void D_DoomMain (void)
|
|||
// [RH] Load sound environments
|
||||
S_ParseReverbDef ();
|
||||
|
||||
// [RH] Parse any SNDINFO lumps
|
||||
Printf ("S_InitData: Load sound definitions.\n");
|
||||
S_InitData ();
|
||||
|
||||
// [RH] Parse through all loaded mapinfo lumps
|
||||
Printf ("G_ParseMapInfo: Load map definitions.\n");
|
||||
G_ParseMapInfo (iwad_info->MapInfo);
|
||||
ReadStatistics();
|
||||
|
||||
// [RH] Parse any SNDINFO lumps
|
||||
Printf ("S_InitData: Load sound definitions.\n");
|
||||
S_InitData ();
|
||||
// MUSINFO must be parsed after MAPINFO
|
||||
S_ParseMusInfo();
|
||||
|
||||
Printf ("Texman.Init: Init texture manager.\n");
|
||||
TexMan.Init();
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "p_lnspec.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h"
|
||||
#include "hardware.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
|
@ -135,7 +136,18 @@ static int oldentertics;
|
|||
|
||||
extern bool advancedemo;
|
||||
|
||||
CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
// Do not use the separate FPS limit timer if we are limiting FPS with this.
|
||||
if (self)
|
||||
{
|
||||
I_SetFPSLimit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
I_SetFPSLimit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Special "ticcmds" get stored in here
|
||||
static struct TicSpecial
|
||||
|
|
|
@ -65,7 +65,9 @@ struct FPlayerColorSet
|
|||
BYTE NumExtraRanges;
|
||||
ExtraRange Extra[6];
|
||||
};
|
||||
|
||||
typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
|
||||
typedef TMap<FName, PalEntry> PainFlashList;
|
||||
|
||||
class PClassPlayerPawn : public PClassActor
|
||||
{
|
||||
|
@ -76,6 +78,8 @@ public:
|
|||
PClassPlayerPawn();
|
||||
void EnumColorSets(TArray<int> *out);
|
||||
FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
|
||||
void SetPainFlash(FName type, PalEntry color);
|
||||
bool GetPainFlash(FName type, PalEntry *color) const;
|
||||
|
||||
FString DisplayName; // Display name (used in menus, etc.)
|
||||
FString SoundClass; // Sound class
|
||||
|
@ -88,6 +92,7 @@ public:
|
|||
BYTE ColorRangeStart; // Skin color range
|
||||
BYTE ColorRangeEnd;
|
||||
FPlayerColorSetMap ColorSets;
|
||||
PainFlashList PainFlashes;
|
||||
};
|
||||
FString GetPrintableDisplayName(PClassPlayerPawn *cls);
|
||||
|
||||
|
@ -105,6 +110,7 @@ public:
|
|||
virtual void AddInventory (AInventory *item);
|
||||
virtual void RemoveInventory (AInventory *item);
|
||||
virtual bool UseInventory (AInventory *item);
|
||||
virtual void MarkPrecacheSounds () const;
|
||||
|
||||
virtual void PlayIdle ();
|
||||
virtual void PlayRunning ();
|
||||
|
@ -122,7 +128,7 @@ public:
|
|||
void GiveDefaultInventory ();
|
||||
void PlayAttacking ();
|
||||
void PlayAttacking2 ();
|
||||
const char *GetSoundClass ();
|
||||
const char *GetSoundClass () const;
|
||||
|
||||
enum EInvulState
|
||||
{
|
||||
|
@ -145,6 +151,8 @@ public:
|
|||
|
||||
// [GRB] Player class properties
|
||||
fixed_t JumpZ;
|
||||
fixed_t GruntSpeed;
|
||||
fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed;
|
||||
fixed_t ViewHeight;
|
||||
fixed_t ForwardMove1, ForwardMove2;
|
||||
fixed_t SideMove1, SideMove2;
|
||||
|
@ -221,6 +229,7 @@ typedef enum
|
|||
CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die
|
||||
CF_WEAPONRELOADOK = 1 << 28, // [XA] Okay to reload this weapon.
|
||||
CF_WEAPONZOOMOK = 1 << 29, // [XA] Okay to use weapon zoom function.
|
||||
CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip
|
||||
} cheat_t;
|
||||
|
||||
#define WPIECE1 1
|
||||
|
@ -452,6 +461,14 @@ inline void AActor::SetFriendPlayer(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
inline bool AActor::IsNoClip2() const
|
||||
{
|
||||
if (player != NULL && player->mo == this)
|
||||
{
|
||||
return (player->cheats & CF_NOCLIP2) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define CROUCHSPEED (FRACUNIT/12)
|
||||
|
||||
|
|
|
@ -218,7 +218,8 @@ enum ECheatCommand
|
|||
CHT_GIMMIEI,
|
||||
CHT_GIMMIEJ,
|
||||
CHT_GIMMIEZ,
|
||||
CHT_BUDDHA
|
||||
CHT_BUDDHA,
|
||||
CHT_NOCLIP2
|
||||
};
|
||||
|
||||
void StartChunk (int id, BYTE **stream);
|
||||
|
|
|
@ -3367,7 +3367,7 @@ void FParser::SF_RadiusAttack()
|
|||
|
||||
if (spot && source)
|
||||
{
|
||||
P_RadiusAttack(spot, source, damage, damage, NAME_None, true);
|
||||
P_RadiusAttack(spot, source, damage, damage, NAME_None, RADF_HURTSOURCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ void T_LoadScripts(MapData *map)
|
|||
// the default translator is being used.
|
||||
// Custom translators will not be patched.
|
||||
if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && level.info->Translator.IsEmpty() &&
|
||||
level.maptype == MAPTYPE_DOOM && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute)
|
||||
level.maptype == MAPTYPE_DOOM && SimpleLineTranslations.Size() > 272 && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute)
|
||||
{
|
||||
FLineTrans t = SimpleLineTranslations[270];
|
||||
SimpleLineTranslations[270] = SimpleLineTranslations[272];
|
||||
|
|
|
@ -145,7 +145,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
|
|||
target->y - FixedMul (24*FRACUNIT, finesine[an]),
|
||||
target->z);
|
||||
|
||||
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, false);
|
||||
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
|
||||
}
|
||||
target->velz = Scale(thrust, 1000, target->Mass);
|
||||
return 0;
|
||||
|
|
|
@ -151,7 +151,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom)
|
|||
spawntype = PClass::FindActor("FatShot");
|
||||
}
|
||||
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, !(flags & MSF_DontHurt));
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE);
|
||||
P_CheckSplash(self, 128<<FRACBITS);
|
||||
|
||||
// Now launch mushroom cloud
|
||||
|
|
|
@ -52,7 +52,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb)
|
|||
self->z += 32*FRACUNIT;
|
||||
self->RenderStyle = STYLE_Add;
|
||||
self->alpha = FRACUNIT;
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true);
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
|
||||
P_CheckSplash(self, 128<<FRACBITS);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact)
|
|||
self->z += 28*FRACUNIT;
|
||||
//self->velz = 3*FRACUNIT;
|
||||
}
|
||||
P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, true);
|
||||
P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tiny = Spawn("VolcanoTBlast", self->x, self->y, self->z, ALLOW_REPLACE);
|
||||
|
|
|
@ -98,8 +98,8 @@ 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_INT_OPT (strength) { strength = 255; }
|
||||
PARAM_INT_OPT (radius) { radius = 255; }
|
||||
PARAM_FIXED_OPT (speed) { speed = 20; }
|
||||
PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); }
|
||||
PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; }
|
||||
|
|
|
@ -418,7 +418,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage)
|
|||
|
||||
int bobIndex;
|
||||
|
||||
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, true);
|
||||
P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE);
|
||||
bobIndex = self->special2;
|
||||
self->z += finesine[bobIndex << BOBTOFINESHIFT] >> 1;
|
||||
self->special2 = (bobIndex + 1) & 63;
|
||||
|
|
|
@ -737,7 +737,14 @@ void G_DoCompleted (void)
|
|||
|
||||
if (mode == FINISH_SameHub)
|
||||
{ // Remember the level's state for re-entry.
|
||||
G_SnapshotLevel ();
|
||||
if (!(level.flags2 & LEVEL2_FORGETSTATE))
|
||||
{
|
||||
G_SnapshotLevel ();
|
||||
}
|
||||
else
|
||||
{ // Make sure we don't have a snapshot lying around from before.
|
||||
level.info->ClearSnapshot();
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Forget the states of all existing levels.
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
//#include "autosegs.h"
|
||||
#include "sc_man.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
struct level_info_t;
|
||||
struct cluster_info_t;
|
||||
|
@ -179,7 +179,7 @@ enum ELevelFlags
|
|||
|
||||
LEVEL2_KEEPFULLINVENTORY = 0x00000040, // doesn't reduce the amount of inventory items to 1
|
||||
|
||||
LEVEL2_MUSICDEFINED = 0x00000080, // a marker to disable the $map command in SNDINFO for this map
|
||||
/* = 0x00000080, */
|
||||
LEVEL2_MONSTERFALLINGDAMAGE = 0x00000100,
|
||||
LEVEL2_CLIPMIDTEX = 0x00000200,
|
||||
LEVEL2_WRAPMIDTEX = 0x00000400,
|
||||
|
@ -211,6 +211,7 @@ enum ELevelFlags
|
|||
LEVEL2_NOSTATISTICS = 0x10000000, // This level should not have statistics collected
|
||||
LEVEL2_ENDGAME = 0x20000000, // This is an epilogue level that cannot be quit.
|
||||
LEVEL2_NOAUTOSAVEHINT = 0x40000000, // tell the game that an autosave for this level does not need to be kept
|
||||
LEVEL2_FORGETSTATE = 0x80000000, // forget this map's state in a hub
|
||||
};
|
||||
|
||||
|
||||
|
@ -325,6 +326,8 @@ struct level_info_t
|
|||
|
||||
TArray<FSpecialAction> specialactions;
|
||||
|
||||
TArray<FSoundID> PrecacheSounds;
|
||||
|
||||
level_info_t()
|
||||
{
|
||||
Reset();
|
||||
|
|
|
@ -61,6 +61,8 @@ static cluster_info_t TheDefaultClusterInfo;
|
|||
|
||||
TArray<FEpisode> AllEpisodes;
|
||||
|
||||
extern TMap<int, FString> HexenMusic;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -269,6 +271,7 @@ void level_info_t::Reset()
|
|||
teamdamage = 0.f;
|
||||
specialactions.Clear();
|
||||
DefaultEnvironment = 0;
|
||||
PrecacheSounds.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -917,8 +920,6 @@ DEFINE_MAP_OPTION(music, true)
|
|||
{
|
||||
parse.ParseAssign();
|
||||
parse.ParseMusic(info->Music, info->musicorder);
|
||||
// Flag the level so that the $MAP command doesn't override this.
|
||||
info->flags2 |= LEVEL2_MUSICDEFINED;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(intermusic, true)
|
||||
|
@ -1029,7 +1030,7 @@ DEFINE_MAP_OPTION(specialaction, true)
|
|||
sa->Action = P_FindLineSpecial(parse.sc.String, &min_arg, &max_arg);
|
||||
if (sa->Action == 0 || min_arg < 0)
|
||||
{
|
||||
parse.sc.ScriptError("Unknown specialaction '%s'");
|
||||
parse.sc.ScriptError("Unknown specialaction '%s'", parse.sc.String);
|
||||
}
|
||||
int j = 0;
|
||||
while (j < 5 && parse.sc.CheckString(","))
|
||||
|
@ -1040,6 +1041,25 @@ DEFINE_MAP_OPTION(specialaction, true)
|
|||
if (parse.format_type == parse.FMT_Old) parse.sc.SetCMode(false);
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(PrecacheSounds, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
||||
do
|
||||
{
|
||||
parse.sc.MustGetString();
|
||||
FSoundID snd = parse.sc.String;
|
||||
if (snd == 0)
|
||||
{
|
||||
parse.sc.ScriptMessage("Unknown sound \"%s\"", parse.sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->PrecacheSounds.Push(snd);
|
||||
}
|
||||
} while (parse.sc.CheckString(","));
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(redirect, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
@ -1244,6 +1264,8 @@ MapFlagHandlers[] =
|
|||
{ "endofgame", MITYPE_SETFLAG2, LEVEL2_ENDGAME, 0 },
|
||||
{ "nostatistics", MITYPE_SETFLAG2, LEVEL2_NOSTATISTICS, 0 },
|
||||
{ "noautosavehint", MITYPE_SETFLAG2, LEVEL2_NOAUTOSAVEHINT, 0 },
|
||||
{ "forgetstate", MITYPE_SETFLAG2, LEVEL2_FORGETSTATE, 0 },
|
||||
{ "rememberstate", MITYPE_CLRFLAG2, LEVEL2_FORGETSTATE, 0 },
|
||||
{ "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 },
|
||||
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
||||
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
|
||||
|
@ -1516,6 +1538,14 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo)
|
|||
// to teleport to maps with standard names without needing a levelnum.
|
||||
levelinfo->levelnum = GetDefaultLevelNum(levelinfo->mapname);
|
||||
|
||||
// Does this map have a song defined via SNDINFO's $map command?
|
||||
// Set that as this map's default music if it does.
|
||||
FString *song;
|
||||
if ((song = HexenMusic.CheckKey(levelinfo->levelnum)) != NULL)
|
||||
{
|
||||
levelinfo->Music = *song;
|
||||
}
|
||||
|
||||
return levelinfo;
|
||||
}
|
||||
|
||||
|
@ -1810,7 +1840,6 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -47,12 +47,12 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
|
|||
}
|
||||
if (p->morphTics)
|
||||
{ // Player is already a beast
|
||||
if ((p->mo->GetClass() == spawntype)
|
||||
&& (p->mo->PlayerFlags & PPF_CANSUPERMORPH)
|
||||
&& (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE))
|
||||
&& (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL))
|
||||
{ // Make a super chicken
|
||||
p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2));
|
||||
if ((p->mo->GetClass() == spawntype)
|
||||
&& (p->mo->PlayerFlags & PPF_CANSUPERMORPH)
|
||||
&& (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE))
|
||||
&& (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL))
|
||||
{ // Make a super chicken
|
||||
p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -505,6 +505,18 @@ void AInventory::Serialize (FArchive &arc)
|
|||
arc << Owner << Amount << MaxAmount << RespawnTics << ItemFlags << Icon << PickupSound << SpawnPointClass;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: MarkPrecacheSounds
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AInventory::MarkPrecacheSounds() const
|
||||
{
|
||||
Super::MarkPrecacheSounds();
|
||||
PickupSound.MarkUsed();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: SpecialDropAction
|
||||
|
@ -532,6 +544,7 @@ bool AInventory::SpecialDropAction (AActor *dropper)
|
|||
bool AInventory::ShouldRespawn ()
|
||||
{
|
||||
if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags & DF_RESPAWN_SUPER)) return false;
|
||||
if (ItemFlags & IF_NEVERRESPAWN) return false;
|
||||
return !!(dmflags & DF_ITEMS_RESPAWN);
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ enum
|
|||
IF_NOATTENPICKUPSOUND = 1<<17, // Play pickup sound with ATTN_NONE
|
||||
IF_PERSISTENTPOWER = 1<<18, // Powerup is kept when travelling between levels
|
||||
IF_RESTRICTABSOLUTELY = 1<<19, // RestrictedTo and ForbiddenTo do not allow pickup in any form by other classes
|
||||
IF_NEVERRESPAWN = 1<<20, // Never, ever respawns
|
||||
};
|
||||
|
||||
|
||||
|
@ -147,6 +148,7 @@ public:
|
|||
virtual void Touch (AActor *toucher);
|
||||
virtual void Serialize (FArchive &arc);
|
||||
|
||||
virtual void MarkPrecacheSounds() const;
|
||||
virtual void BeginPlay ();
|
||||
virtual void Destroy ();
|
||||
virtual void Tick ();
|
||||
|
@ -296,6 +298,7 @@ public:
|
|||
|
||||
bool bAltFire; // Set when this weapon's alternate fire is used.
|
||||
|
||||
virtual void MarkPrecacheSounds() const;
|
||||
virtual void Serialize (FArchive &arc);
|
||||
virtual bool ShouldStay ();
|
||||
virtual void AttachToOwner (AActor *other);
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
void PostBeginPlay ();
|
||||
void Activate (AActor *activator);
|
||||
void Deactivate (AActor *activator);
|
||||
void MarkPrecacheSounds () const;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS (ASoundSequence)
|
||||
|
@ -154,6 +155,18 @@ void ASoundSequence::PostBeginPlay ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ASoundSequence :: MarkPrecacheSounds
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ASoundSequence::MarkPrecacheSounds() const
|
||||
{
|
||||
Super::MarkPrecacheSounds();
|
||||
SN_MarkPrecacheSounds(args[0], SEQ_ENVIRONMENT);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ASoundSequence :: Activate
|
||||
|
@ -175,4 +188,3 @@ void ASoundSequence::Deactivate (AActor *activator)
|
|||
{
|
||||
SN_StopSequence (this);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,19 @@ void AWeapon::Serialize (FArchive &arc)
|
|||
<< Crosshair;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: MarkPrecacheSounds
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AWeapon::MarkPrecacheSounds() const
|
||||
{
|
||||
Super::MarkPrecacheSounds();
|
||||
UpSound.MarkUsed();
|
||||
ReadySound.MarkUsed();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: TryPickup
|
||||
|
@ -732,6 +745,7 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
|||
if (weap != NULL)
|
||||
{
|
||||
weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only.
|
||||
weap->flags = (weap->flags & ~MF_DROPPED) | (this->flags & MF_DROPPED);
|
||||
if (AmmoGive1 >= 0) weap->AmmoGive1 = AmmoGive1;
|
||||
if (AmmoGive2 >= 0) weap->AmmoGive2 = AmmoGive2;
|
||||
weap->BecomeItem();
|
||||
|
@ -741,7 +755,11 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
|||
|
||||
weap = barrier_cast<AWeapon*>(master);
|
||||
bool res = weap->CallTryPickup(toucher);
|
||||
if (res) GoAwayAndDie();
|
||||
if (res)
|
||||
{
|
||||
GoAwayAndDie();
|
||||
master = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,9 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
|||
State = 0;
|
||||
SourceText = copystring (text);
|
||||
Font = font;
|
||||
VisibilityFlags = 0;
|
||||
Style = STYLE_Translucent;
|
||||
Alpha = FRACUNIT;
|
||||
ResetText (SourceText);
|
||||
}
|
||||
|
||||
|
@ -184,6 +187,23 @@ void DHUDMessage::Serialize (FArchive &arc)
|
|||
Lines = NULL;
|
||||
ResetText (SourceText);
|
||||
}
|
||||
if (SaveVersion < 3821)
|
||||
{
|
||||
VisibilityFlags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << VisibilityFlags;
|
||||
}
|
||||
if (SaveVersion < 3824)
|
||||
{
|
||||
Style = STYLE_Translucent;
|
||||
Alpha = FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << Style << Alpha;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -262,7 +282,7 @@ bool DHUDMessage::Tick ()
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DHUDMessage::Draw (int bottom)
|
||||
void DHUDMessage::Draw (int bottom, int visibility)
|
||||
{
|
||||
int xscale, yscale;
|
||||
int x, y;
|
||||
|
@ -271,6 +291,12 @@ void DHUDMessage::Draw (int bottom)
|
|||
bool clean = false;
|
||||
int hudheight;
|
||||
|
||||
// If any of the visibility flags match, do NOT draw this message.
|
||||
if (VisibilityFlags & visibility)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawSetup ();
|
||||
|
||||
int screen_width = SCREENWIDTH;
|
||||
|
@ -395,6 +421,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -402,6 +430,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
@ -411,6 +441,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
@ -482,6 +514,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
else
|
||||
{
|
||||
fixed_t trans = -(Tics - FadeOutTics) * FRACUNIT / FadeOutTics;
|
||||
trans = FixedMul(trans, Alpha);
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
|
@ -489,6 +522,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -497,6 +531,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
@ -507,6 +542,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
|
@ -575,6 +611,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
if (State == 0)
|
||||
{
|
||||
fixed_t trans = Tics * FRACUNIT / FadeInTics;
|
||||
trans = FixedMul(trans, Alpha);
|
||||
if (hudheight == 0)
|
||||
{
|
||||
if (con_scaletext <= 1)
|
||||
|
@ -582,6 +619,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -590,6 +628,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
DTA_VirtualWidth, SCREENWIDTH/2,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
@ -600,6 +639,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
|
@ -753,6 +793,8 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_CleanNoMove, clean,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -762,6 +804,8 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
DTA_VirtualHeight, SCREENHEIGHT/2,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
@ -770,7 +814,9 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,13 +66,26 @@ public:
|
|||
|
||||
virtual void Serialize (FArchive &arc);
|
||||
|
||||
void Draw (int bottom);
|
||||
void Draw (int bottom, int visibility);
|
||||
virtual void ResetText (const char *text);
|
||||
virtual void DrawSetup ();
|
||||
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
|
||||
virtual bool Tick (); // Returns true to indicate time for removal
|
||||
virtual void ScreenSizeChanged ();
|
||||
|
||||
void SetVisibility(int vis)
|
||||
{
|
||||
VisibilityFlags = vis;
|
||||
}
|
||||
void SetRenderStyle(ERenderStyle style)
|
||||
{
|
||||
Style = style;
|
||||
}
|
||||
void SetAlpha(fixed_t alpha)
|
||||
{
|
||||
Alpha = alpha;
|
||||
}
|
||||
|
||||
protected:
|
||||
FBrokenLines *Lines;
|
||||
int Width, Height, NumLines;
|
||||
|
@ -81,9 +94,12 @@ protected:
|
|||
int HoldTics;
|
||||
int Tics;
|
||||
int State;
|
||||
int VisibilityFlags;
|
||||
int HUDWidth, HUDHeight;
|
||||
EColorRange TextColor;
|
||||
FFont *Font;
|
||||
FRenderStyle Style;
|
||||
fixed_t Alpha;
|
||||
|
||||
DHUDMessage () : SourceText(NULL) {}
|
||||
|
||||
|
@ -95,6 +111,14 @@ private:
|
|||
friend class DBaseStatusBar;
|
||||
};
|
||||
|
||||
// HUD message visibility flags
|
||||
enum
|
||||
{
|
||||
HUDMSG_NotWith3DView = 1,
|
||||
HUDMSG_NotWithFullMap = 2,
|
||||
HUDMSG_NotWithOverlayMap = 4,
|
||||
};
|
||||
|
||||
// HUD Message; appear instantly, then fade out type ------------------------
|
||||
|
||||
class DHUDMessageFadeOut : public DHUDMessage
|
||||
|
@ -242,6 +266,16 @@ int FindMugShotStateIndex(FName state);
|
|||
class FTexture;
|
||||
class AAmmo;
|
||||
|
||||
enum
|
||||
{
|
||||
HUDMSGLayer_OverHUD,
|
||||
HUDMSGLayer_UnderHUD,
|
||||
HUDMSGLayer_OverMap,
|
||||
|
||||
NUM_HUDMSGLAYERS,
|
||||
HUDMSGLayer_Default = HUDMSGLayer_OverHUD,
|
||||
};
|
||||
|
||||
class DBaseStatusBar : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DBaseStatusBar, DObject)
|
||||
|
@ -281,11 +315,10 @@ public:
|
|||
|
||||
void SetScaled (bool scale, bool force=false);
|
||||
|
||||
void AttachMessage (DHUDMessage *msg, uint32 id=0);
|
||||
void AttachMessage (DHUDMessage *msg, uint32 id=0, int layer=HUDMSGLayer_Default);
|
||||
DHUDMessage *DetachMessage (DHUDMessage *msg);
|
||||
DHUDMessage *DetachMessage (uint32 id);
|
||||
void DetachAllMessages ();
|
||||
bool CheckMessage (DHUDMessage *msg);
|
||||
void ShowPlayerName ();
|
||||
fixed_t GetDisplacement () { return Displacement; }
|
||||
int GetPlayer ();
|
||||
|
@ -296,6 +329,7 @@ public:
|
|||
|
||||
virtual void Tick ();
|
||||
virtual void Draw (EHudState state);
|
||||
void DrawBottomStuff (EHudState state);
|
||||
void DrawTopStuff (EHudState state);
|
||||
virtual void FlashItem (const PClass *itemtype);
|
||||
virtual void AttachToPlayer (player_t *player);
|
||||
|
@ -343,6 +377,7 @@ public:
|
|||
bool Scaled;
|
||||
bool Centering;
|
||||
bool FixedOrigin;
|
||||
bool CompleteBorder;
|
||||
fixed_t CrosshairSize;
|
||||
fixed_t Displacement;
|
||||
|
||||
|
@ -363,10 +398,10 @@ public:
|
|||
private:
|
||||
DBaseStatusBar() {}
|
||||
bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const;
|
||||
void DrawMessages (int bottom);
|
||||
void DrawMessages (int layer, int bottom);
|
||||
void DrawConsistancy () const;
|
||||
|
||||
TObjPtr<DHUDMessage> Messages;
|
||||
TObjPtr<DHUDMessage> Messages[NUM_HUDMSGLAYERS];
|
||||
bool ShowLog;
|
||||
};
|
||||
|
||||
|
|
|
@ -149,6 +149,8 @@ class SBarInfoCommand
|
|||
virtual void Reset() {}
|
||||
virtual void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) {}
|
||||
|
||||
SBarInfo *GetScript() { return script; }
|
||||
|
||||
protected:
|
||||
void GetCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y)
|
||||
{
|
||||
|
@ -798,6 +800,8 @@ void SBarInfo::Init()
|
|||
spacingAlignment = ALIGN_CENTER;
|
||||
resW = 320;
|
||||
resH = 200;
|
||||
cleanX = -1;
|
||||
cleanY = -1;
|
||||
|
||||
for(unsigned int i = 0;i < NUMHUDS;i++)
|
||||
huds[i] = new SBarInfoMainBlock(this);
|
||||
|
@ -978,6 +982,8 @@ public:
|
|||
}
|
||||
invBarOffset = script->Images.Size();
|
||||
Images.Init(&patchnames[0], patchnames.Size());
|
||||
|
||||
CompleteBorder = script->completeBorder;
|
||||
}
|
||||
|
||||
~DSBarInfo ()
|
||||
|
@ -985,19 +991,22 @@ public:
|
|||
Images.Uninit();
|
||||
}
|
||||
|
||||
void ScreenSizeChanged()
|
||||
{
|
||||
Super::ScreenSizeChanged();
|
||||
V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY);
|
||||
}
|
||||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
DBaseStatusBar::Draw(state);
|
||||
if (script->cleanX <= 0)
|
||||
{ // Calculate cleanX and cleanY
|
||||
ScreenSizeChanged();
|
||||
}
|
||||
int hud = STBAR_NORMAL;
|
||||
if(state == HUD_StatusBar)
|
||||
{
|
||||
if(script->completeBorder) //Fill the statusbar with the border before we draw.
|
||||
{
|
||||
FTexture *b = TexMan[gameinfo.border->b];
|
||||
V_DrawBorder(viewwindowx, viewwindowy + viewheight + b->GetHeight(), viewwindowx + viewwidth, SCREENHEIGHT);
|
||||
if(screenblocks == 10)
|
||||
screen->FlatFill(viewwindowx, viewwindowy + viewheight, viewwindowx + viewwidth, viewwindowy + viewheight + b->GetHeight(), b, true);
|
||||
}
|
||||
if(script->automapbar && automapactive)
|
||||
{
|
||||
hud = STBAR_AUTOMAP;
|
||||
|
@ -1250,8 +1259,8 @@ public:
|
|||
{
|
||||
double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX;
|
||||
|
||||
double xScale = !hud_scale ? 1.0 : (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW;
|
||||
double yScale = !hud_scale ? 1.0 : (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENHEIGHT/(double) script->resH;
|
||||
double xScale = !hud_scale ? 1 : script->cleanX;
|
||||
double yScale = !hud_scale ? 1 : script->cleanY;
|
||||
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale);
|
||||
|
||||
|
@ -1283,34 +1292,6 @@ public:
|
|||
rcy = cy == 0 ? 0 : ry+(((double) cy/FRACUNIT)*yScale);
|
||||
rcr = cr == 0 ? INT_MAX : rx+w-(((double) cr/FRACUNIT)*xScale);
|
||||
rcb = cb == 0 ? INT_MAX : ry+h-(((double) cb/FRACUNIT)*yScale);
|
||||
|
||||
// Fix the clipping for fullscreenoffsets.
|
||||
/*if(ry < 0)
|
||||
{
|
||||
if(rcy != 0)
|
||||
rcy = hud_scale ? SCREENHEIGHT + (int) (rcy*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcy;
|
||||
if(rcb != INT_MAX)
|
||||
rcb = hud_scale ? SCREENHEIGHT + (int) (rcb*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcb;
|
||||
}
|
||||
else if(hud_scale)
|
||||
{
|
||||
rcy *= (int) (CleanYfac*200.0/script->resH);
|
||||
if(rcb != INT_MAX)
|
||||
rcb *= (int) (CleanYfac*200.0/script->resH);
|
||||
}
|
||||
if(rx < 0)
|
||||
{
|
||||
if(rcx != 0)
|
||||
rcx = hud_scale ? SCREENWIDTH + (int) (rcx*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcx;
|
||||
if(rcr != INT_MAX)
|
||||
rcr = hud_scale ? SCREENWIDTH + (int) (rcr*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcr;
|
||||
}
|
||||
else if(hud_scale)
|
||||
{
|
||||
rcx *= (int) (CleanXfac*320.0/script->resW);
|
||||
if(rcr != INT_MAX)
|
||||
rcr *= (int) (CleanXfac*320.0/script->resW);
|
||||
}*/
|
||||
}
|
||||
|
||||
if(clearDontDraw)
|
||||
|
@ -1370,8 +1351,8 @@ public:
|
|||
{
|
||||
if(hud_scale)
|
||||
{
|
||||
xScale = (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW;
|
||||
yScale = (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENWIDTH/(double) script->resW;
|
||||
xScale = script->cleanX;
|
||||
yScale = script->cleanY;
|
||||
}
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ struct SBarInfo
|
|||
FMugShot MugShot;
|
||||
int resW;
|
||||
int resH;
|
||||
int cleanX;
|
||||
int cleanY;
|
||||
|
||||
int GetGameType() { return gameType; }
|
||||
void ParseSBarInfo(int lump);
|
||||
|
|
|
@ -61,7 +61,9 @@
|
|||
#define POWERUPICONSIZE 32
|
||||
|
||||
IMPLEMENT_POINTY_CLASS(DBaseStatusBar)
|
||||
DECLARE_POINTER(Messages)
|
||||
DECLARE_POINTER(Messages[0])
|
||||
DECLARE_POINTER(Messages[1])
|
||||
DECLARE_POINTER(Messages[2])
|
||||
END_POINTERS
|
||||
|
||||
EXTERN_CVAR (Bool, am_showmonsters)
|
||||
|
@ -70,7 +72,6 @@ EXTERN_CVAR (Bool, am_showitems)
|
|||
EXTERN_CVAR (Bool, am_showtime)
|
||||
EXTERN_CVAR (Bool, am_showtotaltime)
|
||||
EXTERN_CVAR (Bool, noisedebug)
|
||||
EXTERN_CVAR (Bool, hud_scale)
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
|
||||
DBaseStatusBar *StatusBar;
|
||||
|
@ -216,11 +217,12 @@ void ST_Clear()
|
|||
|
||||
DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres)
|
||||
{
|
||||
CompleteBorder = false;
|
||||
Centering = false;
|
||||
FixedOrigin = false;
|
||||
CrosshairSize = FRACUNIT;
|
||||
RelTop = reltop;
|
||||
Messages = NULL;
|
||||
memset(Messages, 0, sizeof(Messages));
|
||||
Displacement = 0;
|
||||
CPlayer = NULL;
|
||||
ShowLog = false;
|
||||
|
@ -238,16 +240,17 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres)
|
|||
|
||||
void DBaseStatusBar::Destroy ()
|
||||
{
|
||||
DHUDMessage *msg;
|
||||
|
||||
msg = Messages;
|
||||
while (msg)
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
msg->Destroy();
|
||||
msg = next;
|
||||
DHUDMessage *msg = Messages[i];
|
||||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
msg->Destroy();
|
||||
msg = next;
|
||||
}
|
||||
Messages[i] = NULL;
|
||||
}
|
||||
Messages = NULL;
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
|
@ -339,32 +342,35 @@ void DBaseStatusBar::MultiplayerChanged ()
|
|||
|
||||
void DBaseStatusBar::Tick ()
|
||||
{
|
||||
DHUDMessage *msg = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
|
||||
while (msg)
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
DHUDMessage *msg = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
|
||||
if (msg->Tick ())
|
||||
while (msg)
|
||||
{
|
||||
*prev = next;
|
||||
msg->Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &msg->Next;
|
||||
}
|
||||
msg = next;
|
||||
}
|
||||
DHUDMessage *next = msg->Next;
|
||||
|
||||
// If the crosshair has been enlarged, shrink it.
|
||||
if (CrosshairSize > FRACUNIT)
|
||||
{
|
||||
CrosshairSize -= XHAIRSHRINKSIZE;
|
||||
if (CrosshairSize < FRACUNIT)
|
||||
if (msg->Tick ())
|
||||
{
|
||||
*prev = next;
|
||||
msg->Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &msg->Next;
|
||||
}
|
||||
msg = next;
|
||||
}
|
||||
|
||||
// If the crosshair has been enlarged, shrink it.
|
||||
if (CrosshairSize > FRACUNIT)
|
||||
{
|
||||
CrosshairSize = FRACUNIT;
|
||||
CrosshairSize -= XHAIRSHRINKSIZE;
|
||||
if (CrosshairSize < FRACUNIT)
|
||||
{
|
||||
CrosshairSize = FRACUNIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +381,7 @@ void DBaseStatusBar::Tick ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
||||
void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id, int layer)
|
||||
{
|
||||
DHUDMessage *old = NULL;
|
||||
DHUDMessage **prev;
|
||||
|
@ -387,7 +393,13 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
|||
old->Destroy();
|
||||
}
|
||||
|
||||
prev = &Messages;
|
||||
// Merge unknown layers into the default layer.
|
||||
if ((size_t)layer >= countof(Messages))
|
||||
{
|
||||
layer = HUDMSGLayer_Default;
|
||||
}
|
||||
|
||||
prev = &Messages[layer];
|
||||
|
||||
// The ID serves as a priority, where lower numbers appear in front of
|
||||
// higher numbers. (i.e. The list is sorted in descending order, since
|
||||
|
@ -412,48 +424,56 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
|||
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *probe = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
// Redraw the status bar in case it was covered
|
||||
if (screen != NULL)
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
SB_state = screen->GetPageCount();
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
// Redraw the status bar in case it was covered
|
||||
if (screen != NULL)
|
||||
{
|
||||
SB_state = screen->GetPageCount();
|
||||
}
|
||||
return probe;
|
||||
}
|
||||
}
|
||||
return probe;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *probe = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
|
||||
while (probe && probe->SBarID != id)
|
||||
{
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
// Redraw the status bar in case it was covered
|
||||
if (screen != NULL)
|
||||
while (probe && probe->SBarID != id)
|
||||
{
|
||||
SB_state = screen->GetPageCount();
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (probe != NULL)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
probe->Next = NULL;
|
||||
// Redraw the status bar in case it was covered
|
||||
if (screen != NULL)
|
||||
{
|
||||
SB_state = screen->GetPageCount();
|
||||
}
|
||||
return probe;
|
||||
}
|
||||
}
|
||||
return probe;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -464,31 +484,18 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id)
|
|||
|
||||
void DBaseStatusBar::DetachAllMessages ()
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
|
||||
Messages = NULL;
|
||||
while (probe != NULL)
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *next = probe->Next;
|
||||
probe->Destroy();
|
||||
probe = next;
|
||||
}
|
||||
}
|
||||
DHUDMessage *probe = Messages[i];
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC CheckMessage
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool DBaseStatusBar::CheckMessage (DHUDMessage *msg)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
probe = probe->Next;
|
||||
Messages[i] = NULL;
|
||||
while (probe != NULL)
|
||||
{
|
||||
DHUDMessage *next = probe->Next;
|
||||
probe->Destroy();
|
||||
probe = next;
|
||||
}
|
||||
}
|
||||
return (probe == msg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1037,27 +1044,46 @@ void DBaseStatusBar::RefreshBackground () const
|
|||
{
|
||||
int x, x2, y, ratio;
|
||||
|
||||
if (SCREENWIDTH > 320)
|
||||
ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT);
|
||||
x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2);
|
||||
y = x == ST_X && x > 0 ? ST_Y : ::ST_Y;
|
||||
|
||||
if(!CompleteBorder)
|
||||
{
|
||||
ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT);
|
||||
x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2);
|
||||
if (x > 0)
|
||||
if(y < SCREENHEIGHT)
|
||||
{
|
||||
V_DrawBorder (x+1, y, SCREENWIDTH, y+1);
|
||||
V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = SCREENWIDTH;
|
||||
}
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
if(!CompleteBorder)
|
||||
{
|
||||
y = x == ST_X ? ST_Y : ::ST_Y;
|
||||
x2 = !(ratio & 3) || !Scaled ? ST_X+HorizontalResolution :
|
||||
SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2);
|
||||
V_DrawBorder (0, y, x, SCREENHEIGHT);
|
||||
V_DrawBorder (x2, y, SCREENWIDTH, SCREENHEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = SCREENWIDTH;
|
||||
}
|
||||
|
||||
if (setblocks >= 10)
|
||||
{
|
||||
const gameborder_t *border = gameinfo.border;
|
||||
FTexture *p;
|
||||
V_DrawBorder (0, y, x+1, SCREENHEIGHT);
|
||||
V_DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT);
|
||||
|
||||
p = TexMan[border->b];
|
||||
screen->FlatFill(0, y, x, y + p->GetHeight(), p, true);
|
||||
screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true);
|
||||
}
|
||||
if (setblocks >= 10)
|
||||
{
|
||||
const gameborder_t *border = gameinfo.border;
|
||||
FTexture *p;
|
||||
|
||||
p = TexMan[border->b];
|
||||
screen->FlatFill(0, y, x, y + p->GetHeight(), p, true);
|
||||
screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1172,13 +1198,23 @@ void DBaseStatusBar::FlashCrosshair ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::DrawMessages (int bottom)
|
||||
void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
||||
{
|
||||
DHUDMessage *msg = Messages;
|
||||
DHUDMessage *msg = Messages[layer];
|
||||
int visibility = 0;
|
||||
|
||||
if (viewactive)
|
||||
{
|
||||
visibility |= HUDMSG_NotWith3DView;
|
||||
}
|
||||
if (automapactive)
|
||||
{
|
||||
visibility |= viewactive ? HUDMSG_NotWithOverlayMap : HUDMSG_NotWithFullMap;
|
||||
}
|
||||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
msg->Draw (bottom);
|
||||
msg->Draw (bottom, visibility);
|
||||
msg = next;
|
||||
}
|
||||
}
|
||||
|
@ -1426,6 +1462,17 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b
|
|||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DrawBottomStuff
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::DrawBottomStuff (EHudState state)
|
||||
{
|
||||
DrawMessages (HUDMSGLayer_UnderHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DrawTopStuff
|
||||
|
@ -1443,16 +1490,11 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
|
|||
}
|
||||
|
||||
DrawPowerups ();
|
||||
|
||||
if (state == HUD_StatusBar)
|
||||
if (automapactive && !viewactive)
|
||||
{
|
||||
DrawMessages (::ST_Y);
|
||||
DrawMessages (HUDMSGLayer_OverMap, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawMessages (SCREENHEIGHT);
|
||||
}
|
||||
|
||||
DrawMessages (HUDMSGLayer_OverHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT);
|
||||
DrawConsistancy ();
|
||||
if (ShowLog && MustDrawLog(state)) DrawLog ();
|
||||
|
||||
|
@ -1578,7 +1620,18 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
|
|||
|
||||
void DBaseStatusBar::Serialize (FArchive &arc)
|
||||
{
|
||||
arc << Messages;
|
||||
if (SaveVersion < 3821)
|
||||
{
|
||||
memset(Messages, 0, sizeof(Messages));
|
||||
arc << Messages[HUDMSGLayer_Default];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
arc << Messages[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBaseStatusBar::ScreenSizeChanged ()
|
||||
|
@ -1586,11 +1639,14 @@ void DBaseStatusBar::ScreenSizeChanged ()
|
|||
st_scale.Callback ();
|
||||
SB_state = screen->GetPageCount ();
|
||||
|
||||
DHUDMessage *message = Messages;
|
||||
while (message != NULL)
|
||||
for (int i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
message->ScreenSizeChanged ();
|
||||
message = message->Next;
|
||||
DHUDMessage *message = Messages[i];
|
||||
while (message != NULL)
|
||||
{
|
||||
message->ScreenSizeChanged ();
|
||||
message = message->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelRefire)
|
|||
self->target->health <= 0 ||
|
||||
!P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) ||
|
||||
P_HitFriend(self) ||
|
||||
(self->MissileState == NULL && !self->CheckMeleeRange()) ||
|
||||
pr_sentinelrefire() < 40)
|
||||
{
|
||||
self->SetState (self->SeeState);
|
||||
|
|
|
@ -721,7 +721,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropFire)
|
|||
|
||||
AActor *drop = Spawn("FireDroplet", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
|
||||
drop->velz = -FRACUNIT;
|
||||
P_RadiusAttack (self, self, 64, 64, NAME_Fire, false);
|
||||
P_RadiusAttack (self, self, 64, 64, NAME_Fire, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -605,7 +605,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BurnArea)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true);
|
||||
P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode512)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
P_RadiusAttack (self, self->target, 512, 512, NAME_None, true);
|
||||
P_RadiusAttack (self, self->target, 512, 512, NAME_None, RADF_HURTSOURCE);
|
||||
if (self->target != NULL && self->target->player != NULL)
|
||||
{
|
||||
self->target->player->extralight = 5;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "v_palette.h"
|
||||
#include "d_player.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "gstrings.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -60,7 +61,7 @@
|
|||
|
||||
static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]);
|
||||
static void HU_DrawTimeRemaining (int y);
|
||||
static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int);
|
||||
static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int, int);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
|
@ -178,10 +179,11 @@ void HU_DrawScores (player_t *player)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth)
|
||||
void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheight)
|
||||
{
|
||||
maxnamewidth = SmallFont->StringWidth("Name");
|
||||
maxscorewidth = 0;
|
||||
maxiconheight = 0;
|
||||
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
@ -195,11 +197,18 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth)
|
|||
if (players[i].mo->ScoreIcon.isValid())
|
||||
{
|
||||
FTexture *pic = TexMan[players[i].mo->ScoreIcon];
|
||||
width = pic->GetWidth() - pic->GetScaledLeftOffset() + 2;
|
||||
width = pic->GetScaledWidth() - pic->GetScaledLeftOffset() + 2;
|
||||
if (width > maxscorewidth)
|
||||
{
|
||||
maxscorewidth = width;
|
||||
}
|
||||
// The icon's top offset does not count toward its height, because
|
||||
// zdoom.pk3's standard Hexen class icons are designed that way.
|
||||
int height = pic->GetScaledHeight() - pic->GetScaledTopOffset();
|
||||
if (height > maxiconheight)
|
||||
{
|
||||
maxiconheight = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,11 +223,11 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth)
|
|||
static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYERS])
|
||||
{
|
||||
int color;
|
||||
int height = SmallFont->GetHeight() * CleanYfac;
|
||||
int height, lineheight;
|
||||
unsigned int i;
|
||||
int maxnamewidth, maxscorewidth;
|
||||
int maxnamewidth, maxscorewidth, maxiconheight;
|
||||
int numTeams = 0;
|
||||
int x, y, bottom;
|
||||
int x, y, ypadding, bottom;
|
||||
int col2, col3, col4;
|
||||
|
||||
if (deathmatch)
|
||||
|
@ -233,7 +242,10 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
|||
color = sb_cooperative_headingcolor;
|
||||
}
|
||||
|
||||
HU_GetPlayerWidths(maxnamewidth, maxscorewidth);
|
||||
HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight);
|
||||
height = SmallFont->GetHeight() * CleanYfac;
|
||||
lineheight = MAX(height, maxiconheight * CleanYfac);
|
||||
ypadding = (lineheight - height + 1) / 2;
|
||||
|
||||
bottom = gamestate != GS_INTERMISSION ? ST_Y : SCREENHEIGHT;
|
||||
y = MAX(48*CleanYfac, (bottom - MAXPLAYERS * (height + CleanYfac + 1)) / 2);
|
||||
|
@ -299,18 +311,22 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
|||
y += (BigFont->GetHeight() + 8) * CleanYfac;
|
||||
}
|
||||
|
||||
col2 = (SmallFont->StringWidth("Color") + 8) * CleanXfac;
|
||||
col3 = col2 + (SmallFont->StringWidth("Frags") + 8) * CleanXfac;
|
||||
const char *text_color = GStrings("SCORE_COLOR"),
|
||||
*text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"),
|
||||
*text_name = GStrings("SCORE_NAME");
|
||||
|
||||
col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac;
|
||||
col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac;
|
||||
col4 = col3 + maxscorewidth * CleanXfac;
|
||||
x = (SCREENWIDTH >> 1) - ((maxnamewidth * CleanXfac + col4) >> 1);
|
||||
|
||||
screen->DrawText (SmallFont, color, x, y, "Color",
|
||||
screen->DrawText (SmallFont, color, x, y, text_color,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
screen->DrawText (SmallFont, color, x + col2, y, deathmatch ? "Frags" : "Kills",
|
||||
screen->DrawText (SmallFont, color, x + col2, y, text_frags,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
screen->DrawText (SmallFont, color, x + col4, y, "Name",
|
||||
screen->DrawText (SmallFont, color, x + col4, y, text_name,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
y += height + 6 * CleanYfac;
|
||||
|
@ -320,8 +336,8 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
|||
{
|
||||
if (playeringame[sortedplayers[i] - players])
|
||||
{
|
||||
HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, height);
|
||||
y += height + CleanYfac;
|
||||
HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, ypadding, lineheight);
|
||||
y += lineheight + CleanYfac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +381,7 @@ static void HU_DrawTimeRemaining (int y)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int height)
|
||||
static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int ypadding, int height)
|
||||
{
|
||||
int color;
|
||||
char str[80];
|
||||
|
@ -386,7 +402,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
|||
HU_DrawColorBar(col1, y, height, (int)(player - players));
|
||||
mysnprintf (str, countof(str), "%d", deathmatch ? player->fragcount : player->killcount);
|
||||
|
||||
screen->DrawText (SmallFont, color, col2, y, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str,
|
||||
screen->DrawText (SmallFont, color, col2, y + ypadding, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
if (player->mo->ScoreIcon.isValid())
|
||||
|
@ -397,13 +413,13 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
|||
TAG_DONE);
|
||||
}
|
||||
|
||||
screen->DrawText (SmallFont, color, col4, y, player->userinfo.netname,
|
||||
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.netname,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
if (teamplay && Teams[player->userinfo.team].GetLogo ().IsNotEmpty ())
|
||||
{
|
||||
FTexture *pic = TexMan[Teams[player->userinfo.team].GetLogo ().GetChars ()];
|
||||
screen->DrawTexture (pic, col1 - (pic->GetWidth() + 2) * CleanXfac, y,
|
||||
screen->DrawTexture (pic, col1 - (pic->GetScaledWidth() + 2) * CleanXfac, y,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ extern int chatmodeon;
|
|||
// [RH] Draw deathmatch scores
|
||||
|
||||
void HU_DrawScores (player_t *me);
|
||||
void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth);
|
||||
void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheight);
|
||||
void HU_DrawColorBar(int x, int y, int height, int playernum);
|
||||
int HU_GetRowColor(player_t *player, bool hightlight);
|
||||
|
||||
|
|
14
src/info.cpp
14
src/info.cpp
|
@ -56,6 +56,7 @@ extern void InitBotStuff();
|
|||
extern void ClearStrifeTypes();
|
||||
|
||||
TArray<PClassActor *> PClassActor::AllActorClasses;
|
||||
FRandom FState::pr_statetics;
|
||||
|
||||
bool FState::CallAction(AActor *self, AActor *stateowner)
|
||||
{
|
||||
|
@ -505,19 +506,6 @@ void PClassActor::SetPainChance(FName type, int chance)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::SetPainFlash(FName type, PalEntry color)
|
||||
{
|
||||
if (PainFlashes == NULL)
|
||||
PainFlashes = new PainFlashList;
|
||||
|
||||
PainFlashes->Insert(type, color);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DmgFactors :: CheckFactor
|
||||
|
|
20
src/info.h
20
src/info.h
|
@ -47,6 +47,7 @@
|
|||
#include "s_sound.h"
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "m_random.h"
|
||||
|
||||
struct Baggage;
|
||||
class FScanner;
|
||||
|
@ -63,18 +64,19 @@ enum
|
|||
|
||||
struct FState
|
||||
{
|
||||
FState *NextState;
|
||||
VMFunction *ActionFunc;
|
||||
WORD sprite;
|
||||
SWORD Tics;
|
||||
int Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
int Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
WORD TicRange;
|
||||
BYTE Frame;
|
||||
BYTE DefineFlags; // Unused byte so let's use it during state creation.
|
||||
int Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
int Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
short Light;
|
||||
BYTE Fullbright:1; // State is fullbright
|
||||
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
||||
BYTE Fast:1;
|
||||
FState *NextState;
|
||||
VMFunction *ActionFunc;
|
||||
|
||||
inline int GetFrame() const
|
||||
{
|
||||
|
@ -90,7 +92,11 @@ struct FState
|
|||
}
|
||||
inline int GetTics() const
|
||||
{
|
||||
return Tics;
|
||||
if (TicRange == 0)
|
||||
{
|
||||
return Tics;
|
||||
}
|
||||
return Tics + pr_statetics.GenRand32() % (TicRange + 1);
|
||||
}
|
||||
inline int GetMisc1() const
|
||||
{
|
||||
|
@ -112,6 +118,7 @@ struct FState
|
|||
bool CallAction(AActor *self, AActor *stateowner);
|
||||
static PClassActor *StaticFindStateOwner (const FState *state);
|
||||
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);
|
||||
static FRandom pr_statetics;
|
||||
};
|
||||
|
||||
struct FStateLabels;
|
||||
|
@ -143,7 +150,6 @@ struct DmgFactors : public TMap<FName, fixed_t>
|
|||
fixed_t *CheckFactor(FName type);
|
||||
};
|
||||
typedef TMap<FName, int> PainChanceList;
|
||||
typedef TMap<FName, PalEntry> PainFlashList;
|
||||
|
||||
struct DamageTypeDefinition
|
||||
{
|
||||
|
@ -190,7 +196,6 @@ public:
|
|||
void SetPainChance(FName type, int chance);
|
||||
size_t PropagateMark();
|
||||
void InitializeNativeDefaults();
|
||||
void SetPainFlash(FName type, PalEntry color);
|
||||
|
||||
FState *FindState(int numnames, FName *names, bool exact=false) const;
|
||||
FState *FindStateByString(const char *name, bool exact=false);
|
||||
|
@ -217,7 +222,6 @@ public:
|
|||
FStateLabels *StateList;
|
||||
DmgFactors *DamageFactors;
|
||||
PainChanceList *PainChances;
|
||||
PainFlashList *PainFlashes;
|
||||
|
||||
TArray<PClassPlayerPawn *> VisibleToPlayerClass;
|
||||
TArray<PClassPlayerPawn *> RestrictedToPlayerClass;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "d_net.h"
|
||||
#include "d_dehacked.h"
|
||||
#include "gi.h"
|
||||
#include "farchive.h"
|
||||
|
||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||
// writes some bytes to the network data stream, and the network code
|
||||
|
@ -106,6 +107,20 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
msg = GStrings("STSTR_NCOFF");
|
||||
break;
|
||||
|
||||
case CHT_NOCLIP2:
|
||||
player->cheats ^= CF_NOCLIP2;
|
||||
if (player->cheats & CF_NOCLIP2)
|
||||
{
|
||||
player->cheats |= CF_NOCLIP;
|
||||
msg = GStrings("STSTR_NC2ON");
|
||||
}
|
||||
else
|
||||
{
|
||||
player->cheats &= ~CF_NOCLIP;
|
||||
msg = GStrings("STSTR_NCOFF");
|
||||
}
|
||||
break;
|
||||
|
||||
case CHT_NOVELOCITY:
|
||||
player->cheats ^= CF_NOVELOCITY;
|
||||
if (player->cheats & CF_NOVELOCITY)
|
||||
|
@ -504,8 +519,8 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
|
||||
if (player == &players[consoleplayer])
|
||||
Printf ("%s\n", msg);
|
||||
else
|
||||
Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg);
|
||||
else if (cheat != CHT_CHASECAM)
|
||||
Printf ("%s cheats: %s\n", player->userinfo.netname, msg);
|
||||
}
|
||||
|
||||
const char *cht_Morph (player_t *player, PClassPlayerPawn *morphclass, bool quickundo)
|
||||
|
@ -1042,21 +1057,53 @@ void cht_Take (player_t *player, const char *name, int amount)
|
|||
return;
|
||||
}
|
||||
|
||||
class DSuicider : public DThinker
|
||||
{
|
||||
DECLARE_CLASS(DSuicider, DThinker)
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
TObjPtr<APlayerPawn> Pawn;
|
||||
|
||||
void Tick()
|
||||
{
|
||||
Pawn->flags |= MF_SHOOTABLE;
|
||||
Pawn->flags2 &= ~MF2_INVULNERABLE;
|
||||
// Store the player's current damage factor, to restore it later.
|
||||
fixed_t plyrdmgfact = Pawn->DamageFactor;
|
||||
Pawn->DamageFactor = 65536;
|
||||
P_DamageMobj (Pawn, Pawn, Pawn, TELEFRAG_DAMAGE, NAME_Suicide);
|
||||
Pawn->DamageFactor = plyrdmgfact;
|
||||
if (Pawn->health <= 0)
|
||||
{
|
||||
Pawn->flags &= ~MF_SHOOTABLE;
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
// You'll probably never be able to catch this in a save game, but
|
||||
// just in case, add a proper serializer.
|
||||
void Serialize(FArchive &arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
arc << Pawn;
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS(DSuicider)
|
||||
DECLARE_POINTER(Pawn)
|
||||
END_POINTERS
|
||||
|
||||
void cht_Suicide (player_t *plyr)
|
||||
{
|
||||
// If this cheat was initiated by the suicide ccmd, and this is a single
|
||||
// player game, the CHT_SUICIDE will be processed before the tic is run,
|
||||
// so the console has not gone up yet. Use a temporary thinker to delay
|
||||
// the suicide until the game ticks so that death noises can be heard on
|
||||
// the initial tick.
|
||||
if (plyr->mo != NULL)
|
||||
{
|
||||
plyr->mo->flags |= MF_SHOOTABLE;
|
||||
plyr->mo->flags2 &= ~MF2_INVULNERABLE;
|
||||
//Store the players current damage factor, to restore it later.
|
||||
fixed_t plyrdmgfact = plyr->mo->DamageFactor;
|
||||
plyr->mo->DamageFactor = 65536;
|
||||
P_DamageMobj (plyr->mo, plyr->mo, plyr->mo, TELEFRAG_DAMAGE, NAME_Suicide);
|
||||
plyr->mo->DamageFactor = plyrdmgfact;
|
||||
if (plyr->mo->health <= 0)
|
||||
{
|
||||
plyr->mo->flags &= ~MF_SHOOTABLE;
|
||||
}
|
||||
DSuicider *suicide = new DSuicider;
|
||||
suicide->Pawn = plyr->mo;
|
||||
GC::WriteBarrier(suicide, suicide->Pawn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -340,9 +340,41 @@ FString GetUserFile (const char *file)
|
|||
struct stat info;
|
||||
|
||||
path = NicePath("~/" GAME_DIR "/");
|
||||
|
||||
if (stat (path, &info) == -1)
|
||||
{
|
||||
if (mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
||||
struct stat extrainfo;
|
||||
|
||||
// Sanity check for ~/.config
|
||||
FString configPath = NicePath("~/.config/");
|
||||
if (stat (configPath, &extrainfo) == -1)
|
||||
{
|
||||
if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
||||
{
|
||||
I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
else if (!S_ISDIR(extrainfo.st_mode))
|
||||
{
|
||||
I_FatalError ("~/.config must be a directory");
|
||||
}
|
||||
|
||||
// This can be removed after a release or two
|
||||
// Transfer the old zdoom directory to the new location
|
||||
bool moved = false;
|
||||
FString oldpath = NicePath("~/.zdoom/");
|
||||
if (stat (oldpath, &extrainfo) != -1)
|
||||
{
|
||||
if (rename(oldpath, path) == -1)
|
||||
{
|
||||
I_Error ("Failed to move old zdoom directory (%s) to new location (%s).",
|
||||
oldpath.GetChars(), path.GetChars());
|
||||
}
|
||||
else
|
||||
moved = true;
|
||||
}
|
||||
|
||||
if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
|
||||
{
|
||||
I_FatalError ("Failed to create %s directory:\n%s",
|
||||
path.GetChars(), strerror (errno));
|
||||
|
@ -682,7 +714,7 @@ void M_ScreenShot (const char *filename)
|
|||
if (dirlen == 0)
|
||||
{
|
||||
#ifdef unix
|
||||
autoname = "~/.zdoom/screenshots/";
|
||||
autoname = "~/" GAME_DIR "/screenshots/";
|
||||
#elif defined(__APPLE__)
|
||||
char cpath[PATH_MAX];
|
||||
FSRef folder;
|
||||
|
@ -702,7 +734,6 @@ void M_ScreenShot (const char *filename)
|
|||
}
|
||||
else if (dirlen > 0)
|
||||
{
|
||||
autoname = screenshot_dir;
|
||||
if (autoname[dirlen-1] != '/' && autoname[dirlen-1] != '\\')
|
||||
{
|
||||
autoname += '/';
|
||||
|
|
|
@ -139,7 +139,6 @@ struct FOptionMenuSettings
|
|||
EColorRange mFontColorHighlight;
|
||||
EColorRange mFontColorSelection;
|
||||
int mLinespacing;
|
||||
int mLabelOffset;
|
||||
};
|
||||
|
||||
struct FOptionMenuDescriptor : public FMenuDescriptor
|
||||
|
|
|
@ -605,7 +605,7 @@ static void ParseOptionSettings(FScanner &sc)
|
|||
else if (sc.Compare("LabelOffset"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
OptionSettings.mLabelOffset = sc.Number;
|
||||
// ignored
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -214,7 +214,7 @@ void DMessageBoxMenu::Drawer ()
|
|||
{
|
||||
screen->DrawText(ConFont, OptionSettings.mFontColorSelection,
|
||||
(150 - 160) * CleanXfac + screen->GetWidth() / 2,
|
||||
(y + (fontheight + 1) * messageSelection - 100) * CleanYfac + screen->GetHeight() / 2,
|
||||
(y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen->GetHeight() / 2,
|
||||
"\xd",
|
||||
DTA_CellX, 8 * CleanXfac,
|
||||
DTA_CellY, 8 * CleanYfac,
|
||||
|
@ -466,19 +466,7 @@ IMPLEMENT_CLASS(DEndGameMenu)
|
|||
|
||||
DEndGameMenu::DEndGameMenu(bool playsound)
|
||||
{
|
||||
int messageindex = gametic % gameinfo.quitmessages.Size();
|
||||
FString EndString = gameinfo.quitmessages[messageindex];
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
EndString = GStrings("NETEND");
|
||||
return;
|
||||
}
|
||||
|
||||
EndString = GStrings("ENDGAME");
|
||||
|
||||
|
||||
Init(NULL, EndString, 0, playsound);
|
||||
Init(NULL, GStrings(netgame ? "NETEND" : "ENDGAME"), 0, playsound);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -492,7 +480,10 @@ void DEndGameMenu::HandleResult(bool res)
|
|||
if (res)
|
||||
{
|
||||
M_ClearMenus ();
|
||||
D_StartTitle ();
|
||||
if (!netgame)
|
||||
{
|
||||
D_StartTitle ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,8 +58,6 @@
|
|||
|
||||
void M_DrawConText (int color, int x, int y, const char *str)
|
||||
{
|
||||
int len = (int)strlen(str);
|
||||
|
||||
screen->DrawText (ConFont, color, x, y, str,
|
||||
DTA_CellX, 8 * CleanXfac_1,
|
||||
DTA_CellY, 8 * CleanYfac_1,
|
||||
|
@ -400,8 +398,6 @@ void DOptionMenu::Drawer ()
|
|||
}
|
||||
}
|
||||
mDesc->mDrawTop = y;
|
||||
//int labelofs = OptionSettings.mLabelOffset * CleanXfac_1;
|
||||
//int cursorspace = 14 * CleanXfac_1;
|
||||
int fontheight = OptionSettings.mLinespacing * CleanYfac_1;
|
||||
y *= CleanYfac_1;
|
||||
|
||||
|
@ -440,7 +436,7 @@ void DOptionMenu::Drawer ()
|
|||
{
|
||||
if (((DMenu::MenuTime%8) < 6) || DMenu::CurrentMenu != this)
|
||||
{
|
||||
M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y-CleanYfac_1+OptionSettings.mLabelOffset, "\xd");
|
||||
M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,11 +447,11 @@ void DOptionMenu::Drawer ()
|
|||
|
||||
if (CanScrollUp)
|
||||
{
|
||||
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop + OptionSettings.mLabelOffset, "\x1a");
|
||||
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a");
|
||||
}
|
||||
if (CanScrollDown)
|
||||
{
|
||||
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1 + OptionSettings.mLabelOffset, "\x1b");
|
||||
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b");
|
||||
}
|
||||
Super::Drawer();
|
||||
}
|
||||
|
|
|
@ -407,11 +407,11 @@ public:
|
|||
C_NameKeys (description, Key1, Key2);
|
||||
if (description[0])
|
||||
{
|
||||
M_DrawConText(CR_WHITE, indent + CURSORSPACE, y-1+OptionSettings.mLabelOffset, description);
|
||||
M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText(SmallFont, CR_BLACK, indent + CURSORSPACE, y + OptionSettings.mLabelOffset, "---",
|
||||
screen->DrawText(SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---",
|
||||
DTA_CleanNoMove_1, true, TAG_DONE);
|
||||
}
|
||||
return indent;
|
||||
|
@ -569,12 +569,13 @@ public:
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
void DrawSlider (int x, int y, double min, double max, double cur,int fracdigits, int indent)
|
||||
void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent)
|
||||
{
|
||||
char textbuf[16];
|
||||
double range;
|
||||
int maxlen = 0;
|
||||
int right = x + (12*8 + 4) * CleanXfac_1;
|
||||
int cy = y + (OptionSettings.mLinespacing-8)*CleanYfac_1;
|
||||
|
||||
range = max - min;
|
||||
double ccur = clamp(cur, min, max) - min;
|
||||
|
@ -589,14 +590,14 @@ public:
|
|||
|
||||
if (!mSliderShort)
|
||||
{
|
||||
M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
|
||||
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), y, "\x13");
|
||||
M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
|
||||
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13");
|
||||
}
|
||||
else
|
||||
{
|
||||
// On 320x200 we need a shorter slider
|
||||
M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x12");
|
||||
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), y, "\x13");
|
||||
M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12");
|
||||
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13");
|
||||
right -= 5*8*CleanXfac_1;
|
||||
}
|
||||
|
||||
|
@ -613,7 +614,7 @@ public:
|
|||
{
|
||||
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
|
||||
mDrawX = indent + CURSORSPACE;
|
||||
DrawSlider (mDrawX, y + OptionSettings.mLabelOffset, mMin, mMax, GetValue(), mShowValue, indent);
|
||||
DrawSlider (mDrawX, y, mMin, mMax, GetValue(), mShowValue, indent);
|
||||
return indent;
|
||||
}
|
||||
|
||||
|
@ -777,8 +778,8 @@ public:
|
|||
if (mCVar != NULL)
|
||||
{
|
||||
int box_x = indent + CURSORSPACE;
|
||||
int box_y = y + OptionSettings.mLabelOffset * CleanYfac_1 / 2;
|
||||
screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + (SmallFont->GetHeight() - 1) * CleanYfac_1,
|
||||
int box_y = y + CleanYfac_1;
|
||||
screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + OptionSettings.mLinespacing*CleanYfac_1,
|
||||
-1, (uint32)*mCVar | 0xff000000);
|
||||
}
|
||||
return indent;
|
||||
|
|
|
@ -590,8 +590,8 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected)
|
|||
if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS);
|
||||
screen->DrawTexture (tex,
|
||||
x + 36*CleanXfac, y + 71*CleanYfac,
|
||||
DTA_DestWidth, MulScale16 (tex->GetWidth() * CleanXfac, scaleX),
|
||||
DTA_DestHeight, MulScale16 (tex->GetHeight() * CleanYfac, scaleY),
|
||||
DTA_DestWidth, MulScale16 (tex->GetScaledWidth() * CleanXfac, scaleX),
|
||||
DTA_DestHeight, MulScale16 (tex->GetScaledHeight() * CleanYfac, scaleY),
|
||||
DTA_Translation, trans,
|
||||
DTA_FlipX, sprframe->Flip & (1 << mRotation),
|
||||
TAG_DONE);
|
||||
|
|
|
@ -99,7 +99,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE)
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Bool, vid_tft, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
FOptionMenuDescriptor *opt = GetVideoModeMenu();
|
||||
if (opt != NULL)
|
||||
|
@ -316,6 +316,7 @@ void M_InitVideoModesMenu ()
|
|||
size_t currval = 0;
|
||||
|
||||
M_RefreshModesList();
|
||||
vid_tft.Callback();
|
||||
|
||||
for (unsigned int i = 1; i <= 32 && currval < countof(BitTranslate); i++)
|
||||
{
|
||||
|
|
112
src/p_acs.cpp
112
src/p_acs.cpp
|
@ -86,10 +86,24 @@ FRandom pr_acs ("ACS");
|
|||
#define STACK_SIZE 4096
|
||||
|
||||
#define CLAMPCOLOR(c) (EColorRange)((unsigned)(c) >= NUM_TEXT_COLORS ? CR_UNTRANSLATED : (c))
|
||||
#define HUDMSG_LOG (0x80000000)
|
||||
#define HUDMSG_COLORSTRING (0x40000000)
|
||||
#define LANGREGIONMASK MAKE_ID(0,0,0xff,0xff)
|
||||
|
||||
// HUD message flags
|
||||
#define HUDMSG_LOG (0x80000000)
|
||||
#define HUDMSG_COLORSTRING (0x40000000)
|
||||
#define HUDMSG_ADDBLEND (0x20000000)
|
||||
#define HUDMSG_ALPHA (0x10000000)
|
||||
|
||||
// HUD message layers; these are not flags
|
||||
#define HUDMSG_LAYER_SHIFT 12
|
||||
#define HUDMSG_LAYER_MASK (0x0000F000)
|
||||
// See HUDMSGLayer enumerations in sbar.h
|
||||
|
||||
// HUD message visibility flags
|
||||
#define HUDMSG_VISIBILITY_SHIFT 16
|
||||
#define HUDMSG_VISIBILITY_MASK (0x00070000)
|
||||
// See HUDMSG visibility enumerations in sbar.h
|
||||
|
||||
// Flags for ReplaceTextures
|
||||
#define NOT_BOTTOM 1
|
||||
#define NOT_MIDDLE 2
|
||||
|
@ -99,13 +113,12 @@ FRandom pr_acs ("ACS");
|
|||
|
||||
struct CallReturn
|
||||
{
|
||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, FString &str)
|
||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard)
|
||||
: ReturnFunction(func),
|
||||
ReturnModule(module),
|
||||
ReturnLocals(locals),
|
||||
ReturnAddress(pc),
|
||||
bDiscardResult(discard),
|
||||
StringBuilder(str)
|
||||
bDiscardResult(discard)
|
||||
{}
|
||||
|
||||
ScriptFunction *ReturnFunction;
|
||||
|
@ -113,7 +126,6 @@ struct CallReturn
|
|||
SDWORD *ReturnLocals;
|
||||
int ReturnAddress;
|
||||
int bDiscardResult;
|
||||
FString StringBuilder;
|
||||
};
|
||||
|
||||
static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
|
||||
|
@ -157,8 +169,8 @@ TArray<FString>
|
|||
ACS_StringsOnTheFly,
|
||||
ACS_StringBuilderStack;
|
||||
|
||||
#define STRINGBUILDER_START(Builder) if (*Builder.GetChars() || ACS_StringBuilderStack.Size()) { ACS_StringBuilderStack.Push(Builder); Builder = ""; }
|
||||
#define STRINGBUILDER_FINISH(Builder) if (!ACS_StringBuilderStack.Pop(Builder)) Builder = "";
|
||||
#define STRINGBUILDER_START(Builder) if (Builder.IsNotEmpty() || ACS_StringBuilderStack.Size()) { ACS_StringBuilderStack.Push(Builder); Builder = ""; }
|
||||
#define STRINGBUILDER_FINISH(Builder) if (!ACS_StringBuilderStack.Pop(Builder)) { Builder = ""; }
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
@ -3362,6 +3374,11 @@ enum EACSFunctions
|
|||
ACSF_ACS_NamedLockedExecuteDoor,
|
||||
ACSF_ACS_NamedExecuteWithResult,
|
||||
ACSF_ACS_NamedExecuteAlways,
|
||||
ACSF_UniqueTID,
|
||||
ACSF_IsTIDUsed,
|
||||
ACSF_Sqrt,
|
||||
ACSF_FixedSqrt,
|
||||
ACSF_VectorLength,
|
||||
|
||||
// ZDaemon
|
||||
ACSF_GetTeamScore = 19620,
|
||||
|
@ -3874,6 +3891,23 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
}
|
||||
break;
|
||||
|
||||
case ACSF_UniqueTID:
|
||||
return P_FindUniqueTID(argCount > 0 ? args[0] : 0, argCount > 1 ? args[1] : 0);
|
||||
break;
|
||||
|
||||
case ACSF_IsTIDUsed:
|
||||
return P_IsTIDUsed(args[0]);
|
||||
break;
|
||||
|
||||
case ACSF_Sqrt:
|
||||
return xs_FloorToInt(sqrt(double(args[0])));
|
||||
|
||||
case ACSF_FixedSqrt:
|
||||
return FLOAT2FIXED(sqrt(FIXED2DBL(args[0])));
|
||||
|
||||
case ACSF_VectorLength:
|
||||
return FLOAT2FIXED(TVector2<double>(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length());
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4295,7 +4329,7 @@ int DLevelScript::RunScript ()
|
|||
}
|
||||
sp += i;
|
||||
::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction,
|
||||
activeBehavior, mylocals, pcd == PCD_CALLDISCARD, work);
|
||||
activeBehavior, mylocals, pcd == PCD_CALLDISCARD);
|
||||
sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int);
|
||||
pc = module->Ofs2PC (func->Address);
|
||||
activeFunction = func;
|
||||
|
@ -4334,7 +4368,6 @@ int DLevelScript::RunScript ()
|
|||
{
|
||||
Stack[sp++] = value;
|
||||
}
|
||||
work = ret->StringBuilder;
|
||||
ret->~CallReturn();
|
||||
}
|
||||
break;
|
||||
|
@ -5655,6 +5688,7 @@ scriptwait:
|
|||
float x = FIXED2FLOAT(Stack[optstart-3]);
|
||||
float y = FIXED2FLOAT(Stack[optstart-2]);
|
||||
float holdTime = FIXED2FLOAT(Stack[optstart-1]);
|
||||
fixed_t alpha;
|
||||
DHUDMessage *msg;
|
||||
|
||||
if (type & HUDMSG_COLORSTRING)
|
||||
|
@ -5666,14 +5700,16 @@ scriptwait:
|
|||
color = CLAMPCOLOR(Stack[optstart-4]);
|
||||
}
|
||||
|
||||
switch (type & 0xFFFF)
|
||||
switch (type & 0xFF)
|
||||
{
|
||||
default: // normal
|
||||
alpha = (optstart < sp) ? Stack[optstart] : FRACUNIT;
|
||||
msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime);
|
||||
break;
|
||||
case 1: // fade out
|
||||
{
|
||||
float fadeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f;
|
||||
alpha = (optstart < sp-1) ? Stack[optstart+1] : FRACUNIT;
|
||||
msg = new DHUDMessageFadeOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime);
|
||||
}
|
||||
break;
|
||||
|
@ -5681,6 +5717,7 @@ scriptwait:
|
|||
{
|
||||
float typeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.05f;
|
||||
float fadeTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f;
|
||||
alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT;
|
||||
msg = new DHUDMessageTypeOnFadeOut (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime);
|
||||
}
|
||||
break;
|
||||
|
@ -5688,11 +5725,22 @@ scriptwait:
|
|||
{
|
||||
float inTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f;
|
||||
float outTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f;
|
||||
alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT;
|
||||
msg = new DHUDMessageFadeInOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime);
|
||||
}
|
||||
break;
|
||||
}
|
||||
StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0);
|
||||
msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT);
|
||||
if (type & HUDMSG_ALPHA)
|
||||
{
|
||||
msg->SetAlpha(alpha);
|
||||
}
|
||||
if (type & HUDMSG_ADDBLEND)
|
||||
{
|
||||
msg->SetRenderStyle(STYLE_Add);
|
||||
}
|
||||
StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0,
|
||||
(type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT);
|
||||
if (type & HUDMSG_LOG)
|
||||
{
|
||||
static const char bar[] = TEXTCOLOR_ORANGE "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
||||
|
@ -6340,7 +6388,18 @@ scriptwait:
|
|||
case PCD_GETACTORZ:
|
||||
{
|
||||
AActor *actor = SingleActorFromTID(STACK(1), activator);
|
||||
STACK(1) = actor == NULL ? 0 : (&actor->x)[pcd - PCD_GETACTORX];
|
||||
if (actor == NULL)
|
||||
{
|
||||
STACK(1) = 0;
|
||||
}
|
||||
else if (pcd == PCD_GETACTORZ)
|
||||
{
|
||||
STACK(1) = actor->z + actor->GetBobOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
STACK(1) = (&actor->x)[pcd - PCD_GETACTORX];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6482,6 +6541,25 @@ scriptwait:
|
|||
}
|
||||
break;
|
||||
|
||||
case PCD_TRANSLATIONRANGE3:
|
||||
{ // translation using desaturation
|
||||
int start = STACK(8);
|
||||
int end = STACK(7);
|
||||
fixed_t r1 = STACK(6);
|
||||
fixed_t g1 = STACK(5);
|
||||
fixed_t b1 = STACK(4);
|
||||
fixed_t r2 = STACK(3);
|
||||
fixed_t g2 = STACK(2);
|
||||
fixed_t b2 = STACK(1);
|
||||
sp -= 8;
|
||||
|
||||
if (translation != NULL)
|
||||
translation->AddDesaturation(start, end,
|
||||
FIXED2DBL(r1), FIXED2DBL(g1), FIXED2DBL(b1),
|
||||
FIXED2DBL(r2), FIXED2DBL(g2), FIXED2DBL(b2));
|
||||
}
|
||||
break;
|
||||
|
||||
case PCD_ENDTRANSLATION:
|
||||
// This might be useful for hardware rendering, but
|
||||
// for software it is superfluous.
|
||||
|
@ -6886,7 +6964,8 @@ scriptwait:
|
|||
}
|
||||
else
|
||||
{
|
||||
userinfo_t *userinfo = &players[STACK(2)].userinfo;
|
||||
player_t *pl = &players[STACK(2)];
|
||||
userinfo_t *userinfo = &pl->userinfo;
|
||||
switch (STACK(1))
|
||||
{
|
||||
case PLAYERINFO_TEAM: STACK(2) = userinfo->team; break;
|
||||
|
@ -6897,6 +6976,8 @@ scriptwait:
|
|||
case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->MoveBob; break;
|
||||
case PLAYERINFO_STILLBOB: STACK(2) = userinfo->StillBob; break;
|
||||
case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->PlayerClass; break;
|
||||
case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break;
|
||||
case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break;
|
||||
default: STACK(2) = 0; break;
|
||||
}
|
||||
}
|
||||
|
@ -7519,6 +7600,3 @@ void DACSThinker::DumpScriptStatus ()
|
|||
script = script->next;
|
||||
}
|
||||
}
|
||||
|
||||
#undef STRINGBUILDER_START
|
||||
#undef STRINGBUILDER_FINISH
|
||||
|
|
|
@ -601,8 +601,9 @@ public:
|
|||
PCD_PUSHFUNCTION, // from Eternity
|
||||
/*360*/ PCD_CALLSTACK, // from Eternity
|
||||
PCD_SCRIPTWAITNAMED,
|
||||
PCD_TRANSLATIONRANGE3,
|
||||
|
||||
/*361*/ PCODE_COMMAND_COUNT
|
||||
/*363*/ PCODE_COMMAND_COUNT
|
||||
};
|
||||
|
||||
// Some constants used by ACS scripts
|
||||
|
@ -664,7 +665,9 @@ public:
|
|||
PLAYERINFO_NEVERSWITCH,
|
||||
PLAYERINFO_MOVEBOB,
|
||||
PLAYERINFO_STILLBOB,
|
||||
PLAYERINFO_PLAYERCLASS
|
||||
PLAYERINFO_PLAYERCLASS,
|
||||
PLAYERINFO_FOV,
|
||||
PLAYERINFO_DESIREDFOV,
|
||||
};
|
||||
|
||||
enum EScriptState
|
||||
|
|
|
@ -926,7 +926,6 @@ public:
|
|||
const char *speakerName;
|
||||
int x, y, linesize;
|
||||
int width, fontheight;
|
||||
int labelofs;
|
||||
|
||||
player_t *cp = &players[consoleplayer];
|
||||
|
||||
|
@ -1015,8 +1014,6 @@ public:
|
|||
}
|
||||
|
||||
y = mYpos;
|
||||
labelofs = OptionSettings.mLabelOffset;
|
||||
y -= labelofs;
|
||||
fontheight = OptionSettings.mLinespacing;
|
||||
|
||||
int response = 0;
|
||||
|
@ -1041,7 +1038,7 @@ public:
|
|||
int color = ((DMenu::MenuTime%8) < 4) || DMenu::CurrentMenu != this ? CR_RED:CR_GREY;
|
||||
|
||||
x = (50 + 3 - 160) * CleanXfac + screen->GetWidth() / 2;
|
||||
int yy = (y-1+labelofs - 100) * CleanYfac + screen->GetHeight() / 2;
|
||||
int yy = (y + fontheight/2 - 5 - 100) * CleanYfac + screen->GetHeight() / 2;
|
||||
screen->DrawText (ConFont, color, x, yy, "\xd",
|
||||
DTA_CellX, 8 * CleanXfac,
|
||||
DTA_CellY, 8 * CleanYfac,
|
||||
|
|
|
@ -1670,7 +1670,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
|
|||
|
||||
// [RC] Well, let's let special monsters with this flag active be able to see
|
||||
// the player then, eh?
|
||||
if(!(actor->flags & MF6_SEEINVISIBLE))
|
||||
if(!(actor->flags6 & MF6_SEEINVISIBLE))
|
||||
{
|
||||
if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) ||
|
||||
player->mo->flags3 & MF3_GHOST)
|
||||
|
@ -3210,7 +3210,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Detonate)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
int damage = self->GetMissileDamage(0, 1);
|
||||
P_RadiusAttack (self, self->target, damage, damage, self->DamageType, true);
|
||||
P_RadiusAttack (self, self->target, damage, damage, self->DamageType, RADF_HURTSOURCE);
|
||||
P_CheckSplash(self, damage<<FRACBITS);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1088,7 +1088,7 @@ static FString GetCachePath()
|
|||
path += "/zdoom/cache";
|
||||
#else
|
||||
// Don't use GAME_DIR and such so that ZDoom and its child ports can share the node cache.
|
||||
path = NicePath("~/.zdoom/cache");
|
||||
path = NicePath("~/.config/zdoom/cache");
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,9 @@ void P_TouchSpecialThing (AActor *special, AActor *toucher)
|
|||
{
|
||||
fixed_t delta = special->z - toucher->z;
|
||||
|
||||
if (delta > toucher->height || delta < -32*FRACUNIT)
|
||||
// The pickup is at or above the toucher's feet OR
|
||||
// The pickup is below the toucher.
|
||||
if (delta > toucher->height || delta < MIN(-32*FRACUNIT, -special->height))
|
||||
{ // out of reach
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -483,8 +483,15 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner);
|
|||
void P_AimCamera (AActor *t1, fixed_t &x, fixed_t &y, fixed_t &z, sector_t *&sec);
|
||||
|
||||
// [RH] Means of death
|
||||
enum
|
||||
{
|
||||
RADF_HURTSOURCE = 1,
|
||||
RADF_NOIMPACTDAMAGE = 2,
|
||||
RADF_SOURCEISSPOT = 4,
|
||||
RADF_NODAMAGE = 8,
|
||||
};
|
||||
void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
|
||||
FName damageType, bool hurtSelf, bool dodamage=true, int fulldamagedistance=0, bool noimpactdamage=false);
|
||||
FName damageType, int flags, int fulldamagedistance=0);
|
||||
|
||||
void P_DelSector_List();
|
||||
void P_DelSeclist(msecnode_t *); // phares 3/16/98
|
||||
|
|
|
@ -501,7 +501,11 @@ int P_GetFriction (const AActor *mo, int *frictionfactor)
|
|||
const msecnode_t *m;
|
||||
const sector_t *sec;
|
||||
|
||||
if (mo->flags2 & MF2_FLY && mo->flags & MF_NOGRAVITY)
|
||||
if (mo->IsNoClip2())
|
||||
{
|
||||
// The default values are fine for noclip2 mode
|
||||
}
|
||||
else if (mo->flags2 & MF2_FLY && mo->flags & MF_NOGRAVITY)
|
||||
{
|
||||
friction = FRICTION_FLY;
|
||||
}
|
||||
|
@ -938,8 +942,11 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
|| ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE))
|
||||
) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away
|
||||
{
|
||||
if (P_ActivateThingSpecial(thing, tm.thing))
|
||||
thing->lastbump = level.maptime + TICRATE;
|
||||
if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING))
|
||||
{
|
||||
if (P_ActivateThingSpecial(thing, tm.thing))
|
||||
thing->lastbump = level.maptime + TICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for skulls slamming into things
|
||||
|
@ -1298,7 +1305,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b
|
|||
|
||||
#ifdef _3DFLOORS
|
||||
//Check 3D floors
|
||||
if(newsec->e->XFloor.ffloors.Size())
|
||||
if (!thing->IsNoClip2() && newsec->e->XFloor.ffloors.Size())
|
||||
{
|
||||
F3DFloor* rover;
|
||||
fixed_t delta1;
|
||||
|
@ -1605,7 +1612,7 @@ void P_FakeZMovement (AActor *mo)
|
|||
mo->z += mo->FloatSpeed;
|
||||
}
|
||||
}
|
||||
if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz))
|
||||
if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz) && !mo->IsNoClip2())
|
||||
{
|
||||
mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8;
|
||||
}
|
||||
|
@ -4440,7 +4447,7 @@ CUSTOM_CVAR (Float, splashfactor, 1.f, CVAR_SERVERINFO)
|
|||
//==========================================================================
|
||||
|
||||
void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int bombdistance, FName bombmod,
|
||||
bool DamageSource, bool bombdodamage, int fulldamagedistance, bool noimpactdamage)
|
||||
int flags, int fulldamagedistance)
|
||||
{
|
||||
if (bombdistance <= 0)
|
||||
return;
|
||||
|
@ -4454,6 +4461,11 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
FBlockThingsIterator it(FBoundingBox(bombspot->x, bombspot->y, bombdistance<<FRACBITS));
|
||||
AActor *thing;
|
||||
|
||||
if (flags & RADF_SOURCEISSPOT)
|
||||
{ // The source is actually the same as the spot, even if that wasn't what we receized.
|
||||
bombsource = bombspot;
|
||||
}
|
||||
|
||||
while ((thing = it.Next()))
|
||||
{
|
||||
// Vulnerable actors can be damaged by radius attacks even if not shootable
|
||||
|
@ -4466,7 +4478,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
if (thing->flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG))
|
||||
continue;
|
||||
|
||||
if (!DamageSource && (thing == bombsource || thing == bombspot))
|
||||
if (!(flags & RADF_HURTSOURCE) && (thing == bombsource || thing == bombspot))
|
||||
{ // don't damage the source of the explosion
|
||||
continue;
|
||||
}
|
||||
|
@ -4486,7 +4498,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
// them far too "active." BossBrains also use the old code
|
||||
// because some user levels require they have a height of 16,
|
||||
// which can make them near impossible to hit with the new code.
|
||||
if (!bombdodamage || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG))
|
||||
if ((flags & RADF_NODAMAGE) || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG))
|
||||
{
|
||||
// [RH] New code. The bounding box only covers the
|
||||
// height of the thing and not the height of the map.
|
||||
|
@ -4545,14 +4557,17 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
double thrust;
|
||||
int damage = (int)points;
|
||||
|
||||
if (bombdodamage) P_DamageMobj (thing, bombspot, bombsource, damage, bombmod);
|
||||
else if (thing->player == NULL && !noimpactdamage) thing->flags2 |= MF2_BLASTED;
|
||||
if (!(flags & RADF_NODAMAGE))
|
||||
P_DamageMobj (thing, bombspot, bombsource, damage, bombmod);
|
||||
else if (thing->player == NULL && !(flags & RADF_NOIMPACTDAMAGE))
|
||||
thing->flags2 |= MF2_BLASTED;
|
||||
|
||||
if (!(thing->flags & MF_ICECORPSE))
|
||||
{
|
||||
if (bombdodamage && !(bombspot->flags3 & MF3_BLOODLESSIMPACT)) P_TraceBleed (damage, thing, bombspot);
|
||||
if (!(flags & RADF_NODAMAGE) && !(bombspot->flags3 & MF3_BLOODLESSIMPACT))
|
||||
P_TraceBleed (damage, thing, bombspot);
|
||||
|
||||
if (!bombdodamage || !(bombspot->flags2 & MF2_NODMGTHRUST))
|
||||
if (!(flags & RADF_NODAMAGE) || !(bombspot->flags2 & MF2_NODMGTHRUST))
|
||||
{
|
||||
if (bombsource == NULL || !(bombsource->flags2 & MF2_NODMGTHRUST))
|
||||
{
|
||||
|
@ -4573,7 +4588,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
angle_t ang = R_PointToAngle2 (bombspot->x, bombspot->y, thing->x, thing->y) >> ANGLETOFINESHIFT;
|
||||
thing->velx += fixed_t (finecosine[ang] * thrust);
|
||||
thing->vely += fixed_t (finesine[ang] * thrust);
|
||||
if (bombdodamage)
|
||||
if (!(flags & RADF_NODAMAGE))
|
||||
thing->velz += (fixed_t)velz; // this really doesn't work well
|
||||
}
|
||||
}
|
||||
|
|
157
src/p_mobj.cpp
157
src/p_mobj.cpp
|
@ -37,6 +37,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "v_video.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "b_bot.h" //Added by MC:
|
||||
#include "stats.h"
|
||||
#include "a_hexenglobal.h"
|
||||
|
@ -107,6 +108,7 @@ static FRandom pr_missiledamage ("MissileDamage");
|
|||
FRandom pr_slam ("SkullSlam");
|
||||
static FRandom pr_multiclasschoice ("MultiClassChoice");
|
||||
static FRandom pr_rockettrail("RocketTrail");
|
||||
static FRandom pr_uniquetid("UniqueTID");
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
|
@ -1158,6 +1160,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
|
|||
}
|
||||
mo->velx = mo->vely = mo->velz = 0;
|
||||
mo->effects = 0; // [RH]
|
||||
mo->flags &= ~MF_SHOOTABLE;
|
||||
|
||||
FState *nextstate=NULL;
|
||||
|
||||
|
@ -1983,7 +1986,9 @@ explode:
|
|||
}
|
||||
|
||||
if (mo->z > mo->floorz && !(mo->flags2 & MF2_ONMOBJ) &&
|
||||
(!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) && !mo->waterlevel)
|
||||
!mo->IsNoClip2() &&
|
||||
(!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) &&
|
||||
!mo->waterlevel)
|
||||
{ // [RH] Friction when falling is available for larger aircontrols
|
||||
if (player != NULL && level.airfriction != FRACUNIT)
|
||||
{
|
||||
|
@ -2226,7 +2231,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
|||
}
|
||||
if (mo->player && (mo->flags & MF_NOGRAVITY) && (mo->z > mo->floorz))
|
||||
{
|
||||
mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8;
|
||||
if (!mo->IsNoClip2())
|
||||
{
|
||||
mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8;
|
||||
}
|
||||
mo->velz = FixedMul (mo->velz, FRICTION_FLY);
|
||||
}
|
||||
if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY))
|
||||
|
@ -2474,7 +2482,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj)
|
|||
{
|
||||
grunted = false;
|
||||
// Why should this number vary by gravity?
|
||||
if (mo->velz < (fixed_t)(800.f /*level.gravity * mo->Sector->gravity*/ * -983.04f) && mo->health > 0)
|
||||
if (mo->health > 0 && mo->velz < -mo->player->mo->GruntSpeed)
|
||||
{
|
||||
S_Sound (mo, CHAN_VOICE, "*grunt", 1, ATTN_NORM);
|
||||
grunted = true;
|
||||
|
@ -2613,10 +2621,7 @@ AActor *AActor::TIDHash[128];
|
|||
|
||||
void AActor::ClearTIDHashes ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
TIDHash[i] = NULL;
|
||||
memset(TIDHash, NULL, sizeof(TIDHash));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2667,6 +2672,92 @@ void AActor::RemoveFromHash ()
|
|||
tid = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_IsTIDUsed
|
||||
//
|
||||
// Returns true if there is at least one actor with the specified TID
|
||||
// (dead or alive).
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool P_IsTIDUsed(int tid)
|
||||
{
|
||||
AActor *probe = AActor::TIDHash[tid & 127];
|
||||
while (probe != NULL)
|
||||
{
|
||||
if (probe->tid == tid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
probe = probe->inext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_FindUniqueTID
|
||||
//
|
||||
// Returns an unused TID. If start_tid is 0, then a random TID will be
|
||||
// chosen. Otherwise, it will perform a linear search starting from
|
||||
// start_tid. If limit is non-0, then it will not check more than <limit>
|
||||
// number of TIDs. Returns 0 if no suitable TID was found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int P_FindUniqueTID(int start_tid, int limit)
|
||||
{
|
||||
int tid;
|
||||
|
||||
if (start_tid != 0)
|
||||
{ // Do a linear search.
|
||||
limit = start_tid + limit - 1;
|
||||
if (limit < start_tid)
|
||||
{ // If it overflowed, clamp to INT_MAX
|
||||
limit = INT_MAX;
|
||||
}
|
||||
for (tid = start_tid; tid <= limit; ++tid)
|
||||
{
|
||||
if (tid != 0 && !P_IsTIDUsed(tid))
|
||||
{
|
||||
return tid;
|
||||
}
|
||||
}
|
||||
// Nothing free found.
|
||||
return 0;
|
||||
}
|
||||
// Do a random search. To try and be a bit more performant, this
|
||||
// actually does several linear searches. In the case of *very*
|
||||
// dense TID usage, this could potentially perform worse than doing
|
||||
// a complete linear scan starting at 1. However, you would need
|
||||
// to use an absolutely ridiculous number of actors before this
|
||||
// becomes a real concern.
|
||||
if (limit == 0)
|
||||
{
|
||||
limit = INT_MAX;
|
||||
}
|
||||
for (int i = 0; i < limit; i += 5)
|
||||
{
|
||||
// Use a positive starting TID.
|
||||
tid = pr_uniquetid.GenRand32() & INT_MAX;
|
||||
tid = P_FindUniqueTID(tid == 0 ? 1 : tid, 5);
|
||||
if (tid != 0)
|
||||
{
|
||||
return tid;
|
||||
}
|
||||
}
|
||||
// Nothing free found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
CCMD(utid)
|
||||
{
|
||||
Printf("%d\n",
|
||||
P_FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
|
||||
argv.argc() > 2 ? atoi(argv[2]) : 0));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor :: GetMissileDamage
|
||||
|
@ -3363,8 +3454,11 @@ void AActor::Tick ()
|
|||
|| ((onmo->activationtype & THINGSPEC_MissileTrigger) && (flags & MF_MISSILE))
|
||||
) && (level.maptime > onmo->lastbump)) // Leave the bumper enough time to go away
|
||||
{
|
||||
if (P_ActivateThingSpecial(onmo, this))
|
||||
onmo->lastbump = level.maptime + TICRATE;
|
||||
if (player == NULL || !(player->cheats & CF_PREDICTING))
|
||||
{
|
||||
if (P_ActivateThingSpecial(onmo, this))
|
||||
onmo->lastbump = level.maptime + TICRATE;
|
||||
}
|
||||
}
|
||||
if (velz != 0 && (BounceFlags & BOUNCE_Actors))
|
||||
{
|
||||
|
@ -3902,6 +3996,19 @@ void AActor::PostBeginPlay ()
|
|||
PrevAngle = angle;
|
||||
}
|
||||
|
||||
void AActor::MarkPrecacheSounds() const
|
||||
{
|
||||
SeeSound.MarkUsed();
|
||||
AttackSound.MarkUsed();
|
||||
PainSound.MarkUsed();
|
||||
DeathSound.MarkUsed();
|
||||
ActiveSound.MarkUsed();
|
||||
UseSound.MarkUsed();
|
||||
BounceSound.MarkUsed();
|
||||
WallBounceSound.MarkUsed();
|
||||
CrushPainSound.MarkUsed();
|
||||
}
|
||||
|
||||
bool AActor::isFast()
|
||||
{
|
||||
if (flags5&MF5_ALWAYSFAST) return true;
|
||||
|
@ -4734,13 +4841,16 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
|
|||
// Moved out of the blood actor so that replacing blood is easier
|
||||
if (gameinfo.gametype & GAME_DoomStrifeChex)
|
||||
{
|
||||
FState *state = th->FindState(NAME_Spray);
|
||||
if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
if (damage > 13)
|
||||
{
|
||||
FState *state = th->FindState(NAME_Spray);
|
||||
if (state != NULL) th->SetState (state);
|
||||
if (state != NULL)
|
||||
{
|
||||
th->SetState (state);
|
||||
goto statedone;
|
||||
}
|
||||
}
|
||||
else damage += 2;
|
||||
}
|
||||
|
@ -4758,14 +4868,15 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
|
|||
|
||||
while (cls != RUNTIME_CLASS(AActor))
|
||||
{
|
||||
int checked_advance = advance;
|
||||
if (cls->OwnsState(th->SpawnState))
|
||||
{
|
||||
for (; advance > 0; --advance)
|
||||
for (; checked_advance > 0; --checked_advance)
|
||||
{
|
||||
// [RH] Do not set to a state we do not own.
|
||||
if (!cls->OwnsState(th->SpawnState + advance))
|
||||
if (cls->OwnsState(th->SpawnState + checked_advance))
|
||||
{
|
||||
th->SetState(th->SpawnState + advance);
|
||||
th->SetState(th->SpawnState + checked_advance);
|
||||
goto statedone;
|
||||
}
|
||||
}
|
||||
|
@ -5295,7 +5406,7 @@ static fixed_t GetDefaultSpeed(PClassActor *type)
|
|||
|
||||
AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor *owner)
|
||||
{
|
||||
return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT,
|
||||
return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT + source->GetBobOffset(),
|
||||
source, dest, type, true, owner);
|
||||
}
|
||||
|
||||
|
@ -5417,7 +5528,7 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct
|
|||
AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type,
|
||||
angle_t angle, fixed_t velz)
|
||||
{
|
||||
return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT,
|
||||
return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(),
|
||||
type, angle, velz, GetDefaultSpeed (type));
|
||||
}
|
||||
|
||||
|
@ -5460,7 +5571,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct
|
|||
AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type,
|
||||
angle_t angle, fixed_t velz, fixed_t speed)
|
||||
{
|
||||
return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT,
|
||||
return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(),
|
||||
type, angle, velz, speed);
|
||||
}
|
||||
|
||||
|
@ -5985,25 +6096,25 @@ void PrintMiscActorInfo(AActor *query)
|
|||
Printf("\n\tflags6: %x", query->flags6);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags6 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags6));
|
||||
Printf("\nIts bounce style and factors are %x and f:%f, w:%f; its bounce flags are:\n\tflagsb: %x",
|
||||
Printf("\nBounce style: %x\nBounce factors: f:%f, w:%f\nBounce flags: %x",
|
||||
query->BounceFlags, FIXED2FLOAT(query->bouncefactor),
|
||||
FIXED2FLOAT(query->wallbouncefactor), query->BounceFlags);
|
||||
/*for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->BounceFlags & 1<<flagi) Printf(" %s", flagnamesb[flagi]);*/
|
||||
Printf("\nIts render style is %i:%s with alpha %f and the following render flags:\n\tflagsr: %x",
|
||||
Printf("\nRender style = %i:%s, alpha %f\nRender flags: %x",
|
||||
querystyle, (querystyle < STYLE_Count ? renderstyles[querystyle] : "Unknown"),
|
||||
FIXED2FLOAT(query->alpha), query->renderflags);
|
||||
/*for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->renderflags & 1<<flagi) Printf(" %s", flagnamesr[flagi]);*/
|
||||
Printf("\nIts thing special and arguments are %s(%i, %i, %i, %i, %i), and its specials are %i and %i.",
|
||||
Printf("\nSpecial+args: %s(%i, %i, %i, %i, %i)\nspecial1: %i, special2: %i.",
|
||||
(query->special ? LineSpecialsInfo[query->special]->name : "None"),
|
||||
query->args[0], query->args[1], query->args[2], query->args[3],
|
||||
query->args[4], query->special1, query->special2);
|
||||
Printf("\nTID is %d", query->tid);
|
||||
Printf("\nIts coordinates are x: %f, y: %f, z:%f, floor:%f, ceiling:%f.",
|
||||
Printf("\nTID: %d", query->tid);
|
||||
Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.",
|
||||
FIXED2FLOAT(query->x), FIXED2FLOAT(query->y), FIXED2FLOAT(query->z),
|
||||
FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz));
|
||||
Printf("\nIts speed is %f and velocity is x:%f, y:%f, z:%f, combined:%f.\n",
|
||||
Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n",
|
||||
FIXED2FLOAT(query->Speed), FIXED2FLOAT(query->velx), FIXED2FLOAT(query->vely), FIXED2FLOAT(query->velz),
|
||||
sqrt(pow(FIXED2FLOAT(query->velx), 2) + pow(FIXED2FLOAT(query->vely), 2) + pow(FIXED2FLOAT(query->velz), 2)));
|
||||
}
|
||||
|
|
|
@ -909,7 +909,6 @@ int FStateDefinitions::FinishStates(PClassActor *actor, AActor *defaults)
|
|||
{
|
||||
FState *realstates = new FState[count];
|
||||
int i;
|
||||
int currange;
|
||||
|
||||
memcpy(realstates, &StateArray[0], count*sizeof(FState));
|
||||
actor->OwnedStates = realstates;
|
||||
|
@ -917,12 +916,15 @@ int FStateDefinitions::FinishStates(PClassActor *actor, AActor *defaults)
|
|||
|
||||
// adjust the state pointers
|
||||
// In the case new states are added these must be adjusted, too!
|
||||
FixStatePointers (actor, StateLabels);
|
||||
FixStatePointers(actor, StateLabels);
|
||||
|
||||
for(i = currange = 0; i < count; i++)
|
||||
// Fix state pointers that are gotos
|
||||
ResolveGotoLabels(actor, defaults, StateLabels);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
// resolve labels and jumps
|
||||
switch(realstates[i].DefineFlags)
|
||||
switch (realstates[i].DefineFlags)
|
||||
{
|
||||
case SDF_STOP: // stop
|
||||
realstates[i].NextState = NULL;
|
||||
|
@ -946,10 +948,11 @@ int FStateDefinitions::FinishStates(PClassActor *actor, AActor *defaults)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix state pointers that are gotos
|
||||
ResolveGotoLabels(actor, defaults, StateLabels);
|
||||
|
||||
else
|
||||
{
|
||||
// Fix state pointers that are gotos
|
||||
ResolveGotoLabels(actor, defaults, StateLabels);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,10 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog)
|
|||
source->PrevX = x;
|
||||
source->PrevY = y;
|
||||
source->PrevZ = z;
|
||||
if (source == players[consoleplayer].camera)
|
||||
{
|
||||
R_ResetViewInterpolation();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -471,6 +471,29 @@ void PClassPlayerPawn::EnumColorSets(TArray<int> *out)
|
|||
qsort(&(*out)[0], out->Size(), sizeof(int), intcmp);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool PClassPlayerPawn::GetPainFlash(FName type, PalEntry *color) const
|
||||
{
|
||||
const PClassPlayerPawn *info = this;
|
||||
|
||||
while (info != NULL)
|
||||
{
|
||||
const PalEntry *flash = info->PainFlashes.CheckKey(type);
|
||||
if (flash != NULL)
|
||||
{
|
||||
*color = *flash;
|
||||
return true;
|
||||
}
|
||||
// Try parent class
|
||||
info = dyn_cast<PClassPlayerPawn>(info->ParentClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// player_t :: SendPitchLimits
|
||||
|
@ -523,6 +546,28 @@ void APlayerPawn::Serialize (FArchive &arc)
|
|||
<< DamageFade
|
||||
<< PlayerFlags
|
||||
<< FlechetteType;
|
||||
if (SaveVersion < 3829)
|
||||
{
|
||||
GruntSpeed = 12*FRACUNIT;
|
||||
FallingScreamMinSpeed = 35*FRACUNIT;
|
||||
FallingScreamMaxSpeed = 40*FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: MarkPrecacheSounds
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::MarkPrecacheSounds() const
|
||||
{
|
||||
Super::MarkPrecacheSounds();
|
||||
S_MarkPlayerSounds(GetSoundClass());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1018,7 +1063,7 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
const char *APlayerPawn::GetSoundClass ()
|
||||
const char *APlayerPawn::GetSoundClass() const
|
||||
{
|
||||
if (player != NULL &&
|
||||
(player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) &&
|
||||
|
@ -1679,7 +1724,11 @@ void P_CalcHeight (player_t *player)
|
|||
// it causes bobbing jerkiness when the player moves from ice to non-ice,
|
||||
// and vice-versa.
|
||||
|
||||
if ((player->mo->flags & MF_NOGRAVITY) && !onground)
|
||||
if (player->cheats & CF_NOCLIP2)
|
||||
{
|
||||
player->bob = 0;
|
||||
}
|
||||
else if ((player->mo->flags & MF_NOGRAVITY) && !onground)
|
||||
{
|
||||
player->bob = FRACUNIT / 2;
|
||||
}
|
||||
|
@ -1804,7 +1853,7 @@ void P_MovePlayer (player_t *player)
|
|||
mo->angle += cmd->ucmd.yaw << 16;
|
||||
}
|
||||
|
||||
onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF);
|
||||
onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2);
|
||||
|
||||
// killough 10/98:
|
||||
//
|
||||
|
@ -2185,7 +2234,11 @@ void P_PlayerThink (player_t *player)
|
|||
player->inventorytics--;
|
||||
}
|
||||
// No-clip cheat
|
||||
if (player->cheats & CF_NOCLIP || (player->mo->GetDefault()->flags & MF_NOCLIP))
|
||||
if ((player->cheats & (CF_NOCLIP | CF_NOCLIP2)) == CF_NOCLIP2)
|
||||
{ // No noclip2 without noclip
|
||||
player->cheats &= ~CF_NOCLIP2;
|
||||
}
|
||||
if (player->cheats & (CF_NOCLIP | CF_NOCLIP2) || (player->mo->GetDefault()->flags & MF_NOCLIP))
|
||||
{
|
||||
player->mo->flags |= MF_NOCLIP;
|
||||
}
|
||||
|
@ -2193,6 +2246,14 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
player->mo->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
if (player->cheats & CF_NOCLIP2)
|
||||
{
|
||||
player->mo->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
else if (!(player->mo->flags2 & MF2_FLY) && !(player->mo->GetDefault()->flags & MF_NOGRAVITY))
|
||||
{
|
||||
player->mo->flags &= ~MF_NOGRAVITY;
|
||||
}
|
||||
cmd = &player->cmd;
|
||||
|
||||
// Make unmodified copies for ACS's GetPlayerInput.
|
||||
|
@ -2413,7 +2474,7 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
cmd->ucmd.upmove = ksgn (cmd->ucmd.upmove) * 0x300;
|
||||
}
|
||||
if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY))
|
||||
if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2))
|
||||
{
|
||||
player->mo->velz = cmd->ucmd.upmove << 9;
|
||||
if (player->mo->waterlevel < 2 && !(player->mo->flags & MF_NOGRAVITY))
|
||||
|
@ -2447,8 +2508,8 @@ void P_PlayerThink (player_t *player)
|
|||
P_PlayerInSpecialSector (player);
|
||||
}
|
||||
P_PlayerOnSpecialFlat (player, P_GetThingFloorType (player->mo));
|
||||
if (player->mo->velz <= -35*FRACUNIT &&
|
||||
player->mo->velz >= -40*FRACUNIT && !player->morphTics &&
|
||||
if (player->mo->velz <= -player->mo->FallingScreamMinSpeed &&
|
||||
player->mo->velz >= -player->mo->FallingScreamMaxSpeed && !player->morphTics &&
|
||||
player->mo->waterlevel == 0)
|
||||
{
|
||||
int id = S_FindSkinnedSound (player->mo, "*falling");
|
||||
|
@ -2531,7 +2592,7 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
if (player->mo->waterlevel < 3 ||
|
||||
(player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||
(player->cheats & CF_GODMODE))
|
||||
(player->cheats & (CF_GODMODE | CF_NOCLIP2)))
|
||||
{
|
||||
player->mo->ResetAirSupply ();
|
||||
}
|
||||
|
@ -2763,6 +2824,14 @@ void player_t::Serialize (FArchive &arc)
|
|||
{
|
||||
cheats &= ~(1 << 17); // make sure old CF_REGENERATION bit is cleared
|
||||
}
|
||||
if (SaveVersion >= 3780)
|
||||
{
|
||||
arc << settings_controller;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_controller = (this - players == Net_Arbitrator);
|
||||
}
|
||||
|
||||
if (isbot)
|
||||
{
|
||||
|
|
|
@ -1185,7 +1185,7 @@ void R_Subsector (subsector_t *sub)
|
|||
frontsector->GetTexture(sector_t::floor),
|
||||
floorlightlevel + r_actualextralight, // killough 3/16/98
|
||||
frontsector->GetAlpha(sector_t::floor),
|
||||
!!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE),
|
||||
!!(fakeFloor->flags & FF_ADDITIVETRANS),
|
||||
frontsector->GetXOffset(position), // killough 3/7/98
|
||||
frontsector->GetYOffset(position), // killough 3/7/98
|
||||
frontsector->GetXScale(position),
|
||||
|
@ -1250,7 +1250,7 @@ void R_Subsector (subsector_t *sub)
|
|||
frontsector->GetTexture(sector_t::ceiling),
|
||||
ceilinglightlevel + r_actualextralight, // killough 4/11/98
|
||||
frontsector->GetAlpha(sector_t::ceiling),
|
||||
!!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE),
|
||||
!!(fakeFloor->flags & FF_ADDITIVETRANS),
|
||||
frontsector->GetXOffset(position), // killough 3/7/98
|
||||
frontsector->GetYOffset(position), // killough 3/7/98
|
||||
frontsector->GetXScale(position),
|
||||
|
|
|
@ -403,14 +403,22 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2)
|
||||
void FRemapTable::AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2)
|
||||
{
|
||||
r1 = clamp(r1, 0.0f, 2.0f);
|
||||
g1 = clamp(g1, 0.0f, 2.0f);
|
||||
b1 = clamp(b1, 0.0f, 2.0f);
|
||||
r2 = clamp(r2, 0.0f, 2.0f);
|
||||
g2 = clamp(g2, 0.0f, 2.0f);
|
||||
b2 = clamp(b2, 0.0f, 2.0f);
|
||||
r1 = clamp(r1, 0.0, 2.0);
|
||||
g1 = clamp(g1, 0.0, 2.0);
|
||||
b1 = clamp(b1, 0.0, 2.0);
|
||||
r2 = clamp(r2, 0.0, 2.0);
|
||||
g2 = clamp(g2, 0.0, 2.0);
|
||||
b2 = clamp(b2, 0.0, 2.0);
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
swapvalues(start, end);
|
||||
swapvalues(r1, r2);
|
||||
swapvalues(g1, g2);
|
||||
swapvalues(b1, b2);
|
||||
}
|
||||
|
||||
r2 -= r1;
|
||||
g2 -= g1;
|
||||
|
@ -419,7 +427,7 @@ void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b
|
|||
g1 *= 255;
|
||||
b1 *= 255;
|
||||
|
||||
for(int c = start; c < end; c++)
|
||||
for(int c = start; c <= end; c++)
|
||||
{
|
||||
double intensity = (GPalette.BaseColors[c].r * 77 +
|
||||
GPalette.BaseColors[c].g * 143 +
|
||||
|
@ -443,7 +451,7 @@ void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void FRemapTable::AddToTranslation(const char * range)
|
||||
void FRemapTable::AddToTranslation(const char *range)
|
||||
{
|
||||
int start,end;
|
||||
bool desaturated = false;
|
||||
|
@ -515,39 +523,39 @@ void FRemapTable::AddToTranslation(const char * range)
|
|||
else if (sc.TokenType == '%')
|
||||
{
|
||||
// translation using RGB values
|
||||
float r1,g1,b1,r2,g2,b2;
|
||||
double r1,g1,b1,r2,g2,b2;
|
||||
|
||||
sc.MustGetToken('[');
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
r1 = float(sc.Float);
|
||||
r1 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
g1 = float(sc.Float);
|
||||
g1 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
b1 = float(sc.Float);
|
||||
b1 = sc.Float;
|
||||
sc.MustGetToken(']');
|
||||
sc.MustGetToken(':');
|
||||
sc.MustGetToken('[');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
r2 = float(sc.Float);
|
||||
r2 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
g2 = float(sc.Float);
|
||||
g2 = sc.Float;
|
||||
sc.MustGetToken(',');
|
||||
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
|
||||
b2 = float(sc.Float);
|
||||
b2 = sc.Float;
|
||||
sc.MustGetToken(']');
|
||||
|
||||
AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
|
||||
|
|
|
@ -38,7 +38,7 @@ struct FRemapTable
|
|||
void Serialize(FArchive &ar);
|
||||
void AddIndexRange(int start, int end, int pal1, int pal2);
|
||||
void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
|
||||
void AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2);
|
||||
void AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
|
||||
void AddToTranslation(const char * range);
|
||||
int StoreTranslation();
|
||||
|
||||
|
|
|
@ -423,6 +423,10 @@ static void R_ExtendSpriteFrames(spritedef_t &spr, int frame)
|
|||
// at all, so we can tack the new frames directly on to the end
|
||||
// of the SpriteFrames array.
|
||||
newstart = SpriteFrames.Reserve(frame - spr.numframes);
|
||||
if (spr.numframes == 0)
|
||||
{
|
||||
spr.spriteframes = WORD(newstart);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // We need to allocate space for all the sprite's frames and copy
|
||||
|
@ -439,7 +443,6 @@ static void R_ExtendSpriteFrames(spritedef_t &spr, int frame)
|
|||
// Initialize all new frames to 0.
|
||||
memset(&SpriteFrames[newstart], 0, sizeof(spriteframe_t)*(frame - spr.numframes));
|
||||
spr.numframes = frame;
|
||||
spr.spriteframes = newstart;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -71,7 +71,7 @@ TDeletingArray<FVoxelDef *> VoxelDefs;
|
|||
struct VoxelOptions
|
||||
{
|
||||
VoxelOptions()
|
||||
: DroppedSpin(0), PlacedSpin(0), Scale(FRACUNIT), AngleOffset(0)
|
||||
: DroppedSpin(0), PlacedSpin(0), Scale(FRACUNIT), AngleOffset(ANGLE_90)
|
||||
{}
|
||||
|
||||
int DroppedSpin;
|
||||
|
@ -332,7 +332,7 @@ FVoxelDef *R_LoadVoxelDef(int lumpnum, int spin)
|
|||
voxdef->Voxel = vox;
|
||||
voxdef->Scale = FRACUNIT;
|
||||
voxdef->DroppedSpin = voxdef->PlacedSpin = spin;
|
||||
voxdef->AngleOffset = 0;
|
||||
voxdef->AngleOffset = ANGLE_90;
|
||||
|
||||
Voxels.Push(vox);
|
||||
VoxelDefs.Push(voxdef);
|
||||
|
@ -508,7 +508,7 @@ static void VOX_ReadOptions(FScanner &sc, VoxelOptions &opts)
|
|||
{
|
||||
sc.TokenMustBe(TK_FloatConst);
|
||||
}
|
||||
opts.AngleOffset = angle_t(sc.Float * ANGLE_180 / 180.0);
|
||||
opts.AngleOffset = ANGLE_90 + angle_t(sc.Float * ANGLE_180 / 180.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
12
src/r_defs.h
12
src/r_defs.h
|
@ -38,8 +38,8 @@
|
|||
|
||||
#include "dthinker.h"
|
||||
|
||||
#define MAXWIDTH 2880
|
||||
#define MAXHEIGHT 1800
|
||||
#define MAXWIDTH 5760
|
||||
#define MAXHEIGHT 3600
|
||||
|
||||
const WORD NO_INDEX = 0xffffu;
|
||||
const DWORD NO_SIDE = 0xffffffffu;
|
||||
|
@ -832,11 +832,11 @@ struct side_t
|
|||
|
||||
void SetTextureXScale(int which, fixed_t scale)
|
||||
{
|
||||
textures[which].xscale = scale <= 0? FRACUNIT : scale;
|
||||
textures[which].xscale = scale == 0 ? FRACUNIT : scale;
|
||||
}
|
||||
void SetTextureXScale(fixed_t scale)
|
||||
{
|
||||
textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale <= 0? FRACUNIT : scale;
|
||||
textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale == 0 ? FRACUNIT : scale;
|
||||
}
|
||||
fixed_t GetTextureXScale(int which) const
|
||||
{
|
||||
|
@ -850,11 +850,11 @@ struct side_t
|
|||
|
||||
void SetTextureYScale(int which, fixed_t scale)
|
||||
{
|
||||
textures[which].yscale = scale <= 0? FRACUNIT : scale;
|
||||
textures[which].yscale = scale == 0 ? FRACUNIT : scale;
|
||||
}
|
||||
void SetTextureYScale(fixed_t scale)
|
||||
{
|
||||
textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale <= 0? FRACUNIT : scale;
|
||||
textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale == 0 ? FRACUNIT : scale;
|
||||
}
|
||||
fixed_t GetTextureYScale(int which) const
|
||||
{
|
||||
|
|
158
src/r_draw.cpp
158
src/r_draw.cpp
|
@ -79,6 +79,8 @@ void (*R_DrawSpan)(void);
|
|||
void (*R_DrawSpanMasked)(void);
|
||||
void (*R_DrawSpanTranslucent)(void);
|
||||
void (*R_DrawSpanMaskedTranslucent)(void);
|
||||
void (*R_DrawSpanAddClamp)(void);
|
||||
void (*R_DrawSpanMaskedAddClamp)(void);
|
||||
void (STACK_ARGS *rt_map4cols)(int,int,int);
|
||||
|
||||
//
|
||||
|
@ -1324,6 +1326,152 @@ void R_DrawSpanMaskedTranslucentP_C (void)
|
|||
}
|
||||
}
|
||||
|
||||
void R_DrawSpanAddClampP_C (void)
|
||||
{
|
||||
dsfixed_t xfrac;
|
||||
dsfixed_t yfrac;
|
||||
dsfixed_t xstep;
|
||||
dsfixed_t ystep;
|
||||
BYTE* dest;
|
||||
const BYTE* source = ds_source;
|
||||
const BYTE* colormap = ds_colormap;
|
||||
int count;
|
||||
int spot;
|
||||
DWORD *fg2rgb = dc_srcblend;
|
||||
DWORD *bg2rgb = dc_destblend;
|
||||
|
||||
xfrac = ds_xfrac;
|
||||
yfrac = ds_yfrac;
|
||||
|
||||
dest = ylookup[ds_y] + ds_x1 + dc_destorg;
|
||||
|
||||
count = ds_x2 - ds_x1 + 1;
|
||||
|
||||
xstep = ds_xstep;
|
||||
ystep = ds_ystep;
|
||||
|
||||
if (ds_xbits == 6 && ds_ybits == 6)
|
||||
{
|
||||
// 64x64 is the most common case by far, so special case it.
|
||||
do
|
||||
{
|
||||
spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6));
|
||||
DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest];
|
||||
DWORD b = a;
|
||||
|
||||
a |= 0x01f07c1f;
|
||||
b &= 0x40100400;
|
||||
a &= 0x3fffffff;
|
||||
b = b - (b >> 5);
|
||||
a |= b;
|
||||
*dest++ = RGB32k[0][0][a & (a>>15)];
|
||||
xfrac += xstep;
|
||||
yfrac += ystep;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE yshift = 32 - ds_ybits;
|
||||
BYTE xshift = yshift - ds_xbits;
|
||||
int xmask = ((1 << ds_xbits) - 1) << ds_ybits;
|
||||
do
|
||||
{
|
||||
spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift);
|
||||
DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest];
|
||||
DWORD b = a;
|
||||
|
||||
a |= 0x01f07c1f;
|
||||
b &= 0x40100400;
|
||||
a &= 0x3fffffff;
|
||||
b = b - (b >> 5);
|
||||
a |= b;
|
||||
*dest++ = RGB32k[0][0][a & (a>>15)];
|
||||
xfrac += xstep;
|
||||
yfrac += ystep;
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
void R_DrawSpanMaskedAddClampP_C (void)
|
||||
{
|
||||
dsfixed_t xfrac;
|
||||
dsfixed_t yfrac;
|
||||
dsfixed_t xstep;
|
||||
dsfixed_t ystep;
|
||||
BYTE* dest;
|
||||
const BYTE* source = ds_source;
|
||||
const BYTE* colormap = ds_colormap;
|
||||
int count;
|
||||
int spot;
|
||||
DWORD *fg2rgb = dc_srcblend;
|
||||
DWORD *bg2rgb = dc_destblend;
|
||||
|
||||
xfrac = ds_xfrac;
|
||||
yfrac = ds_yfrac;
|
||||
|
||||
dest = ylookup[ds_y] + ds_x1 + dc_destorg;
|
||||
|
||||
count = ds_x2 - ds_x1 + 1;
|
||||
|
||||
xstep = ds_xstep;
|
||||
ystep = ds_ystep;
|
||||
|
||||
if (ds_xbits == 6 && ds_ybits == 6)
|
||||
{
|
||||
// 64x64 is the most common case by far, so special case it.
|
||||
do
|
||||
{
|
||||
BYTE texdata;
|
||||
|
||||
spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6));
|
||||
texdata = source[spot];
|
||||
if (texdata != 0)
|
||||
{
|
||||
DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest];
|
||||
DWORD b = a;
|
||||
|
||||
a |= 0x01f07c1f;
|
||||
b &= 0x40100400;
|
||||
a &= 0x3fffffff;
|
||||
b = b - (b >> 5);
|
||||
a |= b;
|
||||
*dest = RGB32k[0][0][a & (a>>15)];
|
||||
}
|
||||
dest++;
|
||||
xfrac += xstep;
|
||||
yfrac += ystep;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE yshift = 32 - ds_ybits;
|
||||
BYTE xshift = yshift - ds_xbits;
|
||||
int xmask = ((1 << ds_xbits) - 1) << ds_ybits;
|
||||
do
|
||||
{
|
||||
BYTE texdata;
|
||||
|
||||
spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift);
|
||||
texdata = source[spot];
|
||||
if (texdata != 0)
|
||||
{
|
||||
DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest];
|
||||
DWORD b = a;
|
||||
|
||||
a |= 0x01f07c1f;
|
||||
b &= 0x40100400;
|
||||
a &= 0x3fffffff;
|
||||
b = b - (b >> 5);
|
||||
a |= b;
|
||||
*dest = RGB32k[0][0][a & (a>>15)];
|
||||
}
|
||||
dest++;
|
||||
xfrac += xstep;
|
||||
yfrac += ystep;
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Just fill a span with a color
|
||||
void R_FillSpan (void)
|
||||
{
|
||||
|
@ -2005,6 +2153,14 @@ void tmvline4_revsubclamp ()
|
|||
|
||||
const BYTE *R_GetColumn (FTexture *tex, int col)
|
||||
{
|
||||
int width;
|
||||
|
||||
// If the texture's width isn't a power of 2, then we need to make it a
|
||||
// positive offset for proper clamping.
|
||||
if (col < 0 && (width = tex->GetWidth()) != (1 << tex->WidthBits))
|
||||
{
|
||||
col = width + (col % width);
|
||||
}
|
||||
return tex->GetColumn (col, NULL);
|
||||
}
|
||||
|
||||
|
@ -2040,6 +2196,8 @@ void R_InitColumnDrawers ()
|
|||
#endif
|
||||
R_DrawSpanTranslucent = R_DrawSpanTranslucentP_C;
|
||||
R_DrawSpanMaskedTranslucent = R_DrawSpanMaskedTranslucentP_C;
|
||||
R_DrawSpanAddClamp = R_DrawSpanAddClampP_C;
|
||||
R_DrawSpanMaskedAddClamp = R_DrawSpanMaskedAddClampP_C;
|
||||
}
|
||||
|
||||
// [RH] Choose column drawers in a single place
|
||||
|
|
|
@ -106,6 +106,12 @@ extern void (*R_DrawSpanTranslucent)(void);
|
|||
// Span drawing for masked, translucent textures.
|
||||
extern void (*R_DrawSpanMaskedTranslucent)(void);
|
||||
|
||||
// Span drawing for translucent, additive textures.
|
||||
extern void (*R_DrawSpanAddClamp)(void);
|
||||
|
||||
// Span drawing for masked, translucent, additive textures.
|
||||
extern void (*R_DrawSpanMaskedAddClamp)(void);
|
||||
|
||||
// [RH] Span blit into an interleaved intermediate buffer
|
||||
extern void (*R_DrawColumnHoriz)(void);
|
||||
void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *spans);
|
||||
|
|
|
@ -596,7 +596,6 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
|||
else sky = 0; // not skyflatnum so it can't be a sky
|
||||
skybox = NULL;
|
||||
alpha = FRACUNIT;
|
||||
additive = false;
|
||||
}
|
||||
|
||||
// New visplane algorithm uses hash table -- killough
|
||||
|
@ -1047,7 +1046,7 @@ void R_DrawHeightPlanes(fixed_t height)
|
|||
viewy = pl->viewy;
|
||||
viewangle = pl->viewangle;
|
||||
MirrorFlags = pl->MirrorFlags;
|
||||
R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, false, true);
|
||||
R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1528,16 +1527,24 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
else
|
||||
plane_shade = true;
|
||||
|
||||
// Additive not supported yet because the drawer function doesn't look like it can handle it.
|
||||
if (spanfunc != R_FillSpan)
|
||||
{
|
||||
if (masked)
|
||||
{
|
||||
if (alpha < OPAQUE)
|
||||
if (alpha < OPAQUE || additive)
|
||||
{
|
||||
spanfunc = R_DrawSpanMaskedTranslucent;
|
||||
dc_srcblend = Col2RGB8[alpha>>10];
|
||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
||||
if (!additive)
|
||||
{
|
||||
spanfunc = R_DrawSpanMaskedTranslucent;
|
||||
dc_srcblend = Col2RGB8[alpha>>10];
|
||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
||||
}
|
||||
else
|
||||
{
|
||||
spanfunc = R_DrawSpanMaskedAddClamp;
|
||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1546,11 +1553,20 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
|
|||
}
|
||||
else
|
||||
{
|
||||
if (alpha < OPAQUE)
|
||||
if (alpha < OPAQUE || additive)
|
||||
{
|
||||
spanfunc = R_DrawSpanTranslucent;
|
||||
dc_srcblend = Col2RGB8[alpha>>10];
|
||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
||||
if (!additive)
|
||||
{
|
||||
spanfunc = R_DrawSpanTranslucent;
|
||||
dc_srcblend = Col2RGB8[alpha>>10];
|
||||
dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10];
|
||||
}
|
||||
else
|
||||
{
|
||||
spanfunc = R_DrawSpanAddClamp;
|
||||
dc_srcblend = Col2RGB8_LessPrecision[alpha>>10];
|
||||
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1965,7 +1965,7 @@ void R_NewWall (bool needlights)
|
|||
}
|
||||
if (midtexture->bWorldPanning)
|
||||
{
|
||||
rw_midtexturemid = MulScale16(rowoffset, yrepeat);
|
||||
rw_midtexturemid += MulScale16(rowoffset, yrepeat);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2769,6 +2769,7 @@ int WallMost (short *mostbuf, const secplane_t &plane)
|
|||
static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat)
|
||||
{
|
||||
// fix for rounding errors
|
||||
walxrepeat = abs(walxrepeat);
|
||||
fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0;
|
||||
int x;
|
||||
|
||||
|
@ -2803,7 +2804,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat)
|
|||
void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat)
|
||||
{ // swall = scale, lwall = texturecolumn
|
||||
double top, bot, i;
|
||||
double xrepeat = walxrepeat;
|
||||
double xrepeat = fabs((double)walxrepeat);
|
||||
|
||||
i = WallSX1 - centerx;
|
||||
top = WallUoverZorg + WallUoverZstep * i;
|
||||
|
@ -2812,7 +2813,14 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat)
|
|||
for (int x = WallSX1; x < WallSX2; x++)
|
||||
{
|
||||
double frac = top / bot;
|
||||
lwall[x] = xs_RoundToInt(frac * xrepeat);
|
||||
if (walxrepeat < 0)
|
||||
{
|
||||
lwall[x] = xs_RoundToInt(xrepeat - frac * xrepeat);
|
||||
}
|
||||
else
|
||||
{
|
||||
lwall[x] = xs_RoundToInt(frac * xrepeat);
|
||||
}
|
||||
swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg);
|
||||
top += WallUoverZstep;
|
||||
bot += WallInvZstep;
|
||||
|
@ -2823,7 +2831,7 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat)
|
|||
void PrepLWall (fixed_t *lwall, fixed_t walxrepeat)
|
||||
{ // lwall = texturecolumn
|
||||
double top, bot, i;
|
||||
double xrepeat = walxrepeat;
|
||||
double xrepeat = fabs((double)walxrepeat);
|
||||
double topstep;
|
||||
|
||||
i = WallSX1 - centerx;
|
||||
|
@ -2835,7 +2843,14 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat)
|
|||
|
||||
for (int x = WallSX1; x < WallSX2; x++)
|
||||
{
|
||||
lwall[x] = xs_RoundToInt(top / bot);
|
||||
if (walxrepeat < 0)
|
||||
{
|
||||
lwall[x] = xs_RoundToInt(xrepeat - top / bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
lwall[x] = xs_RoundToInt(top / bot);
|
||||
}
|
||||
top += topstep;
|
||||
bot += WallInvZstep;
|
||||
}
|
||||
|
|
|
@ -514,13 +514,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
// [RH] Interpolate the sprite's position to make it look smooth
|
||||
fx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX);
|
||||
fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY);
|
||||
fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ);
|
||||
|
||||
// [RH] Make floatbobbing a renderer-only effect.
|
||||
if (thing->flags2 & MF2_FLOATBOB)
|
||||
{
|
||||
fz += finesine[(Scale(thing->FloatBobPhase + level.maptime, FINEANGLES, 64) + r_TicFrac * ((FINEANGLES/64) / 1000)) & FINEMASK] * 8;
|
||||
}
|
||||
fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = fx - viewx;
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
void AddSound (int player_sound_id, int sfx_id);
|
||||
int LookupSound (int player_sound_id);
|
||||
FPlayerSoundHashTable &operator= (const FPlayerSoundHashTable &other);
|
||||
void MarkUsed();
|
||||
|
||||
protected:
|
||||
struct Entry
|
||||
|
@ -122,7 +123,7 @@ struct FAmbientSound
|
|||
int periodmax; // max # of tics for random ambients
|
||||
float volume; // relative volume of sound
|
||||
float attenuation;
|
||||
FString sound; // Logical name of sound to play
|
||||
FSoundID sound; // Sound to play
|
||||
};
|
||||
TMap<int, FAmbientSound> Ambients;
|
||||
|
||||
|
@ -219,6 +220,7 @@ extern int sfx_empty;
|
|||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
TArray<sfxinfo_t> S_sfx (128);
|
||||
TMap<int, FString> HexenMusic;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -830,6 +832,25 @@ int FPlayerSoundHashTable::LookupSound (int player_sound_id)
|
|||
return entry != NULL ? entry->SfxID : 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FPlayerSoundHashTable :: Mark
|
||||
//
|
||||
// Marks all sounds defined for this class/gender as used.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FPlayerSoundHashTable::MarkUsed()
|
||||
{
|
||||
for (size_t i = 0; i < NUM_BUCKETS; ++i)
|
||||
{
|
||||
for (Entry *probe = Buckets[i]; probe != NULL; probe = probe->Next)
|
||||
{
|
||||
S_sfx[probe->SfxID].bUsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_ClearSoundData
|
||||
|
@ -866,6 +887,7 @@ static void S_ClearSoundData()
|
|||
DefPlayerClassName = "";
|
||||
MusicAliases.Clear();
|
||||
MidiDevices.Clear();
|
||||
HexenMusic.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -984,10 +1006,10 @@ static void S_AddSNDINFO (int lump)
|
|||
ambient->periodmax = 0;
|
||||
ambient->volume = 0;
|
||||
ambient->attenuation = 0;
|
||||
ambient->sound = "";
|
||||
ambient->sound = 0;
|
||||
|
||||
sc.MustGetString ();
|
||||
ambient->sound = sc.String;
|
||||
ambient->sound = FSoundID(S_FindSoundTentative(sc.String));
|
||||
ambient->attenuation = 0;
|
||||
|
||||
sc.MustGetString ();
|
||||
|
@ -1064,16 +1086,14 @@ static void S_AddSNDINFO (int lump)
|
|||
|
||||
case SI_Map: {
|
||||
// Hexen-style $MAP command
|
||||
level_info_t *info;
|
||||
char temp[16];
|
||||
int mapnum;
|
||||
|
||||
sc.MustGetNumber ();
|
||||
mysnprintf (temp, countof(temp), "MAP%02d", sc.Number);
|
||||
info = FindLevelInfo (temp);
|
||||
sc.MustGetString ();
|
||||
if (info->mapname[0] && (!(info->flags2 & LEVEL2_MUSICDEFINED)))
|
||||
sc.MustGetNumber();
|
||||
mapnum = sc.Number;
|
||||
sc.MustGetString();
|
||||
if (mapnum != 0)
|
||||
{
|
||||
info->Music = sc.String;
|
||||
HexenMusic[mapnum] = sc.String;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1899,6 +1919,44 @@ bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time)
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// sfxinfo_t :: MarkUsed
|
||||
//
|
||||
// Marks this sound for precaching.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void sfxinfo_t::MarkUsed()
|
||||
{
|
||||
bUsed = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_MarkPlayerSounds
|
||||
//
|
||||
// Marks all sounds from a particular player class for precaching.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void S_MarkPlayerSounds (const char *playerclass)
|
||||
{
|
||||
int classidx = S_FindPlayerClass(playerclass);
|
||||
if (classidx < 0)
|
||||
{
|
||||
classidx = DefPlayerClass;
|
||||
}
|
||||
for (int g = 0; g < 3; ++g)
|
||||
{
|
||||
int listidx = PlayerClassLookups[classidx].ListIndex[0];
|
||||
if (listidx != 0xffff)
|
||||
{
|
||||
PlayerSounds[listidx].MarkUsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CCMD soundlist
|
||||
|
@ -2014,6 +2072,7 @@ class AAmbientSound : public AActor
|
|||
public:
|
||||
void Serialize (FArchive &arc);
|
||||
|
||||
void MarkPrecacheSounds () const;
|
||||
void BeginPlay ();
|
||||
void Tick ();
|
||||
void Activate (AActor *activator);
|
||||
|
@ -2040,6 +2099,22 @@ void AAmbientSound::Serialize (FArchive &arc)
|
|||
arc << bActive << NextCheck;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AmbientSound :: MarkPrecacheSounds
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void AAmbientSound::MarkPrecacheSounds() const
|
||||
{
|
||||
Super::MarkPrecacheSounds();
|
||||
FAmbientSound *ambient = Ambients.CheckKey(args[0]);
|
||||
if (ambient != NULL)
|
||||
{
|
||||
ambient->sound.MarkUsed();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AmbientSound :: Tick
|
||||
|
@ -2067,7 +2142,7 @@ void AAmbientSound::Tick ()
|
|||
loop = CHAN_LOOP;
|
||||
}
|
||||
|
||||
if (ambient->sound.IsNotEmpty())
|
||||
if (ambient->sound != 0)
|
||||
{
|
||||
// The second argument scales the ambient sound's volume.
|
||||
// 0 and 100 are normal volume. The maximum volume level
|
||||
|
|
|
@ -760,7 +760,7 @@ static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, c
|
|||
Sequences[curseq] = (FSoundSequence *)M_Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size());
|
||||
Sequences[curseq]->SeqName = seqname;
|
||||
Sequences[curseq]->Slot = slot;
|
||||
Sequences[curseq]->StopSound = stopsound;
|
||||
Sequences[curseq]->StopSound = FSoundID(stopsound);
|
||||
memcpy (Sequences[curseq]->Script, &ScriptTemp[0], sizeof(DWORD)*ScriptTemp.Size());
|
||||
Sequences[curseq]->Script[ScriptTemp.Size()] = MakeCommand(SS_CMD_END, 0);
|
||||
}
|
||||
|
@ -1311,6 +1311,32 @@ FName SN_GetSequenceSlot (int sequence, seqtype_t type)
|
|||
return NAME_None;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_MarkPrecacheSounds
|
||||
//
|
||||
// Marks all sounds played by this sequence for precaching.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_MarkPrecacheSounds(int sequence, seqtype_t type)
|
||||
{
|
||||
if (TwiddleSeqNum(sequence, type))
|
||||
{
|
||||
FSoundSequence *seq = Sequences[sequence];
|
||||
|
||||
seq->StopSound.MarkUsed();
|
||||
for (int i = 0; GetCommand(seq->Script[i]) != SS_CMD_END; ++i)
|
||||
{
|
||||
int cmd = GetCommand(seq->Script[i]);
|
||||
if (cmd == SS_CMD_PLAY || cmd == SS_CMD_PLAYREPEAT || cmd == SS_CMD_PLAYLOOP)
|
||||
{
|
||||
FSoundID(GetData(seq->Script[i])).MarkUsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_ChangeNodeData
|
||||
|
|
|
@ -71,10 +71,10 @@ void SN_StopAllSequences (void);
|
|||
|
||||
struct FSoundSequence
|
||||
{
|
||||
FName SeqName;
|
||||
FName Slot;
|
||||
int StopSound;
|
||||
SDWORD Script[1]; // + more until end of sequence script
|
||||
FName SeqName;
|
||||
FName Slot;
|
||||
FSoundID StopSound;
|
||||
SDWORD Script[1]; // + more until end of sequence script
|
||||
};
|
||||
|
||||
void S_ParseSndSeq (int levellump);
|
||||
|
@ -98,6 +98,7 @@ void SN_DoStop (void *);
|
|||
void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics,
|
||||
float volume, int currentSoundID);
|
||||
FName SN_GetSequenceSlot (int sequence, seqtype_t type);
|
||||
void SN_MarkPrecacheSounds (int sequence, seqtype_t type);
|
||||
bool SN_IsMakingLoopingSound (sector_t *sector);
|
||||
|
||||
#endif //__S_SNDSEQ_H__
|
||||
|
|
|
@ -326,7 +326,6 @@ void S_InitData ()
|
|||
LastLocalSndInfo = LastLocalSndSeq = "";
|
||||
S_ParseSndInfo (false);
|
||||
S_ParseSndSeq (-1);
|
||||
S_ParseMusInfo();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -477,14 +476,15 @@ void S_PrecacheLevel ()
|
|||
AActor *actor;
|
||||
TThinkerIterator<AActor> iterator;
|
||||
|
||||
while ( (actor = iterator.Next ()) != NULL )
|
||||
// Precache all sounds known to be used by the currently spawned actors.
|
||||
while ( (actor = iterator.Next()) != NULL )
|
||||
{
|
||||
S_sfx[actor->SeeSound].bUsed = true;
|
||||
S_sfx[actor->AttackSound].bUsed = true;
|
||||
S_sfx[actor->PainSound].bUsed = true;
|
||||
S_sfx[actor->DeathSound].bUsed = true;
|
||||
S_sfx[actor->ActiveSound].bUsed = true;
|
||||
S_sfx[actor->UseSound].bUsed = true;
|
||||
actor->MarkPrecacheSounds();
|
||||
}
|
||||
// Precache all extra sounds requested by this map.
|
||||
for (i = 0; i < level.info->PrecacheSounds.Size(); ++i)
|
||||
{
|
||||
level.info->PrecacheSounds[i].MarkUsed();
|
||||
}
|
||||
|
||||
for (i = 1; i < S_sfx.Size(); ++i)
|
||||
|
@ -1764,7 +1764,7 @@ void S_SetSoundPaused (int state)
|
|||
S_ResumeSound(true);
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
GSnd->SetInactive(false);
|
||||
GSnd->SetInactive(SoundRenderer::INACTIVE_Active);
|
||||
}
|
||||
if (!netgame
|
||||
#ifdef _DEBUG
|
||||
|
@ -1783,7 +1783,9 @@ void S_SetSoundPaused (int state)
|
|||
S_PauseSound(false, true);
|
||||
if (GSnd != NULL)
|
||||
{
|
||||
GSnd->SetInactive(true);
|
||||
GSnd->SetInactive(gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL ?
|
||||
SoundRenderer::INACTIVE_Complete :
|
||||
SoundRenderer::INACTIVE_Mute);
|
||||
}
|
||||
if (!netgame
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -65,6 +65,8 @@ struct sfxinfo_t
|
|||
|
||||
FRolloffInfo Rolloff;
|
||||
float Attenuation; // Multiplies the attenuation passed to S_Sound.
|
||||
|
||||
void MarkUsed(); // Marks this sound as used.
|
||||
};
|
||||
|
||||
// Rolloff types
|
||||
|
@ -132,6 +134,10 @@ public:
|
|||
{
|
||||
return ID ? S_sfx[ID].name.GetChars() : NULL;
|
||||
}
|
||||
void MarkUsed() const
|
||||
{
|
||||
S_sfx[ID].MarkUsed();
|
||||
}
|
||||
private:
|
||||
int ID;
|
||||
protected:
|
||||
|
@ -351,6 +357,7 @@ int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump ind
|
|||
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname);
|
||||
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);
|
||||
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false);
|
||||
void S_MarkPlayerSounds (const char *playerclass);
|
||||
void S_ShrinkPlayerSoundLists ();
|
||||
void S_UnloadSound (sfxinfo_t *sfx);
|
||||
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
||||
|
|
|
@ -177,6 +177,10 @@ void I_ClosestResolution (int *width, int *height, int bits)
|
|||
}
|
||||
}
|
||||
|
||||
void I_SetFPSLimit(int limit)
|
||||
{
|
||||
}
|
||||
|
||||
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
||||
|
||||
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
|
|
@ -59,6 +59,8 @@ void I_InitGraphics ();
|
|||
void I_ShutdownGraphics ();
|
||||
void I_CreateRenderer();
|
||||
|
||||
void I_SetFPSLimit(int limit);
|
||||
|
||||
extern IVideo *Video;
|
||||
|
||||
#endif // __HARDWARE_H__
|
||||
|
|
|
@ -672,6 +672,7 @@ bool FMODSoundRenderer::Init()
|
|||
PrevEnvironment = DefaultEnvironments[0];
|
||||
DSPClock.AsOne = 0;
|
||||
ChannelGroupTargetUnit = NULL;
|
||||
ChannelGroupTargetUnitOutput = NULL;
|
||||
SfxReverbHooked = false;
|
||||
SfxReverbPlaceholder = NULL;
|
||||
OutputPlugin = 0;
|
||||
|
@ -1155,6 +1156,15 @@ bool FMODSoundRenderer::Init()
|
|||
{
|
||||
ChannelGroupTargetUnit = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMOD::DSP *dontcare;
|
||||
result = ChannelGroupTargetUnit->getOutput(0, &dontcare, &ChannelGroupTargetUnitOutput);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
ChannelGroupTargetUnitOutput = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1598,6 +1608,7 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla
|
|||
FMOD::Sound *stream;
|
||||
FMOD_RESULT result;
|
||||
bool url;
|
||||
FString patches;
|
||||
|
||||
InitCreateSoundExInfo(&exinfo);
|
||||
mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM;
|
||||
|
@ -1614,7 +1625,20 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla
|
|||
exinfo.fileoffset = offset;
|
||||
if ((*snd_midipatchset)[0] != '\0')
|
||||
{
|
||||
exinfo.dlsname = snd_midipatchset;
|
||||
#ifdef _WIN32
|
||||
// If the path does not contain any path separators, automatically
|
||||
// prepend $PROGDIR to the path.
|
||||
if (strcspn(snd_midipatchset, ":/\\") == strlen(snd_midipatchset))
|
||||
{
|
||||
patches << "$PROGDIR/" << snd_midipatchset;
|
||||
patches = NicePath(patches);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
patches = NicePath(snd_midipatchset);
|
||||
}
|
||||
exinfo.dlsname = patches;
|
||||
}
|
||||
|
||||
url = (offset == 0 && length == 0 && strstr(filename_or_data, "://") > filename_or_data);
|
||||
|
@ -2109,11 +2133,33 @@ void FMODSoundRenderer::SetSfxPaused(bool paused, int slot)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::SetInactive(bool inactive)
|
||||
void FMODSoundRenderer::SetInactive(SoundRenderer::EInactiveState inactive)
|
||||
{
|
||||
float mix;
|
||||
bool active;
|
||||
|
||||
if (inactive == INACTIVE_Active)
|
||||
{
|
||||
mix = 1;
|
||||
active = true;
|
||||
}
|
||||
else if (inactive == INACTIVE_Complete)
|
||||
{
|
||||
mix = 1;
|
||||
active = false;
|
||||
}
|
||||
else // inactive == INACTIVE_Mute
|
||||
{
|
||||
mix = 0;
|
||||
active = true;
|
||||
}
|
||||
if (ChannelGroupTargetUnitOutput != NULL)
|
||||
{
|
||||
ChannelGroupTargetUnitOutput->setMix(mix);
|
||||
}
|
||||
if (ChannelGroupTargetUnit != NULL)
|
||||
{
|
||||
ChannelGroupTargetUnit->setActive(!inactive);
|
||||
ChannelGroupTargetUnit->setActive(active);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void SetSfxPaused (bool paused, int slot);
|
||||
|
||||
// Pauses or resumes *every* channel, including environmental reverb.
|
||||
void SetInactive (bool inactive);
|
||||
void SetInactive (EInactiveState inactive);
|
||||
|
||||
// Updates the position of a sound channel.
|
||||
void UpdateSoundParams3D (SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel);
|
||||
|
@ -107,6 +107,7 @@ private:
|
|||
FMOD::ChannelGroup *MusicGroup;
|
||||
FMOD::DSP *WaterLP, *WaterReverb;
|
||||
FMOD::DSPConnection *SfxConnection;
|
||||
FMOD::DSPConnection *ChannelGroupTargetUnitOutput;
|
||||
FMOD::DSP *ChannelGroupTargetUnit;
|
||||
FMOD::DSP *SfxReverbPlaceholder;
|
||||
bool SfxReverbHooked;
|
||||
|
|
|
@ -199,7 +199,7 @@ public:
|
|||
}
|
||||
|
||||
// Pauses or resumes *every* channel, including environmental reverb.
|
||||
void SetInactive(bool inactive)
|
||||
void SetInactive(SoundRenderer::EInactiveState inactive)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,13 @@ public:
|
|||
virtual void SetSfxPaused (bool paused, int slot) = 0;
|
||||
|
||||
// Pauses or resumes *every* channel, including environmental reverb.
|
||||
virtual void SetInactive(bool inactive) = 0;
|
||||
enum EInactiveState
|
||||
{
|
||||
INACTIVE_Active, // sound is active
|
||||
INACTIVE_Complete, // sound is completely paused
|
||||
INACTIVE_Mute // sound is only muted
|
||||
};
|
||||
virtual void SetInactive(EInactiveState inactive) = 0;
|
||||
|
||||
// Updates the volume, separation, and pitch of a sound channel.
|
||||
virtual void UpdateSoundParams3D (SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel) = 0;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "m_swap.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_text.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -471,7 +472,21 @@ int FluidSynthMIDIDevice::LoadPatchSets(const char *patches)
|
|||
count = 0;
|
||||
while (tok != NULL)
|
||||
{
|
||||
if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, tok, count == 0))
|
||||
FString path;
|
||||
#ifdef _WIN32
|
||||
// If the path does not contain any path separators, automatically
|
||||
// prepend $PROGDIR to the path.
|
||||
if (strcspn(tok, ":/\\") == strlen(tok))
|
||||
{
|
||||
path << "$PROGDIR/" << tok;
|
||||
path = NicePath(path);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
path = NicePath(tok);
|
||||
}
|
||||
if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, path, count == 0))
|
||||
{
|
||||
DPrintf("Loaded patch set %s.\n", tok);
|
||||
count++;
|
||||
|
|
|
@ -944,7 +944,13 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
|
|||
if (Restarting)
|
||||
{
|
||||
Restarting = false;
|
||||
events = WriteStopNotes(events); // Stop all notes in case any were left hanging.
|
||||
// Reset the tempo to the inital value.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
events[2] = (MEVT_TEMPO << 24) | InitialTempo; // dwEvent
|
||||
events += 3;
|
||||
// Stop all notes in case any were left hanging.
|
||||
events = WriteStopNotes(events);
|
||||
DoRestart();
|
||||
}
|
||||
events = MakeEvents(events, max_event_p, max_time);
|
||||
|
@ -1130,7 +1136,7 @@ void MIDIStreamer::Precache()
|
|||
void MIDIStreamer::CreateSMF(TArray<BYTE> &file, int looplimit)
|
||||
{
|
||||
DWORD delay = 0;
|
||||
BYTE running_status = 0;
|
||||
BYTE running_status = 255;
|
||||
|
||||
// Always create songs aimed at GM devices.
|
||||
CheckCaps(MOD_MIDIPORT);
|
||||
|
@ -1163,6 +1169,7 @@ void MIDIStreamer::CreateSMF(TArray<BYTE> &file, int looplimit)
|
|||
file.Push(BYTE(tempo >> 16));
|
||||
file.Push(BYTE(tempo >> 8));
|
||||
file.Push(BYTE(tempo));
|
||||
running_status = 255;
|
||||
}
|
||||
else if (MEVT_EVENTTYPE(event[2]) == MEVT_LONGMSG)
|
||||
{
|
||||
|
@ -1176,6 +1183,7 @@ void MIDIStreamer::CreateSMF(TArray<BYTE> &file, int looplimit)
|
|||
file.Push(MIDI_SYSEX);
|
||||
WriteVarLen(file, len);
|
||||
memcpy(&file[file.Reserve(len - 1)], bytes, len);
|
||||
running_status = 255;
|
||||
}
|
||||
}
|
||||
else if (MEVT_EVENTTYPE(event[2]) == 0)
|
||||
|
|
|
@ -608,10 +608,11 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
|||
}
|
||||
else
|
||||
{
|
||||
info.blendcolor[3] = b.a * FRACUNIT / 255;
|
||||
info.blendcolor[0] = b.r * (FRACUNIT-info.blendcolor[3]);
|
||||
info.blendcolor[1] = b.g * (FRACUNIT-info.blendcolor[3]);
|
||||
info.blendcolor[2] = b.b * (FRACUNIT-info.blendcolor[3]);
|
||||
fixed_t blendalpha = b.a * FRACUNIT / 255;
|
||||
info.blendcolor[0] = b.r * blendalpha;
|
||||
info.blendcolor[1] = b.g * blendalpha;
|
||||
info.blendcolor[2] = b.b * blendalpha;
|
||||
info.blendcolor[3] = FRACUNIT - blendalpha;
|
||||
info.blend = BLEND_OVERLAY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,6 +197,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
if (type->NumOwnedStates == 1)
|
||||
{
|
||||
type->OwnedStates->Tics = -1;
|
||||
type->OwnedStates->TicRange = 0;
|
||||
type->OwnedStates->Misc1 = 0;
|
||||
}
|
||||
else
|
||||
|
@ -224,6 +225,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
else
|
||||
{
|
||||
type->OwnedStates[i].Tics = -1;
|
||||
type->OwnedStates[i].TicRange = 0;
|
||||
type->OwnedStates[i].Misc1 = 0;
|
||||
}
|
||||
|
||||
|
@ -274,6 +276,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
else
|
||||
{
|
||||
type->OwnedStates[i].Tics = -1;
|
||||
type->OwnedStates[i].TicRange = 0;
|
||||
type->OwnedStates[i].Misc1 = 0;
|
||||
}
|
||||
|
||||
|
@ -308,12 +311,14 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
}
|
||||
type->OwnedStates[i].NextState = &type->OwnedStates[type->NumOwnedStates-1];
|
||||
type->OwnedStates[i].Tics = 5;
|
||||
type->OwnedStates[i].TicRange = 0;
|
||||
type->OwnedStates[i].Misc1 = 0;
|
||||
type->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeath")->Function);
|
||||
|
||||
i = type->NumOwnedStates - 1;
|
||||
type->OwnedStates[i].NextState = &type->OwnedStates[i];
|
||||
type->OwnedStates[i].Tics = 1;
|
||||
type->OwnedStates[i].TicRange = 0;
|
||||
type->OwnedStates[i].Misc1 = 0;
|
||||
type->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks")->Function);
|
||||
bag.statedef.SetStateLabel("Ice", &type->OwnedStates[extra.IceDeathStart]);
|
||||
|
@ -672,6 +677,7 @@ static void ParseSpriteFrames (PClassActor *info, TArray<FState> &states, FScann
|
|||
}
|
||||
|
||||
state.Tics = rate;
|
||||
state.TicRange = 0;
|
||||
|
||||
while (*token)
|
||||
{
|
||||
|
|
|
@ -170,7 +170,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void SetReplacement(PClassActor *info, FName replaceName)
|
||||
void SetReplacement(FScanner &sc, PClassActor *info, FName replaceName)
|
||||
{
|
||||
// Check for "replaces"
|
||||
if (replaceName != NAME_None)
|
||||
|
@ -180,7 +180,8 @@ void SetReplacement(PClassActor *info, FName replaceName)
|
|||
|
||||
if (replacee == NULL)
|
||||
{
|
||||
I_Error ("Replaced type '%s' not found in %s", replaceName.GetChars(), info->TypeName.GetChars());
|
||||
sc.ScriptMessage("Replaced type '%s' not found for %s", replaceName.GetChars(), info->TypeName.GetChars());
|
||||
return;
|
||||
}
|
||||
if (replacee != NULL)
|
||||
{
|
||||
|
|
|
@ -211,7 +211,7 @@ PSymbolActionFunction *FindGlobalActionFunction(const char *name);
|
|||
//==========================================================================
|
||||
|
||||
PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native);
|
||||
void SetReplacement(PClassActor *info, FName replaceName);
|
||||
void SetReplacement(FScanner &sc, PClassActor *info, FName replaceName);
|
||||
|
||||
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);
|
||||
void FinishActor(const FScriptPosition &sc, PClassActor *info, Baggage &bag);
|
||||
|
|
|
@ -355,9 +355,9 @@ static void DoAttack (AActor *self, bool domelee, bool domissile,
|
|||
else if (domissile && MissileType != NULL)
|
||||
{
|
||||
// This seemingly senseless code is needed for proper aiming.
|
||||
self->z += MissileHeight - 32*FRACUNIT;
|
||||
self->z += MissileHeight + self->GetBobOffset() - 32*FRACUNIT;
|
||||
AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, MissileType, false);
|
||||
self->z -= MissileHeight - 32*FRACUNIT;
|
||||
self->z -= MissileHeight + self->GetBobOffset() - 32*FRACUNIT;
|
||||
|
||||
if (missile)
|
||||
{
|
||||
|
@ -663,6 +663,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHealthLower)
|
|||
return numret;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State jump function
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetOutsideMeleeRange)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_STATE(jump);
|
||||
|
||||
if (!self->CheckMeleeRange())
|
||||
{
|
||||
ACTION_JUMP(jump);
|
||||
}
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
return numret;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State jump function
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInsideMeleeRange)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_STATE(jump);
|
||||
|
||||
if (self->CheckMeleeRange())
|
||||
{
|
||||
ACTION_JUMP(jump);
|
||||
}
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
return numret;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State jump function
|
||||
|
@ -799,12 +835,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
XF_HURTSOURCE = 1,
|
||||
XF_NOTMISSILE = 4,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT (damage) { damage = -1; }
|
||||
PARAM_INT_OPT (distance) { distance = -1; }
|
||||
PARAM_BOOL_OPT (hurtSource) { hurtSource = true; }
|
||||
PARAM_INT_OPT (flags) { flags = XF_HURTSOURCE; }
|
||||
PARAM_BOOL_OPT (alert) { alert = false; }
|
||||
PARAM_INT_OPT (fulldmgdistance) { fulldmgdistance = 0; }
|
||||
PARAM_INT_OPT (nails) { nails = 0; }
|
||||
|
@ -815,11 +857,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
|||
{
|
||||
damage = self->GetClass()->ExplosionDamage;
|
||||
distance = self->GetClass()->ExplosionRadius;
|
||||
if (distance < 0)
|
||||
{
|
||||
distance = damage;
|
||||
}
|
||||
hurtSource = !self->GetClass()->DontHurtShooter;
|
||||
flags = !self->GetClass()->DontHurtShooter;
|
||||
alert = false;
|
||||
}
|
||||
else
|
||||
|
@ -842,7 +880,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
|||
}
|
||||
}
|
||||
|
||||
P_RadiusAttack (self, self->target, damage, distance, self->DamageType, hurtSource, true, fulldmgdistance);
|
||||
P_RadiusAttack (self, self->target, damage, distance, self->DamageType, flags, fulldmgdistance);
|
||||
P_CheckSplash(self, distance<<FRACBITS);
|
||||
if (alert && self->target != NULL && self->target->player != NULL)
|
||||
{
|
||||
|
@ -852,43 +890,41 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
RTF_AFFECTSOURCE = 1,
|
||||
RTF_NOIMPACTDAMAGE = 2,
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_RadiusThrust
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
enum
|
||||
{
|
||||
RTF_AFFECTSOURCE = 1,
|
||||
RTF_NOIMPACTDAMAGE = 2,
|
||||
RTF_NOTMISSILE = 4,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT (force) { force = 128; }
|
||||
PARAM_INT_OPT (distance) { distance = -1; }
|
||||
PARAM_INT_OPT (thrustFlags) { thrustFlags = RTF_AFFECTSOURCE; }
|
||||
PARAM_INT_OPT (flags) { flags = RTF_AFFECTSOURCE; }
|
||||
PARAM_INT_OPT (fullthrustdistance) { fullthrustdistance = 0; }
|
||||
|
||||
bool affectSource = !!(thrustFlags & RTF_AFFECTSOURCE);
|
||||
bool noimpactdamage = !!(thrustFlags & RTF_NOIMPACTDAMAGE);
|
||||
|
||||
bool sourcenothrust = false;
|
||||
|
||||
if (force <= 0) force = 128;
|
||||
if (distance <= 0) distance = force;
|
||||
|
||||
// Temporarily negate MF2_NODMGTHRUST on the shooter, since it renders this function useless.
|
||||
if (self->target != NULL && self->target->flags2 & MF2_NODMGTHRUST)
|
||||
if (!(flags & RTF_NOTMISSILE) && self->target != NULL && self->target->flags2 & MF2_NODMGTHRUST)
|
||||
{
|
||||
sourcenothrust = true;
|
||||
self->target->flags2 &= ~MF2_NODMGTHRUST;
|
||||
}
|
||||
int sourceflags2 = self->target != NULL ? self->target->flags2 : 0;
|
||||
|
||||
P_RadiusAttack (self, self->target, force, distance, self->DamageType, affectSource, false, fullthrustdistance, noimpactdamage);
|
||||
P_RadiusAttack (self, self->target, force, distance, self->DamageType, flags | RADF_NODAMAGE, fullthrustdistance);
|
||||
P_CheckSplash(self, distance << FRACBITS);
|
||||
|
||||
if (sourcenothrust)
|
||||
|
@ -959,7 +995,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
|
|||
angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT;
|
||||
fixed_t x = spawnofs_xy * finecosine[ang];
|
||||
fixed_t y = spawnofs_xy * finesine[ang];
|
||||
fixed_t z = spawnheight - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
|
||||
fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
|
||||
|
||||
switch (aimmode)
|
||||
{
|
||||
|
@ -976,14 +1012,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
|
|||
break;
|
||||
|
||||
case 1:
|
||||
missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z+spawnheight, self, self->target, ti, false);
|
||||
missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + spawnheight, self, self->target, ti, false);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
self->x += x;
|
||||
self->y += y;
|
||||
missile = P_SpawnMissileAngleZSpeed(self, self->z+spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
|
||||
self->x -= x;
|
||||
missile = P_SpawnMissileAngleZSpeed(self, self->z + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
|
||||
self->x -= x;
|
||||
self->y -= y;
|
||||
|
||||
flags |= CMF_ABSOLUTEPITCH;
|
||||
|
@ -1210,9 +1246,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack)
|
|||
else if (ti)
|
||||
{
|
||||
// This seemingly senseless code is needed for proper aiming.
|
||||
self->z += spawnheight - 32*FRACUNIT;
|
||||
AActor *missile = P_SpawnMissileXYZ(self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false);
|
||||
self->z -= spawnheight - 32*FRACUNIT;
|
||||
self->z += spawnheight + self->GetBobOffset() - 32*FRACUNIT;
|
||||
AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false);
|
||||
self->z -= spawnheight + self->GetBobOffset() - 32*FRACUNIT;
|
||||
|
||||
if (missile)
|
||||
{
|
||||
|
@ -1951,7 +1987,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
|
|||
AActor *mo = Spawn(missile,
|
||||
self->x + FixedMul(distance, finecosine[self->angle>>ANGLETOFINESHIFT]),
|
||||
self->y + FixedMul(distance, finesine[self->angle>>ANGLETOFINESHIFT]),
|
||||
self->z - self->floorclip + zheight, ALLOW_REPLACE);
|
||||
self->z - self->floorclip + self->GetBobOffset() + zheight, ALLOW_REPLACE);
|
||||
|
||||
int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
|
||||
bool res = InitSpawnedItem(self, mo, flags);
|
||||
|
@ -2024,7 +2060,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
|
|||
xvel = newxvel;
|
||||
}
|
||||
|
||||
AActor *mo = Spawn(missile, x, y, self->z - self->floorclip + zofs, ALLOW_REPLACE);
|
||||
AActor * mo = Spawn(missile, x, y, self->z - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE);
|
||||
bool res = InitSpawnedItem(self, mo, flags);
|
||||
ACTION_SET_RESULT(res); // for an inventory item's use state
|
||||
if (mo)
|
||||
|
@ -2073,7 +2109,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade)
|
|||
AActor *bo;
|
||||
|
||||
bo = Spawn(missile, self->x, self->y,
|
||||
self->z - self->floorclip + zheight + 35*FRACUNIT + (self->player ? self->player->crouchoffset : 0),
|
||||
self->z - self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0),
|
||||
ALLOW_REPLACE);
|
||||
if (bo)
|
||||
{
|
||||
|
@ -2435,7 +2471,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris)
|
|||
{
|
||||
mo = Spawn(debris, self->x+((pr_spawndebris()-128)<<12),
|
||||
self->y+((pr_spawndebris()-128)<<12),
|
||||
self->z+(pr_spawndebris()*self->height/256), ALLOW_REPLACE);
|
||||
self->z+(pr_spawndebris()*self->height/256+self->GetBobOffset()), ALLOW_REPLACE);
|
||||
if (mo && transfer_translation)
|
||||
{
|
||||
mo->Translation = self->Translation;
|
||||
|
@ -2760,7 +2796,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
|
|||
mo = Spawn(chunk,
|
||||
self->x + (((pr_burst()-128)*self->radius)>>7),
|
||||
self->y + (((pr_burst()-128)*self->radius)>>7),
|
||||
self->z + (pr_burst()*self->height/255), ALLOW_REPLACE);
|
||||
self->z + (pr_burst()*self->height/255 + self->GetBobOffset()), ALLOW_REPLACE);
|
||||
|
||||
if (mo)
|
||||
{
|
||||
|
@ -4712,3 +4748,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_SetTics
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT(tics_to_set);
|
||||
|
||||
self->tics = tics_to_set;
|
||||
return 0;
|
||||
}
|
|
@ -276,6 +276,7 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_DUMMY_FLAG(NONETID), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(SERVERSIDEONLY), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless
|
||||
};
|
||||
|
||||
|
@ -297,6 +298,7 @@ static FFlagDef InventoryFlags[] =
|
|||
DEFINE_FLAG(IF, NOATTENPICKUPSOUND, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, PERSISTENTPOWER, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, RESTRICTABSOLUTELY, AInventory, ItemFlags),
|
||||
DEFINE_FLAG(IF, NEVERRESPAWN, AInventory, ItemFlags),
|
||||
|
||||
DEFINE_DEPRECATED_FLAG(PICKUPFLASH),
|
||||
DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),
|
||||
|
|
|
@ -1124,7 +1124,7 @@ static PClassActor *ParseActorHeader(FScanner &sc, Baggage *bag)
|
|||
info->DoomEdNum = DoomEdNum > 0 ? DoomEdNum : -1;
|
||||
info->SourceLumpName = Wads.GetLumpFullPath(sc.LumpNum);
|
||||
|
||||
SetReplacement(info, replaceName);
|
||||
SetReplacement(sc, info, replaceName);
|
||||
|
||||
ResetBaggage (bag, info == RUNTIME_CLASS(AActor) ? NULL : static_cast<PClassActor *>(info->ParentClass));
|
||||
bag->Info = info;
|
||||
|
|
|
@ -2280,6 +2280,26 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, jumpz, F, PlayerPawn)
|
|||
defaults->JumpZ = z;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(player, GruntSpeed, F, PlayerPawn)
|
||||
{
|
||||
PROP_FIXED_PARM(z, 0);
|
||||
defaults->GruntSpeed = z;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(player, FallingScreamSpeed, FF, PlayerPawn)
|
||||
{
|
||||
PROP_FIXED_PARM(minz, 0);
|
||||
PROP_FIXED_PARM(maxz, 0);
|
||||
defaults->FallingScreamMinSpeed = minz;
|
||||
defaults->FallingScreamMaxSpeed = maxz;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -2454,7 +2474,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, damagescreencolor, Cfs, PlayerPawn)
|
|||
PROP_STRING_PARM(type, 3);
|
||||
|
||||
color.a = BYTE(255 * clamp(a, 0.f, 1.f));
|
||||
info->SetPainFlash(type, color);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
|
||||
static_cast<PClassPlayerPawn *>(info)->PainFlashes.Insert(type, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "colormatcher.h"
|
||||
#include "thingdef_exp.h"
|
||||
#include "version.h"
|
||||
#include "templates.h"
|
||||
|
||||
TDeletingArray<FStateTempCall *> StateTempCalls;
|
||||
|
||||
|
@ -223,12 +224,34 @@ do_stop:
|
|||
sc.MustGetString();
|
||||
statestring = sc.String;
|
||||
|
||||
sc.MustGetNumber();
|
||||
state.Tics = clamp<int>(sc.Number, -1, 32767);
|
||||
if (tcall == NULL)
|
||||
{
|
||||
tcall = new FStateTempCall;
|
||||
}
|
||||
if (sc.CheckString("RANDOM"))
|
||||
{
|
||||
int min, max;
|
||||
|
||||
sc.MustGetStringName("(");
|
||||
sc.MustGetNumber();
|
||||
min = clamp<int>(sc.Number, -1, SHRT_MAX);
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
max = clamp<int>(sc.Number, -1, SHRT_MAX);
|
||||
sc.MustGetStringName(")");
|
||||
if (min > max)
|
||||
{
|
||||
swapvalues(min, max);
|
||||
}
|
||||
state.Tics = min;
|
||||
state.TicRange = max - min;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
state.Tics = clamp<int>(sc.Number, -1, SHRT_MAX);
|
||||
state.TicRange = 0;
|
||||
}
|
||||
|
||||
while (sc.GetString() && !sc.Crossed)
|
||||
{
|
||||
|
|
|
@ -120,15 +120,8 @@ void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int
|
|||
BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
|
||||
}
|
||||
|
||||
PainFlashList * pfl = CPlayer->mo->GetClass()->PainFlashes;
|
||||
PalEntry painFlash = CPlayer->mo->DamageFade;
|
||||
|
||||
if (pfl)
|
||||
{
|
||||
PalEntry * color = pfl->CheckKey(CPlayer->mo->DamageTypeReceived);
|
||||
|
||||
if (color) painFlash = *color;
|
||||
}
|
||||
CPlayer->mo->GetClass()->GetPainFlash(CPlayer->mo->DamageTypeReceived, &painFlash);
|
||||
|
||||
if (painFlash.a != 0)
|
||||
{
|
||||
|
|
|
@ -837,10 +837,10 @@ void DCanvas::FillBorder (FTexture *img)
|
|||
}
|
||||
else
|
||||
{
|
||||
Clear (0, 0, Width, bordtop, 0, 0); // Top
|
||||
Clear (0, bordtop, bordleft, Height - bordbottom, 0, 0); // Left
|
||||
Clear (Width - bordright, bordtop, Width, Height - bordbottom, 0, 0); // Right
|
||||
Clear (0, Height - bordbottom, Width, Height, 0, 0); // Bottom
|
||||
Clear (0, 0, Width, bordtop, GPalette.BlackIndex, 0); // Top
|
||||
Clear (0, bordtop, bordleft, Height - bordbottom, GPalette.BlackIndex, 0); // Left
|
||||
Clear (Width - bordright, bordtop, Width, Height - bordbottom, GPalette.BlackIndex, 0); // Right
|
||||
Clear (0, Height - bordbottom, Width, Height, GPalette.BlackIndex, 0); // Bottom
|
||||
}
|
||||
}
|
||||
|
||||
|
|
348
src/v_font.cpp
348
src/v_font.cpp
|
@ -124,16 +124,26 @@ public:
|
|||
FSingleLumpFont (const char *fontname, int lump);
|
||||
|
||||
protected:
|
||||
void CheckFON1Chars (int lump, const BYTE *data, double *luminosity);
|
||||
void CheckFON1Chars (double *luminosity);
|
||||
void BuildTranslations2 ();
|
||||
void FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette,
|
||||
bool rescale, PalEntry *out_palette);
|
||||
void LoadTranslations ();
|
||||
void LoadFON1 (int lump, const BYTE *data);
|
||||
void LoadFON2 (int lump, const BYTE *data);
|
||||
void LoadBMF (int lump, const BYTE *data);
|
||||
void CreateFontFromPic (FTextureID picnum);
|
||||
|
||||
static int STACK_ARGS BMFCompare(const void *a, const void *b);
|
||||
|
||||
enum
|
||||
{
|
||||
FONT1,
|
||||
FONT2,
|
||||
BMFFONT
|
||||
} FontType;
|
||||
BYTE PaletteData[768];
|
||||
bool RescalePalette;
|
||||
};
|
||||
|
||||
class FSinglePicFont : public FFont
|
||||
|
@ -153,16 +163,22 @@ protected:
|
|||
class FSpecialFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate);
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump);
|
||||
|
||||
void LoadTranslations();
|
||||
|
||||
protected:
|
||||
bool notranslate[256];
|
||||
};
|
||||
|
||||
// This is a font character that loads a texture and recolors it.
|
||||
class FFontChar1 : public FTexture
|
||||
{
|
||||
public:
|
||||
FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap);
|
||||
FFontChar1 (FTexture *sourcelump);
|
||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const BYTE *GetPixels ();
|
||||
void SetSourceRemap(const BYTE *sourceremap);
|
||||
void Unload ();
|
||||
~FFontChar1 ();
|
||||
|
||||
|
@ -178,11 +194,12 @@ protected:
|
|||
class FFontChar2 : public FTexture
|
||||
{
|
||||
public:
|
||||
FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||
~FFontChar2 ();
|
||||
|
||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const BYTE *GetPixels ();
|
||||
void SetSourceRemap(const BYTE *sourceremap);
|
||||
void Unload ();
|
||||
|
||||
protected:
|
||||
|
@ -322,18 +339,17 @@ FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start)
|
||||
FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump, int spacewidth)
|
||||
{
|
||||
int i;
|
||||
FTextureID lump;
|
||||
char buffer[12];
|
||||
FTexture **charlumps;
|
||||
BYTE usedcolors[256], identity[256];
|
||||
double *luminosity;
|
||||
int maxyoffs;
|
||||
bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
|
||||
bool stcfn121 = false;
|
||||
|
||||
Lump = fdlump;
|
||||
Chars = new CharData[count];
|
||||
charlumps = new FTexture *[count];
|
||||
PatchRemap = new BYTE[256];
|
||||
|
@ -341,7 +357,6 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
LastChar = first + count - 1;
|
||||
FontHeight = 0;
|
||||
GlobalKerning = false;
|
||||
memset (usedcolors, 0, 256);
|
||||
Name = copystring (name);
|
||||
Next = FirstFont;
|
||||
FirstFont = this;
|
||||
|
@ -392,18 +407,12 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
{
|
||||
FontHeight = height;
|
||||
}
|
||||
RecordTextureColors (pic, usedcolors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (charlumps[i] != NULL)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||
}
|
||||
else
|
||||
|
@ -413,7 +422,11 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
}
|
||||
}
|
||||
|
||||
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||
if (spacewidth != -1)
|
||||
{
|
||||
SpaceWidth = spacewidth;
|
||||
}
|
||||
else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||
{
|
||||
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||
}
|
||||
|
@ -424,9 +437,8 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
|
||||
FixXMoves();
|
||||
|
||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
||||
LoadTranslations();
|
||||
|
||||
delete[] luminosity;
|
||||
delete[] charlumps;
|
||||
}
|
||||
|
||||
|
@ -803,6 +815,42 @@ int FFont::GetCharWidth (int code) const
|
|||
return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: LoadTranslations
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFont::LoadTranslations()
|
||||
{
|
||||
unsigned int count = LastChar - FirstChar + 1;
|
||||
BYTE usedcolors[256], identity[256];
|
||||
double *luminosity;
|
||||
|
||||
memset (usedcolors, 0, 256);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].Pic);
|
||||
if(pic)
|
||||
{
|
||||
pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture
|
||||
RecordTextureColors (pic, usedcolors);
|
||||
}
|
||||
}
|
||||
|
||||
ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if(Chars[i].Pic)
|
||||
static_cast<FFontChar1 *>(Chars[i].Pic)->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
||||
|
||||
delete[] luminosity;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: Preload
|
||||
|
@ -854,8 +902,9 @@ void FFont::StaticPreloadFonts()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont::FFont ()
|
||||
FFont::FFont (int lump)
|
||||
{
|
||||
Lump = lump;
|
||||
Chars = NULL;
|
||||
PatchRemap = NULL;
|
||||
Name = NULL;
|
||||
|
@ -869,7 +918,7 @@ FFont::FFont ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSingleLumpFont::FSingleLumpFont (const char *name, int lump)
|
||||
FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
|
||||
{
|
||||
assert(lump >= 0);
|
||||
|
||||
|
@ -927,6 +976,51 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
|||
ActiveColors = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSingleLumpFont :: LoadTranslations
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::LoadTranslations()
|
||||
{
|
||||
double luminosity[256];
|
||||
BYTE identity[256];
|
||||
PalEntry local_palette[256];
|
||||
bool useidentity = true;
|
||||
bool usepalette = false;
|
||||
const void* ranges;
|
||||
unsigned int count = LastChar - FirstChar + 1;
|
||||
|
||||
switch(FontType)
|
||||
{
|
||||
case FONT1:
|
||||
useidentity = false;
|
||||
ranges = &TranslationParms[1][0];
|
||||
CheckFON1Chars (luminosity);
|
||||
break;
|
||||
|
||||
case BMFFONT:
|
||||
case FONT2:
|
||||
usepalette = true;
|
||||
FixupPalette (identity, luminosity, PaletteData, RescalePalette, local_palette);
|
||||
|
||||
ranges = &TranslationParms[0][0];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0;i < count;++i)
|
||||
{
|
||||
if(Chars[i].Pic)
|
||||
static_cast<FFontChar2*>(Chars[i].Pic)->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSingleLumpFont :: LoadFON1
|
||||
|
@ -937,7 +1031,6 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
|||
|
||||
void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data)
|
||||
{
|
||||
double luminosity[256];
|
||||
int w, h;
|
||||
|
||||
Chars = new CharData[256];
|
||||
|
@ -945,6 +1038,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data)
|
|||
w = data[4] + data[5]*256;
|
||||
h = data[6] + data[7]*256;
|
||||
|
||||
FontType = FONT1;
|
||||
FontHeight = h;
|
||||
SpaceWidth = w;
|
||||
FirstChar = 0;
|
||||
|
@ -952,8 +1046,10 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data)
|
|||
GlobalKerning = 0;
|
||||
PatchRemap = new BYTE[256];
|
||||
|
||||
CheckFON1Chars (lump, data, luminosity);
|
||||
BuildTranslations (luminosity, NULL, &TranslationParms[1][0], ActiveColors, NULL);
|
||||
for(unsigned int i = 0;i < 256;++i)
|
||||
Chars[i].Pic = NULL;
|
||||
|
||||
LoadTranslations();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -969,17 +1065,17 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
|||
{
|
||||
int count, i, totalwidth;
|
||||
int *widths2;
|
||||
BYTE identity[256];
|
||||
double luminosity[256];
|
||||
PalEntry local_palette[256];
|
||||
WORD *widths;
|
||||
const BYTE *palette;
|
||||
const BYTE *data_p;
|
||||
|
||||
FontType = FONT2;
|
||||
FontHeight = data[4] + data[5]*256;
|
||||
FirstChar = data[6];
|
||||
LastChar = data[7];
|
||||
ActiveColors = data[10];
|
||||
PatchRemap = NULL;
|
||||
RescalePalette = data[9] == 0;
|
||||
|
||||
count = LastChar - FirstChar + 1;
|
||||
Chars = new CharData[count];
|
||||
|
@ -1029,7 +1125,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
|||
SpaceWidth = totalwidth * 2 / (3 * count);
|
||||
}
|
||||
|
||||
FixupPalette (identity, luminosity, palette, data[9] == 0, local_palette);
|
||||
memcpy(PaletteData, palette, (ActiveColors+1)*3);
|
||||
|
||||
data_p = palette + (ActiveColors+1)*3;
|
||||
|
||||
|
@ -1043,7 +1139,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
Chars[i].Pic = new FFontChar2 (lump, NULL, int(data_p - data), widths2[i], FontHeight);
|
||||
Chars[i].Pic = new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight);
|
||||
do
|
||||
{
|
||||
SBYTE code = *data_p++;
|
||||
|
@ -1066,7 +1162,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
|||
}
|
||||
}
|
||||
|
||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette);
|
||||
LoadTranslations();
|
||||
delete[] widths2;
|
||||
}
|
||||
|
||||
|
@ -1087,15 +1183,14 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
|||
int i, chari;
|
||||
BYTE raw_palette[256*3];
|
||||
PalEntry sort_palette[256];
|
||||
PalEntry local_palette[256];
|
||||
double luminosity[256];
|
||||
BYTE identity[256];
|
||||
|
||||
FontType = BMFFONT;
|
||||
FontHeight = data[5];
|
||||
GlobalKerning = (SBYTE)data[8];
|
||||
ActiveColors = data[16];
|
||||
SpaceWidth = -1;
|
||||
nwidth = -1;
|
||||
RescalePalette = true;
|
||||
|
||||
infolen = data[17 + ActiveColors*3];
|
||||
chardata = data + 18 + ActiveColors*3 + infolen;
|
||||
|
@ -1160,7 +1255,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
|||
PatchRemap[sort_palette[i].a] = i;
|
||||
}
|
||||
|
||||
FixupPalette(identity, luminosity, raw_palette, true, local_palette);
|
||||
memcpy(PaletteData, raw_palette, 768);
|
||||
|
||||
// Now scan through the characters again, creating glyphs for each one.
|
||||
for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2])
|
||||
|
@ -1180,7 +1275,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
|||
{ // Empty character: skip it.
|
||||
continue;
|
||||
}
|
||||
Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data),
|
||||
Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, int(chardata + chari + 6 - data),
|
||||
chardata[chari+1], // width
|
||||
chardata[chari+2], // height
|
||||
-(SBYTE)chardata[chari+3], // x offset
|
||||
|
@ -1202,7 +1297,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
|||
}
|
||||
|
||||
FixXMoves();
|
||||
BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette);
|
||||
LoadTranslations();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1232,8 +1327,11 @@ int STACK_ARGS FSingleLumpFont::BMFCompare(const void *a, const void *b)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *luminosity)
|
||||
void FSingleLumpFont::CheckFON1Chars (double *luminosity)
|
||||
{
|
||||
FMemLump memLump = Wads.ReadLump(Lump);
|
||||
const BYTE* data = (const BYTE*) memLump.GetMem();
|
||||
|
||||
BYTE used[256], reverse[256];
|
||||
const BYTE *data_p;
|
||||
int i, j;
|
||||
|
@ -1245,8 +1343,11 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino
|
|||
{
|
||||
int destSize = SpaceWidth * FontHeight;
|
||||
|
||||
Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight);
|
||||
Chars[i].XMove = SpaceWidth;
|
||||
if(!Chars[i].Pic)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight);
|
||||
Chars[i].XMove = SpaceWidth;
|
||||
}
|
||||
|
||||
// Advance to next char's data and count the used colors.
|
||||
do
|
||||
|
@ -1304,7 +1405,7 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY
|
|||
identity[0] = 0;
|
||||
palette += 3; // Skip the transparent color
|
||||
|
||||
for (i = 1; i <= ActiveColors; ++i, palette += 3)
|
||||
for (i = 1; i < ActiveColors; ++i, palette += 3)
|
||||
{
|
||||
int r = palette[0];
|
||||
int g = palette[1];
|
||||
|
@ -1331,7 +1432,7 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY
|
|||
{
|
||||
diver = 1.0 / 255.0;
|
||||
}
|
||||
for (i = 1; i <= ActiveColors; ++i)
|
||||
for (i = 1; i < ActiveColors; ++i)
|
||||
{
|
||||
luminosity[i] = (luminosity[i] - minlum) * diver;
|
||||
}
|
||||
|
@ -1347,7 +1448,8 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSinglePicFont::FSinglePicFont(const char *picname)
|
||||
FSinglePicFont::FSinglePicFont(const char *picname) :
|
||||
FFont(-1) // Since lump is only needed for priority information we don't need to worry about this here.
|
||||
{
|
||||
FTextureID picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Any);
|
||||
|
||||
|
@ -1413,8 +1515,8 @@ int FSinglePicFont::GetCharWidth (int code) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFontChar1::FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap)
|
||||
: SourceRemap (sourceremap)
|
||||
FFontChar1::FFontChar1 (FTexture *sourcelump)
|
||||
: SourceRemap (NULL)
|
||||
{
|
||||
UseType = FTexture::TEX_FontChar;
|
||||
BaseTexture = sourcelump;
|
||||
|
@ -1453,9 +1555,16 @@ void FFontChar1::MakeTexture ()
|
|||
Pixels = new BYTE[Width*Height];
|
||||
const BYTE *pix = BaseTexture->GetPixels();
|
||||
|
||||
for (int x = 0; x < Width*Height; ++x)
|
||||
if (!SourceRemap)
|
||||
{
|
||||
Pixels[x] = SourceRemap[pix[x]];
|
||||
memcpy(Pixels, pix, Width*Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < Width*Height; ++x)
|
||||
{
|
||||
Pixels[x] = SourceRemap[pix[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1476,6 +1585,18 @@ const BYTE *FFontChar1::GetColumn (unsigned int column, const Span **spans_out)
|
|||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFontChar1 :: SetSourceRemap
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFontChar1::SetSourceRemap(const BYTE *sourceremap)
|
||||
{
|
||||
Unload();
|
||||
SourceRemap = sourceremap;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFontChar1 :: Unload
|
||||
|
@ -1510,8 +1631,8 @@ FFontChar1::~FFontChar1 ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs, int topofs)
|
||||
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap)
|
||||
FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
|
||||
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(NULL)
|
||||
{
|
||||
UseType = TEX_FontChar;
|
||||
Width = width;
|
||||
|
@ -1594,6 +1715,18 @@ const BYTE *FFontChar2::GetColumn (unsigned int column, const Span **spans_out)
|
|||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFontChar2 :: SetSourceRemap
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFontChar2::SetSourceRemap(const BYTE *sourceremap)
|
||||
{
|
||||
Unload();
|
||||
SourceRemap = sourceremap;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFontChar2 :: MakeTexture
|
||||
|
@ -1730,16 +1863,15 @@ void FFontChar2::MakeTexture ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate)
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump) : FFont(lump)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
FTexture **charlumps;
|
||||
BYTE usedcolors[256], identity[256];
|
||||
double *luminosity;
|
||||
int maxyoffs;
|
||||
int TotalColors;
|
||||
FTexture *pic;
|
||||
|
||||
|
||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
||||
|
||||
Name = copystring(name);
|
||||
Chars = new CharData[count];
|
||||
charlumps = new FTexture*[count];
|
||||
|
@ -1748,7 +1880,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
LastChar = first + count - 1;
|
||||
FontHeight = 0;
|
||||
GlobalKerning = false;
|
||||
memset (usedcolors, 0, 256);
|
||||
Next = FirstFont;
|
||||
FirstFont = this;
|
||||
|
||||
|
@ -1771,7 +1902,58 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
{
|
||||
FontHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
if (charlumps[i] != NULL)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].Pic = NULL;
|
||||
Chars[i].XMove = INT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
// Special fonts normally don't have all characters so be careful here!
|
||||
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||
{
|
||||
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpaceWidth = 4;
|
||||
}
|
||||
|
||||
FixXMoves();
|
||||
|
||||
LoadTranslations();
|
||||
|
||||
delete[] charlumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSpecialFont :: LoadTranslations
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSpecialFont::LoadTranslations()
|
||||
{
|
||||
int count = LastChar - FirstChar + 1;
|
||||
BYTE usedcolors[256], identity[256];
|
||||
double *luminosity;
|
||||
int TotalColors;
|
||||
int i, j;
|
||||
|
||||
memset (usedcolors, 0, 256);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].Pic);
|
||||
if(pic)
|
||||
{
|
||||
pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture
|
||||
RecordTextureColors (pic, usedcolors);
|
||||
}
|
||||
}
|
||||
|
@ -1802,30 +1984,10 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (charlumps[i] != NULL)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].Pic = NULL;
|
||||
Chars[i].XMove = INT_MIN;
|
||||
}
|
||||
if(Chars[i].Pic)
|
||||
static_cast<FFontChar1 *>(Chars[i].Pic)->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
// Special fonts normally don't have all characters so be careful here!
|
||||
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||
{
|
||||
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpaceWidth = 4;
|
||||
}
|
||||
|
||||
FixXMoves();
|
||||
|
||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
|
||||
|
||||
// add the untranslated colors to the Ranges tables
|
||||
|
@ -1845,7 +2007,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
ActiveColors = TotalColors;
|
||||
|
||||
delete[] luminosity;
|
||||
delete[] charlumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1899,6 +2060,7 @@ void V_InitCustomFonts()
|
|||
int start;
|
||||
int first;
|
||||
int count;
|
||||
int spacewidth;
|
||||
char cursor = '_';
|
||||
|
||||
while ((llump = Wads.FindLump ("FONTDEFS", &lastlump)) != -1)
|
||||
|
@ -1913,6 +2075,7 @@ void V_InitCustomFonts()
|
|||
start = 33;
|
||||
first = 33;
|
||||
count = 223;
|
||||
spacewidth = -1;
|
||||
|
||||
sc.MustGetStringName ("{");
|
||||
while (!sc.CheckString ("}"))
|
||||
|
@ -1951,6 +2114,13 @@ void V_InitCustomFonts()
|
|||
sc.MustGetString();
|
||||
cursor = sc.String[0];
|
||||
}
|
||||
else if (sc.Compare ("SPACEWIDTH"))
|
||||
{
|
||||
if (format == 2) goto wrong;
|
||||
sc.MustGetNumber();
|
||||
spacewidth = sc.Number;
|
||||
format = 1;
|
||||
}
|
||||
else if (sc.Compare ("NOTRANSLATION"))
|
||||
{
|
||||
if (format == 1) goto wrong;
|
||||
|
@ -1994,7 +2164,7 @@ void V_InitCustomFonts()
|
|||
}
|
||||
if (format == 1)
|
||||
{
|
||||
FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start);
|
||||
FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump, spacewidth);
|
||||
fnt->SetCursor(cursor);
|
||||
}
|
||||
else if (format == 2)
|
||||
|
@ -2017,7 +2187,7 @@ void V_InitCustomFonts()
|
|||
}
|
||||
if (count > 0)
|
||||
{
|
||||
FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate);
|
||||
FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump);
|
||||
fnt->SetCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
@ -2396,19 +2566,19 @@ void V_InitFonts()
|
|||
}
|
||||
else if (Wads.CheckNumForName ("FONTA_S") >= 0)
|
||||
{
|
||||
SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1);
|
||||
SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
SmallFont->SetCursor('[');
|
||||
}
|
||||
else
|
||||
{
|
||||
SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
|
||||
SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
|
||||
}
|
||||
}
|
||||
if (!(SmallFont2 = FFont::FindFont("SmallFont2"))) // Only used by Strife
|
||||
{
|
||||
if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0)
|
||||
{
|
||||
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
|
||||
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2427,7 +2597,7 @@ void V_InitFonts()
|
|||
}
|
||||
else
|
||||
{
|
||||
BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1);
|
||||
BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
}
|
||||
}
|
||||
if (!(ConFont = FFont::FindFont("ConsoleFont")))
|
||||
|
@ -2455,4 +2625,14 @@ void V_ClearFonts()
|
|||
}
|
||||
FFont::FirstFont = NULL;
|
||||
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void V_RetranslateFonts()
|
||||
{
|
||||
FFont *font = FFont::FirstFont;
|
||||
while(font)
|
||||
{
|
||||
font->LoadTranslations();
|
||||
font = font->Next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,15 +76,17 @@ extern int NumTextColors;
|
|||
class FFont
|
||||
{
|
||||
public:
|
||||
FFont (const char *fontname, const char *nametemplate, int first, int count, int base);
|
||||
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1);
|
||||
virtual ~FFont ();
|
||||
|
||||
virtual FTexture *GetChar (int code, int *const width) const;
|
||||
virtual int GetCharWidth (int code) const;
|
||||
FRemapTable *GetColorTranslation (EColorRange range) const;
|
||||
int GetLump() const { return Lump; }
|
||||
int GetSpaceWidth () const { return SpaceWidth; }
|
||||
int GetHeight () const { return FontHeight; }
|
||||
int GetDefaultKerning () const { return GlobalKerning; }
|
||||
virtual void LoadTranslations();
|
||||
void Preload() const;
|
||||
|
||||
static FFont *FindFont (const char *fontname);
|
||||
|
@ -99,7 +101,7 @@ public:
|
|||
void SetCursor(char c) { Cursor = c; }
|
||||
|
||||
protected:
|
||||
FFont ();
|
||||
FFont (int lump);
|
||||
|
||||
void BuildTranslations (const double *luminosity, const BYTE *identity,
|
||||
const void *ranges, int total_colors, const PalEntry *palette);
|
||||
|
@ -122,6 +124,7 @@ protected:
|
|||
TArray<FRemapTable> Ranges;
|
||||
BYTE *PatchRemap;
|
||||
|
||||
int Lump;
|
||||
char *Name;
|
||||
FFont *Next;
|
||||
|
||||
|
@ -129,6 +132,7 @@ protected:
|
|||
friend struct FontsDeleter;
|
||||
|
||||
friend void V_ClearFonts();
|
||||
friend void V_RetranslateFonts();
|
||||
|
||||
friend FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font);
|
||||
};
|
||||
|
@ -143,5 +147,6 @@ PalEntry V_LogColorFromColorRange (EColorRange range);
|
|||
EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor);
|
||||
FFont *V_GetFont(const char *);
|
||||
void V_InitFontColors();
|
||||
void V_RetranslateFonts();
|
||||
|
||||
#endif //__V_FONT_H__
|
||||
|
|
|
@ -159,8 +159,8 @@ void FPalette::SetPalette (const BYTE *colors)
|
|||
// Find white and black from the original palette so that they can be
|
||||
// used to make an educated guess of the translucency % for a BOOM
|
||||
// translucency map.
|
||||
WhiteIndex = BestColor ((DWORD *)BaseColors, 255, 255, 255);
|
||||
BlackIndex = BestColor ((DWORD *)BaseColors, 0, 0, 0);
|
||||
WhiteIndex = BestColor ((DWORD *)BaseColors, 255, 255, 255, 0, 255);
|
||||
BlackIndex = BestColor ((DWORD *)BaseColors, 0, 0, 0, 0, 255);
|
||||
}
|
||||
|
||||
// In ZDoom's new texture system, color 0 is used as the transparent color.
|
||||
|
|
|
@ -859,7 +859,7 @@ void DFrameBuffer::DrawRateStuff ()
|
|||
|
||||
chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount);
|
||||
rate_x = Width - chars * 8;
|
||||
Clear (rate_x, 0, Width, 8, 0, 0);
|
||||
Clear (rate_x, 0, Width, 8, GPalette.BlackIndex, 0);
|
||||
DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0], TAG_DONE);
|
||||
|
||||
DWORD thisSec = ms/1000;
|
||||
|
@ -1324,10 +1324,7 @@ CCMD(clean)
|
|||
bool V_DoModeSetup (int width, int height, int bits)
|
||||
{
|
||||
DFrameBuffer *buff = I_SetMode (width, height, screen);
|
||||
int ratio;
|
||||
int cwidth;
|
||||
int cheight;
|
||||
int cx1, cy1, cx2, cy2;
|
||||
int cx1, cx2;
|
||||
|
||||
if (buff == NULL)
|
||||
{
|
||||
|
@ -1342,41 +1339,7 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
// if D3DFB is being used for the display.
|
||||
FFont::StaticPreloadFonts();
|
||||
|
||||
ratio = CheckRatio (width, height);
|
||||
if (ratio & 4)
|
||||
{
|
||||
cwidth = width;
|
||||
cheight = height * BaseRatioSizes[ratio][3] / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
cwidth = width * BaseRatioSizes[ratio][3] / 48;
|
||||
cheight = height;
|
||||
}
|
||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
||||
// between CleanXfac and CleanYfac.
|
||||
cx1 = MAX(cwidth / 320, 1);
|
||||
cy1 = MAX(cheight / 200, 1);
|
||||
cx2 = MAX(width / 320, 1);
|
||||
cy2 = MAX(height / 200, 1);
|
||||
if (abs(cx1 - cy1) <= abs(cx2 - cy2))
|
||||
{ // e.g. 640x360 looks better with this.
|
||||
CleanXfac = cx1;
|
||||
CleanYfac = cy1;
|
||||
}
|
||||
else
|
||||
{ // e.g. 720x480 looks better with this.
|
||||
CleanXfac = cx2;
|
||||
CleanYfac = cy2;
|
||||
}
|
||||
|
||||
if (CleanXfac > 1 && CleanYfac > 1 && CleanXfac != CleanYfac)
|
||||
{
|
||||
if (CleanXfac < CleanYfac)
|
||||
CleanYfac = CleanXfac;
|
||||
else
|
||||
CleanXfac = CleanYfac;
|
||||
}
|
||||
V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2);
|
||||
|
||||
CleanWidth = width / CleanXfac;
|
||||
CleanHeight = height / CleanYfac;
|
||||
|
@ -1426,6 +1389,52 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
return true;
|
||||
}
|
||||
|
||||
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)
|
||||
{
|
||||
int ratio;
|
||||
int cwidth;
|
||||
int cheight;
|
||||
int cx1, cy1, cx2, cy2;
|
||||
|
||||
ratio = CheckRatio(realwidth, realheight);
|
||||
if (ratio & 4)
|
||||
{
|
||||
cwidth = realwidth;
|
||||
cheight = realheight * BaseRatioSizes[ratio][3] / 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
cwidth = realwidth * BaseRatioSizes[ratio][3] / 48;
|
||||
cheight = realheight;
|
||||
}
|
||||
// Use whichever pair of cwidth/cheight or width/height that produces less difference
|
||||
// between CleanXfac and CleanYfac.
|
||||
cx1 = MAX(cwidth / designwidth, 1);
|
||||
cy1 = MAX(cheight / designheight, 1);
|
||||
cx2 = MAX(realwidth / designwidth, 1);
|
||||
cy2 = MAX(realheight / designheight, 1);
|
||||
if (abs(cx1 - cy1) <= abs(cx2 - cy2))
|
||||
{ // e.g. 640x360 looks better with this.
|
||||
*cleanx = cx1;
|
||||
*cleany = cy1;
|
||||
}
|
||||
else
|
||||
{ // e.g. 720x480 looks better with this.
|
||||
*cleanx = cx2;
|
||||
*cleany = cy2;
|
||||
}
|
||||
|
||||
if (*cleanx > 1 && *cleany > 1 && *cleanx != *cleany)
|
||||
{
|
||||
if (*cleanx < *cleany)
|
||||
*cleany = *cleanx;
|
||||
else
|
||||
*cleanx = *cleany;
|
||||
}
|
||||
if (_cx1 != NULL) *_cx1 = cx1;
|
||||
if (_cx2 != NULL) *_cx2 = cx2;
|
||||
}
|
||||
|
||||
bool IVideo::SetResolution (int width, int height, int bits)
|
||||
{
|
||||
int oldwidth, oldheight;
|
||||
|
|
|
@ -46,6 +46,7 @@ extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;
|
|||
extern int DisplayWidth, DisplayHeight, DisplayBits;
|
||||
|
||||
bool V_DoModeSetup (int width, int height, int bits);
|
||||
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *cx1=NULL, int *cx2=NULL);
|
||||
|
||||
class FTexture;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ static inline const char *MakeSaveSig()
|
|||
#define BUGS_FORUM_URL "http://forum.zdoom.org/index.php?c=3"
|
||||
|
||||
#ifdef unix
|
||||
#define GAME_DIR ".zdoom"
|
||||
#define GAME_DIR ".config/zdoom"
|
||||
#elif defined(__APPLE__)
|
||||
#define GAME_DIR GAMENAME
|
||||
#else
|
||||
|
|
|
@ -1588,30 +1588,36 @@ void WI_updateNetgameStats ()
|
|||
|
||||
void WI_drawNetgameStats ()
|
||||
{
|
||||
int i, x, y, height;
|
||||
int maxnamewidth, maxscorewidth;
|
||||
int i, x, y, ypadding, height, lineheight;
|
||||
int maxnamewidth, maxscorewidth, maxiconheight;
|
||||
int pwidth = IntermissionFont->GetCharWidth('%');
|
||||
int icon_x, name_x, kills_x, bonus_x, secret_x;
|
||||
int bonus_len, secret_len;
|
||||
int missed_kills, missed_items, missed_secrets;
|
||||
EColorRange color;
|
||||
const char *bonus_label;
|
||||
const char *text_bonus, *text_color, *text_secret, *text_kills;
|
||||
|
||||
// draw animated background
|
||||
WI_drawBackground();
|
||||
|
||||
y = WI_drawLF();
|
||||
|
||||
HU_GetPlayerWidths(maxnamewidth, maxscorewidth);
|
||||
HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight);
|
||||
height = SmallFont->GetHeight() * CleanYfac;
|
||||
lineheight = MAX(height, maxiconheight * CleanYfac);
|
||||
ypadding = (lineheight - height + 1) / 2;
|
||||
y += 16*CleanYfac;
|
||||
|
||||
bonus_label = (gameinfo.gametype & GAME_Raven) ? "BONUS" : "ITEMS";
|
||||
icon_x = (SmallFont->StringWidth("COLOR") + 8) * CleanXfac;
|
||||
text_bonus = GStrings((gameinfo.gametype & GAME_Raven) ? "SCORE_BONUS" : "SCORE_ITEMS");
|
||||
text_color = GStrings("SCORE_COLOR");
|
||||
text_secret = GStrings("SCORE_SECRET");
|
||||
text_kills = GStrings("SCORE_KILLS");
|
||||
|
||||
icon_x = (SmallFont->StringWidth(text_color) + 8) * CleanXfac;
|
||||
name_x = icon_x + maxscorewidth * CleanXfac;
|
||||
kills_x = name_x + (maxnamewidth + SmallFont->StringWidth("XXXXX") + 8) * CleanXfac;
|
||||
bonus_x = kills_x + ((bonus_len = SmallFont->StringWidth(bonus_label)) + 8) * CleanXfac;
|
||||
secret_x = bonus_x + ((secret_len = SmallFont->StringWidth("SECRET")) + 8) * CleanXfac;
|
||||
kills_x = name_x + (maxnamewidth + MAX(SmallFont->StringWidth("XXXXX"), SmallFont->StringWidth(text_kills)) + 8) * CleanXfac;
|
||||
bonus_x = kills_x + ((bonus_len = SmallFont->StringWidth(text_bonus)) + 8) * CleanXfac;
|
||||
secret_x = bonus_x + ((secret_len = SmallFont->StringWidth(text_secret)) + 8) * CleanXfac;
|
||||
|
||||
x = (SCREENWIDTH - secret_x) >> 1;
|
||||
icon_x += x;
|
||||
|
@ -1622,11 +1628,11 @@ void WI_drawNetgameStats ()
|
|||
|
||||
color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED;
|
||||
|
||||
screen->DrawText(SmallFont, color, x, y, "COLOR", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, name_x, y, "NAME", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, kills_x - SmallFont->StringWidth("KILLS")*CleanXfac, y, "KILLS", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, bonus_x - bonus_len*CleanXfac, y, bonus_label, DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, secret_x - secret_len*CleanXfac, y, "SECRET", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, x, y, text_color, DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_NAME"), DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, kills_x - SmallFont->StringWidth(text_kills)*CleanXfac, y, text_kills, DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, bonus_x - bonus_len*CleanXfac, y, text_bonus, DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, secret_x - secret_len*CleanXfac, y, text_secret, DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += height + 6 * CleanYfac;
|
||||
|
||||
missed_kills = wbs->maxkills;
|
||||
|
@ -1642,32 +1648,32 @@ void WI_drawNetgameStats ()
|
|||
continue;
|
||||
|
||||
player = &players[i];
|
||||
HU_DrawColorBar(x, y, height, i);
|
||||
HU_DrawColorBar(x, y, lineheight, i);
|
||||
color = (EColorRange)HU_GetRowColor(player, i == consoleplayer);
|
||||
if (player->mo->ScoreIcon.isValid())
|
||||
{
|
||||
FTexture *pic = TexMan[player->mo->ScoreIcon];
|
||||
screen->DrawTexture(pic, icon_x, y, DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
screen->DrawText(SmallFont, color, name_x, y, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE);
|
||||
WI_drawPercent(SmallFont, kills_x, y, cnt_kills[i], wbs->maxkills, false, color);
|
||||
screen->DrawText(SmallFont, color, name_x, y + ypadding, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE);
|
||||
WI_drawPercent(SmallFont, kills_x, y + ypadding, cnt_kills[i], wbs->maxkills, false, color);
|
||||
missed_kills -= cnt_kills[i];
|
||||
if (ng_state >= 4)
|
||||
{
|
||||
WI_drawPercent(SmallFont, bonus_x, y, cnt_items[i], wbs->maxitems, false, color);
|
||||
WI_drawPercent(SmallFont, bonus_x, y + ypadding, cnt_items[i], wbs->maxitems, false, color);
|
||||
missed_items -= cnt_items[i];
|
||||
if (ng_state >= 6)
|
||||
{
|
||||
WI_drawPercent(SmallFont, secret_x, y, cnt_secret[i], wbs->maxsecret, false, color);
|
||||
WI_drawPercent(SmallFont, secret_x, y + ypadding, cnt_secret[i], wbs->maxsecret, false, color);
|
||||
missed_secrets -= cnt_secret[i];
|
||||
}
|
||||
}
|
||||
y += height + CleanYfac;
|
||||
y += lineheight + CleanYfac;
|
||||
}
|
||||
|
||||
// Draw "MISSED" line
|
||||
y += 5 * CleanYfac;
|
||||
screen->DrawText(SmallFont, CR_DARKGRAY, name_x, y, "MISSED", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, CR_DARKGRAY, name_x, y, GStrings("SCORE_MISSED"), DTA_CleanNoMove, true, TAG_DONE);
|
||||
WI_drawPercent(SmallFont, kills_x, y, missed_kills, wbs->maxkills, false, CR_DARKGRAY);
|
||||
if (ng_state >= 4)
|
||||
{
|
||||
|
@ -1681,7 +1687,7 @@ void WI_drawNetgameStats ()
|
|||
// Draw "TOTAL" line
|
||||
y += height + 5 * CleanYfac;
|
||||
color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED;
|
||||
screen->DrawText(SmallFont, color, name_x, y, "TOTAL", DTA_CleanNoMove, true, TAG_DONE);
|
||||
screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_TOTAL"), DTA_CleanNoMove, true, TAG_DONE);
|
||||
WI_drawNum(SmallFont, kills_x, y, wbs->maxkills, 0, false, color);
|
||||
if (ng_state >= 4)
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue