mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
fbefe13bb2
21 changed files with 388 additions and 89 deletions
|
@ -111,6 +111,6 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
CHECK_CXX_COMPILER_FLAG( -msse DUMB_CAN_USE_SSE )
|
||||
|
||||
if( DUMB_CAN_USE_SSE )
|
||||
set_source_files_properties( src/it/filter.cpp PROPERTIES COMPILE_FLAGS -msse )
|
||||
set_source_files_properties( src/helpers/resampler.c PROPERTIES COMPILE_FLAGS -msse )
|
||||
endif( DUMB_CAN_USE_SSE )
|
||||
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
|
|
|
@ -372,6 +372,7 @@ enum ActorFlag7
|
|||
MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly
|
||||
MF7_NODECAL = 0x00040000, // [ZK] Forces puff to have no impact decal
|
||||
MF7_FORCEDECAL = 0x00080000, // [ZK] Forces puff's decal to override the weapon's.
|
||||
MF7_LAXTELEFRAGDMG = 0x00100000, // [MC] Telefrag damage can be reduced.
|
||||
};
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
@ -823,7 +824,7 @@ public:
|
|||
}
|
||||
|
||||
// These also set CF_INTERPVIEW for players.
|
||||
void SetPitch(int p, bool interpolate);
|
||||
void SetPitch(int p, bool interpolate, bool forceclamp = false);
|
||||
void SetAngle(angle_t ang, bool interpolate);
|
||||
void SetRoll(angle_t roll, bool interpolate);
|
||||
|
||||
|
|
|
@ -525,7 +525,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage
|
|||
}
|
||||
else if(condition == INVULNERABILITY)
|
||||
{
|
||||
if(statusBar->CPlayer->cheats&CF_GODMODE)
|
||||
if(statusBar->CPlayer->cheats&(CF_GODMODE|CF_GODMODE2))
|
||||
{
|
||||
drawAlt = 1;
|
||||
}
|
||||
|
@ -1730,7 +1730,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
static int artiflashTick;
|
||||
static fixed_t itemflashFade;
|
||||
};
|
||||
int CommandDrawSelectedInventory::artiflashTick = 4;
|
||||
int CommandDrawSelectedInventory::artiflashTick = 0;
|
||||
int CommandDrawSelectedInventory::itemflashFade = FRACUNIT*3/4;
|
||||
|
||||
void DSBarInfo::FlashItem(const PClass *itemtype)
|
||||
|
|
|
@ -83,7 +83,7 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
|
|||
// new to Vista, hence the reason we support both.
|
||||
if (SHGetKnownFolderPath == NULL)
|
||||
{
|
||||
static TOptWin32Proc<HRESULT(*)(HWND, int, HANDLE, DWORD, LPTSTR)>
|
||||
static TOptWin32Proc<HRESULT(WINAPI*)(HWND, int, HANDLE, DWORD, LPTSTR)>
|
||||
SHGetFolderPathA("shell32.dll", "SHGetFolderPathA");
|
||||
|
||||
// NT4 doesn't even have this function.
|
||||
|
@ -146,6 +146,7 @@ FString M_GetCachePath(bool create)
|
|||
// Don't use GAME_DIR and such so that ZDoom and its child ports can
|
||||
// share the node cache.
|
||||
path += "/zdoom/cache";
|
||||
path.Substitute("//", "/"); // needed because progdir ends with a slash.
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
@ -644,9 +644,13 @@ class DTextEnterMenu : public DMenu
|
|||
int InputGridX;
|
||||
int InputGridY;
|
||||
|
||||
// [TP]
|
||||
bool AllowColors;
|
||||
|
||||
public:
|
||||
|
||||
DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid);
|
||||
// [TP] Added allowcolors
|
||||
DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false);
|
||||
|
||||
void Drawer ();
|
||||
bool MenuEvent (int mkey, bool fromcontroller);
|
||||
|
|
|
@ -830,6 +830,63 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
|
|||
FOptionMenuItem *it = new FOptionMenuScreenResolutionLine(sc.String);
|
||||
desc->mItems.Push(it);
|
||||
}
|
||||
// [TP] -- Text input widget
|
||||
else if ( sc.Compare( "TextField" ))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FString label = sc.String;
|
||||
sc.MustGetStringName( "," );
|
||||
sc.MustGetString();
|
||||
FString cvar = sc.String;
|
||||
FString check;
|
||||
|
||||
if ( sc.CheckString( "," ))
|
||||
{
|
||||
sc.MustGetString();
|
||||
check = sc.String;
|
||||
}
|
||||
|
||||
FOptionMenuItem* it = new FOptionMenuTextField( label, cvar, check );
|
||||
desc->mItems.Push( it );
|
||||
}
|
||||
// [TP] -- Number input widget
|
||||
else if ( sc.Compare( "NumberField" ))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FString label = sc.String;
|
||||
sc.MustGetStringName( "," );
|
||||
sc.MustGetString();
|
||||
FString cvar = sc.String;
|
||||
float minimum = 0.0f;
|
||||
float maximum = 100.0f;
|
||||
float step = 1.0f;
|
||||
FString check;
|
||||
|
||||
if ( sc.CheckString( "," ))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
minimum = (float) sc.Float;
|
||||
sc.MustGetStringName( "," );
|
||||
sc.MustGetFloat();
|
||||
maximum = (float) sc.Float;
|
||||
|
||||
if ( sc.CheckString( "," ))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
step = (float) sc.Float;
|
||||
|
||||
if ( sc.CheckString( "," ))
|
||||
{
|
||||
sc.MustGetString();
|
||||
check = sc.String;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FOptionMenuItem* it = new FOptionMenuNumberField( label, cvar,
|
||||
minimum, maximum, step, check );
|
||||
desc->mItems.Push( it );
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Unknown keyword '%s'", sc.String);
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "d_gui.h"
|
||||
#include "v_font.h"
|
||||
#include "v_palette.h"
|
||||
// [TP] New #includes
|
||||
#include "v_text.h"
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS(DTextEnterMenu)
|
||||
|
||||
|
@ -64,7 +66,8 @@ CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid)
|
||||
// [TP] Added allowcolors
|
||||
DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors)
|
||||
: DMenu(parent)
|
||||
{
|
||||
mEnterString = textbuffer;
|
||||
|
@ -83,6 +86,7 @@ DTextEnterMenu::DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int
|
|||
InputGridX = 0;
|
||||
InputGridY = 0;
|
||||
}
|
||||
AllowColors = allowcolors; // [TP]
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -140,6 +144,10 @@ bool DTextEnterMenu::Responder(event_t *ev)
|
|||
{
|
||||
if (mEnterString[0])
|
||||
{
|
||||
// [TP] If we allow color codes, colorize the string now.
|
||||
if (AllowColors)
|
||||
strbin(mEnterString);
|
||||
|
||||
DMenu *parent = mParentMenu;
|
||||
Close();
|
||||
parent->MenuEvent(MKEY_Input, false);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
#include "v_text.h"
|
||||
|
||||
|
||||
void M_DrawConText (int color, int x, int y, const char *str);
|
||||
|
@ -943,6 +944,207 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// [TP] FOptionMenuFieldBase
|
||||
//
|
||||
// Base class for input fields
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class FOptionMenuFieldBase : public FOptionMenuItem
|
||||
{
|
||||
public:
|
||||
FOptionMenuFieldBase ( const char* label, const char* menu, const char* graycheck ) :
|
||||
FOptionMenuItem ( label, menu ),
|
||||
mCVar ( FindCVar( mAction, NULL )),
|
||||
mGrayCheck (( graycheck && strlen( graycheck )) ? FindCVar( graycheck, NULL ) : NULL ) {}
|
||||
|
||||
const char* GetCVarString()
|
||||
{
|
||||
if ( mCVar == NULL )
|
||||
return "";
|
||||
|
||||
return mCVar->GetGenericRep( CVAR_String ).String;
|
||||
}
|
||||
|
||||
virtual FString Represent()
|
||||
{
|
||||
return GetCVarString();
|
||||
}
|
||||
|
||||
int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected )
|
||||
{
|
||||
bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool );
|
||||
drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed );
|
||||
int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0;
|
||||
|
||||
screen->DrawText( SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y,
|
||||
Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE );
|
||||
return indent;
|
||||
}
|
||||
|
||||
bool GetString ( int i, char* s, int len )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
strncpy( s, GetCVarString(), len );
|
||||
s[len - 1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SetString ( int i, const char* s )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
if ( mCVar )
|
||||
{
|
||||
UCVarValue vval;
|
||||
vval.String = s;
|
||||
mCVar->SetGenericRep( vval, CVAR_String );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Action is a CVar in this class and derivatives.
|
||||
FBaseCVar* mCVar;
|
||||
FBaseCVar* mGrayCheck;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// [TP] FOptionMenuTextField
|
||||
//
|
||||
// A text input field widget, for use with string CVars.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class FOptionMenuTextField : public FOptionMenuFieldBase
|
||||
{
|
||||
public:
|
||||
FOptionMenuTextField ( const char *label, const char* menu, const char* graycheck ) :
|
||||
FOptionMenuFieldBase ( label, menu, graycheck ),
|
||||
mEntering ( false ) {}
|
||||
|
||||
FString Represent()
|
||||
{
|
||||
FString text = mEntering ? mEditName : GetCVarString();
|
||||
|
||||
if ( mEntering )
|
||||
text += ( gameinfo.gametype & GAME_DoomStrifeChex ) ? '_' : '[';
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
bool MenuEvent ( int mkey, bool fromcontroller )
|
||||
{
|
||||
if ( mkey == MKEY_Enter )
|
||||
{
|
||||
S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE );
|
||||
strcpy( mEditName, GetCVarString() );
|
||||
mEntering = true;
|
||||
DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller );
|
||||
M_ActivateMenu( input );
|
||||
return true;
|
||||
}
|
||||
else if ( mkey == MKEY_Input )
|
||||
{
|
||||
if ( mCVar )
|
||||
{
|
||||
UCVarValue vval;
|
||||
vval.String = mEditName;
|
||||
mCVar->SetGenericRep( vval, CVAR_String );
|
||||
}
|
||||
|
||||
mEntering = false;
|
||||
return true;
|
||||
}
|
||||
else if ( mkey == MKEY_Abort )
|
||||
{
|
||||
mEntering = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return FOptionMenuItem::MenuEvent( mkey, fromcontroller );
|
||||
}
|
||||
|
||||
private:
|
||||
bool mEntering;
|
||||
char mEditName[128];
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// [TP] FOptionMenuNumberField
|
||||
//
|
||||
// A numeric input field widget, for use with number CVars where sliders are inappropriate (i.e.
|
||||
// where the user is interested in the exact value specifically)
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class FOptionMenuNumberField : public FOptionMenuFieldBase
|
||||
{
|
||||
public:
|
||||
FOptionMenuNumberField ( const char *label, const char* menu, float minimum, float maximum,
|
||||
float step, const char* graycheck )
|
||||
: FOptionMenuFieldBase ( label, menu, graycheck ),
|
||||
mMinimum ( minimum ),
|
||||
mMaximum ( maximum ),
|
||||
mStep ( step )
|
||||
{
|
||||
if ( mMaximum <= mMinimum )
|
||||
swapvalues( mMinimum, mMaximum );
|
||||
|
||||
if ( mStep <= 0 )
|
||||
mStep = 1;
|
||||
}
|
||||
|
||||
bool MenuEvent ( int mkey, bool fromcontroller )
|
||||
{
|
||||
if ( mCVar )
|
||||
{
|
||||
float value = mCVar->GetGenericRep( CVAR_Float ).Float;
|
||||
|
||||
if ( mkey == MKEY_Left )
|
||||
{
|
||||
value -= mStep;
|
||||
|
||||
if ( value < mMinimum )
|
||||
value = mMaximum;
|
||||
}
|
||||
else if ( mkey == MKEY_Right || mkey == MKEY_Enter )
|
||||
{
|
||||
value += mStep;
|
||||
|
||||
if ( value > mMaximum )
|
||||
value = mMinimum;
|
||||
}
|
||||
else
|
||||
return FOptionMenuItem::MenuEvent( mkey, fromcontroller );
|
||||
|
||||
UCVarValue vval;
|
||||
vval.Float = value;
|
||||
mCVar->SetGenericRep( vval, CVAR_Float );
|
||||
S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
float mMinimum;
|
||||
float mMaximum;
|
||||
float mStep;
|
||||
};
|
||||
#ifndef NO_IMP
|
||||
CCMD(am_restorecolors)
|
||||
{
|
||||
|
|
|
@ -946,6 +946,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
bool forcedPain = false;
|
||||
int fakeDamage = 0;
|
||||
int holdDamage = 0;
|
||||
int rawdamage = damage;
|
||||
|
||||
if (damage < 0) damage = 0;
|
||||
|
||||
|
@ -980,7 +981,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
if ((target->flags2 & MF2_INVULNERABLE) && (damage < TELEFRAG_DAMAGE) && (!(flags & DMG_FORCED)))
|
||||
// [MC] Changed it to check rawdamage here for consistency, even though that doesn't actually do anything
|
||||
// different here. At any rate, invulnerable is being checked before type factoring, which is then being
|
||||
// checked by player cheats/invul/buddha followed by monster buddha. This is inconsistent. Don't let the
|
||||
// original telefrag damage CHECK (rawdamage) be influenced by outside factors when looking at cheats/invul.
|
||||
if ((target->flags2 & MF2_INVULNERABLE) && (rawdamage < TELEFRAG_DAMAGE) && (!(flags & DMG_FORCED)))
|
||||
{ // actor is invulnerable
|
||||
if (target->player == NULL)
|
||||
{
|
||||
|
@ -1040,7 +1045,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (damage < TELEFRAG_DAMAGE) // TELEFRAG_DAMAGE may not be reduced at all or it may not guarantee its effect.
|
||||
if ((rawdamage < TELEFRAG_DAMAGE) || (target->flags7 & MF7_LAXTELEFRAGDMG)) // TELEFRAG_DAMAGE may only be reduced with NOTELEFRAGPIERCE or it may not guarantee its effect.
|
||||
{
|
||||
if (player && damage > 1)
|
||||
{
|
||||
|
@ -1218,7 +1223,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
if (player)
|
||||
FriendlyFire = true;
|
||||
if (damage < TELEFRAG_DAMAGE)
|
||||
if (rawdamage < TELEFRAG_DAMAGE) //Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it.
|
||||
{ // Still allow telefragging :-(
|
||||
damage = (int)((float)damage * level.teamdamage);
|
||||
if (damage < 0)
|
||||
|
@ -1261,7 +1266,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (!(flags & DMG_FORCED))
|
||||
{
|
||||
// check the real player, not a voodoo doll here for invulnerability effects
|
||||
if ((damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||
if ((rawdamage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) ||
|
||||
(player->cheats & CF_GODMODE))) ||
|
||||
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
||||
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
||||
|
@ -1286,7 +1291,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
{
|
||||
player->mo->Inventory->AbsorbDamage(damage, mod, newdam);
|
||||
}
|
||||
if (damage < TELEFRAG_DAMAGE)
|
||||
if ((rawdamage < TELEFRAG_DAMAGE) || (player->mo->flags7 & MF7_LAXTELEFRAGDMG)) //rawdamage is never modified.
|
||||
{
|
||||
// if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise.
|
||||
damage = newdam;
|
||||
|
@ -1305,7 +1310,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
}
|
||||
}
|
||||
|
||||
if (damage >= player->health && damage < TELEFRAG_DAMAGE
|
||||
if (damage >= player->health && rawdamage < TELEFRAG_DAMAGE
|
||||
&& (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch)
|
||||
&& !player->morphTics)
|
||||
{ // Try to use some inventory health
|
||||
|
@ -1329,7 +1334,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
// but telefragging should still do enough damage to kill the player)
|
||||
// Ignore players that are already dead.
|
||||
// [MC]Buddha2 absorbs telefrag damage, and anything else thrown their way.
|
||||
if (!(flags & DMG_FORCED) && (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD)))
|
||||
if (!(flags & DMG_FORCED) && (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (rawdamage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD)))
|
||||
{
|
||||
// If this is a voodoo doll we need to handle the real player as well.
|
||||
player->mo->health = target->health = player->health = 1;
|
||||
|
@ -1394,7 +1399,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (target->health <= 0)
|
||||
{
|
||||
//[MC]Buddha flag for monsters.
|
||||
if (!(flags & DMG_FORCED) && ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA))))
|
||||
if (!(flags & DMG_FORCED) && ((target->flags7 & MF7_BUDDHA) && (rawdamage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA))))
|
||||
{ //FOILBUDDHA or Telefrag damage must kill it.
|
||||
target->health = 1;
|
||||
}
|
||||
|
|
|
@ -3115,8 +3115,24 @@ void AActor::SetShade (int r, int g, int b)
|
|||
fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b);
|
||||
}
|
||||
|
||||
void AActor::SetPitch(int p, bool interpolate)
|
||||
void AActor::SetPitch(int p, bool interpolate, bool forceclamp)
|
||||
{
|
||||
if (player != NULL || forceclamp)
|
||||
{ // clamp the pitch we set
|
||||
int min, max;
|
||||
|
||||
if (player != NULL)
|
||||
{
|
||||
min = player->MinPitch;
|
||||
max = player->MaxPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = -ANGLE_90 + (1 << ANGLETOFINESHIFT);
|
||||
max = ANGLE_90 - (1 << ANGLETOFINESHIFT);
|
||||
}
|
||||
p = clamp<int>(p, min, max);
|
||||
}
|
||||
if (p != pitch)
|
||||
{
|
||||
pitch = p;
|
||||
|
|
|
@ -207,10 +207,10 @@ void P_BringUpWeapon (player_t *player)
|
|||
player->ReadyWeapon = weapon;
|
||||
player->psprites[ps_weapon].sy = player->cheats & CF_INSTANTWEAPSWITCH
|
||||
? WEAPONTOP : WEAPONBOTTOM;
|
||||
P_SetPsprite (player, ps_weapon, newstate);
|
||||
// make sure that the previous weapon's flash state is terminated.
|
||||
// When coming here from a weapon drop it may still be active.
|
||||
P_SetPsprite(player, ps_flash, NULL);
|
||||
P_SetPsprite (player, ps_weapon, newstate);
|
||||
player->mo->weaponspecial = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1741,7 +1741,7 @@ static void P_SpawnScrollers(void)
|
|||
if (lines[i].special == Sector_CopyScroller)
|
||||
{
|
||||
// don't allow copying the scroller if the sector has the same tag as it would just duplicate it.
|
||||
if (tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0]))
|
||||
if (!tagManager.SectorHasTag(lines[i].frontsector, lines[i].args[0]))
|
||||
{
|
||||
copyscrollers.Push(i);
|
||||
}
|
||||
|
|
|
@ -98,13 +98,16 @@ void FTagManager::AddSectorTag(int sector, int tag)
|
|||
|
||||
void FTagManager::RemoveSectorTags(int sect)
|
||||
{
|
||||
int start = startForSector[sect];
|
||||
if (start >= 0)
|
||||
if (startForSector.Size() > 0)
|
||||
{
|
||||
while (allTags[start].target == sect)
|
||||
int start = startForSector[sect];
|
||||
if (start >= 0)
|
||||
{
|
||||
allTags[start].tag = allTags[start].target = -1;
|
||||
start++;
|
||||
while (allTags[start].target == sect)
|
||||
{
|
||||
allTags[start].tag = allTags[start].target = -1;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
startForSector.Clear();
|
||||
startForLine.Clear();
|
||||
memset(TagHashFirst, -1, sizeof(TagHashFirst));
|
||||
memset(IDHashFirst, -1, sizeof(IDHashFirst));
|
||||
}
|
||||
|
||||
bool SectorHasTags(const sector_t *sector) const;
|
||||
|
|
|
@ -28,7 +28,7 @@ class SDLFB : public DFrameBuffer
|
|||
{
|
||||
DECLARE_CLASS(SDLFB, DFrameBuffer)
|
||||
public:
|
||||
SDLFB (int width, int height, bool fullscreen);
|
||||
SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin);
|
||||
~SDLFB ();
|
||||
|
||||
bool Lock (bool buffer);
|
||||
|
@ -67,7 +67,6 @@ private:
|
|||
SDL_Texture *Texture;
|
||||
SDL_Surface *Surface;
|
||||
};
|
||||
SDL_Rect UpdateRect;
|
||||
|
||||
bool UsingRenderer;
|
||||
bool NeedPalUpdate;
|
||||
|
@ -261,6 +260,8 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
PalEntry flashColor;
|
||||
int flashAmount;
|
||||
|
||||
SDL_Window *oldwin = NULL;
|
||||
|
||||
if (old != NULL)
|
||||
{ // Reuse the old framebuffer if its attributes are the same
|
||||
SDLFB *fb = static_cast<SDLFB *> (old);
|
||||
|
@ -275,6 +276,10 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
oldwin = fb->Screen;
|
||||
fb->Screen = NULL;
|
||||
|
||||
old->GetFlash (flashColor, flashAmount);
|
||||
old->ObjectFlags |= OF_YesReallyDelete;
|
||||
if (screen == old) screen = NULL;
|
||||
|
@ -286,7 +291,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
flashAmount = 0;
|
||||
}
|
||||
|
||||
SDLFB *fb = new SDLFB (width, height, fullscreen);
|
||||
SDLFB *fb = new SDLFB (width, height, fullscreen, oldwin);
|
||||
|
||||
// If we could not create the framebuffer, try again with slightly
|
||||
// different parameters in this order:
|
||||
|
@ -340,7 +345,7 @@ void SDLVideo::SetWindowedScale (float scale)
|
|||
|
||||
// FrameBuffer implementation -----------------------------------------------
|
||||
|
||||
SDLFB::SDLFB (int width, int height, bool fullscreen)
|
||||
SDLFB::SDLFB (int width, int height, bool fullscreen, SDL_Window *oldwin)
|
||||
: DFrameBuffer (width, height)
|
||||
{
|
||||
int i;
|
||||
|
@ -351,15 +356,27 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
|
|||
NotPaletted = false;
|
||||
FlashAmount = 0;
|
||||
|
||||
FString caption;
|
||||
caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
|
||||
if (oldwin)
|
||||
{
|
||||
// In some cases (Mac OS X fullscreen) SDL2 doesn't like having multiple windows which
|
||||
// appears to inevitably happen while compositor animations are running. So lets try
|
||||
// to reuse the existing window.
|
||||
Screen = oldwin;
|
||||
SDL_SetWindowSize (Screen, width, height);
|
||||
SetFullscreen (fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString caption;
|
||||
caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
|
||||
|
||||
Screen = SDL_CreateWindow (caption,
|
||||
SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter),
|
||||
width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
|
||||
Screen = SDL_CreateWindow (caption,
|
||||
SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter),
|
||||
width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)|SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if (Screen == NULL)
|
||||
return;
|
||||
if (Screen == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
Renderer = NULL;
|
||||
Texture = NULL;
|
||||
|
@ -381,15 +398,15 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
|
|||
|
||||
SDLFB::~SDLFB ()
|
||||
{
|
||||
if (Renderer)
|
||||
{
|
||||
if (Texture)
|
||||
SDL_DestroyTexture (Texture);
|
||||
SDL_DestroyRenderer (Renderer);
|
||||
}
|
||||
|
||||
if(Screen)
|
||||
{
|
||||
if (Renderer)
|
||||
{
|
||||
if (Texture)
|
||||
SDL_DestroyTexture (Texture);
|
||||
SDL_DestroyRenderer (Renderer);
|
||||
}
|
||||
|
||||
SDL_DestroyWindow (Screen);
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +515,8 @@ void SDLFB::Update ()
|
|||
SDL_UnlockTexture (Texture);
|
||||
|
||||
SDLFlipCycles.Clock();
|
||||
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect);
|
||||
SDL_RenderClear(Renderer);
|
||||
SDL_RenderCopy(Renderer, Texture, NULL, NULL);
|
||||
SDL_RenderPresent(Renderer);
|
||||
SDLFlipCycles.Unclock();
|
||||
}
|
||||
|
@ -613,6 +631,9 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256])
|
|||
|
||||
void SDLFB::SetFullscreen (bool fullscreen)
|
||||
{
|
||||
if (IsFullscreen() == fullscreen)
|
||||
return;
|
||||
|
||||
SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
if (!fullscreen)
|
||||
{
|
||||
|
@ -645,6 +666,8 @@ void SDLFB::ResetSDLRenderer ()
|
|||
if (!Renderer)
|
||||
return;
|
||||
|
||||
SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
|
||||
|
||||
Uint32 fmt;
|
||||
switch(vid_displaybits)
|
||||
{
|
||||
|
@ -681,24 +704,14 @@ void SDLFB::ResetSDLRenderer ()
|
|||
NotPaletted = false;
|
||||
}
|
||||
|
||||
// Calculate update rectangle
|
||||
// In fullscreen, set logical size according to animorphic ratio.
|
||||
// Windowed modes are rendered to fill the window (usually 1:1)
|
||||
if (IsFullscreen ())
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize (Screen, &w, &h);
|
||||
UpdateRect.w = w;
|
||||
UpdateRect.h = h;
|
||||
ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height);
|
||||
UpdateRect.x = (w - UpdateRect.w)/2;
|
||||
UpdateRect.y = (h - UpdateRect.h)/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In windowed mode we just update the whole window.
|
||||
UpdateRect.x = 0;
|
||||
UpdateRect.y = 0;
|
||||
UpdateRect.w = Width;
|
||||
UpdateRect.h = Height;
|
||||
ScaleWithAspect (w, h, Width, Height);
|
||||
SDL_RenderSetLogicalSize (Renderer, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,13 +739,14 @@ void SDLFB::SetVSync (bool vsync)
|
|||
|
||||
void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize (Screen, &w, &h);
|
||||
|
||||
// Detect if we're doing scaling in the Window and adjust the mouse
|
||||
// coordinates accordingly. This could be more efficent, but I
|
||||
// don't think performance is an issue in the menus.
|
||||
if(IsFullscreen())
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize (Screen, &w, &h);
|
||||
int realw = w, realh = h;
|
||||
ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
|
||||
if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
|
||||
|
@ -751,6 +765,11 @@ void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = (SWORD)(x*Width/w);
|
||||
y = (SWORD)(y*Height/h);
|
||||
}
|
||||
}
|
||||
|
||||
ADD_STAT (blit)
|
||||
|
|
|
@ -267,6 +267,11 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
|||
BYTE *Pixels = const_cast<BYTE*>(tex->GetPixels());
|
||||
DSimpleCanvas *Canvas = tex->GetCanvas();
|
||||
|
||||
// curse Doom's overuse of global variables in the renderer.
|
||||
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
||||
unsigned char *savecolormap = fixedcolormap;
|
||||
FSpecialColormap *savecm = realfixedcolormap;
|
||||
|
||||
float savedfov = LastFOV;
|
||||
R_SetFOV ((float)fov);
|
||||
R_RenderViewToCanvas (viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate);
|
||||
|
@ -280,6 +285,8 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
|||
FTexture::FlipNonSquareBlockRemap (Pixels, Canvas->GetBuffer(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap);
|
||||
}
|
||||
tex->SetUpdated();
|
||||
fixedcolormap = savecolormap;
|
||||
realfixedcolormap = savecm;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -62,9 +62,6 @@
|
|||
extern bool DrawFSHUD; // [RH] Defined in d_main.cpp
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
|
||||
extern lighttable_t* fixedcolormap;
|
||||
extern FSpecialColormap*realfixedcolormap;
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
struct InterpolationViewer
|
||||
|
@ -1101,11 +1098,6 @@ void FCanvasTextureInfo::UpdateAll ()
|
|||
{
|
||||
FCanvasTextureInfo *probe;
|
||||
|
||||
// curse Doom's overuse of global variables in the renderer.
|
||||
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
||||
unsigned char *savecolormap = fixedcolormap;
|
||||
FSpecialColormap *savecm = realfixedcolormap;
|
||||
|
||||
for (probe = List; probe != NULL; probe = probe->Next)
|
||||
{
|
||||
if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate)
|
||||
|
@ -1113,9 +1105,6 @@ void FCanvasTextureInfo::UpdateAll ()
|
|||
Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV);
|
||||
}
|
||||
}
|
||||
|
||||
fixedcolormap = savecolormap;
|
||||
realfixedcolormap = savecm;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -3989,23 +3989,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ref->player != NULL || (flags & SPF_FORCECLAMP))
|
||||
{ // clamp the pitch we set
|
||||
int min, max;
|
||||
|
||||
if (ref->player != NULL)
|
||||
{
|
||||
min = ref->player->MinPitch;
|
||||
max = ref->player->MaxPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = -ANGLE_90 + (1 << ANGLETOFINESHIFT);
|
||||
max = ANGLE_90 - (1 << ANGLETOFINESHIFT);
|
||||
}
|
||||
pitch = clamp<int>(pitch, min, max);
|
||||
}
|
||||
ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE));
|
||||
ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -258,6 +258,8 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF7, NODECAL, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FORCEDECAL, AActor, flags7),
|
||||
|
||||
DEFINE_FLAG(MF7, LAXTELEFRAGDMG, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects),
|
||||
|
|
|
@ -536,7 +536,7 @@ map LEVEL09 lookup "NHUSTR_9"
|
|||
|
||||
cluster 11
|
||||
{
|
||||
flat = "RROCK19"
|
||||
flat = "SLIME16"
|
||||
music = "$MUSIC_READ_M"
|
||||
exittext = lookup, "NERVETEXT"
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ statusbar fullscreen, fullscreenoffsets
|
|||
|
||||
statusbar Normal
|
||||
{
|
||||
drawimage "H2BAR", 0, 135;
|
||||
drawimage "H2BAR", 0, 134;
|
||||
drawimage "STATBAR", 38, 162;
|
||||
|
||||
drawselectedinventory artiflash, INDEXFONT_RAVEN, 143, 163, 174, 184, untranslated;
|
||||
|
@ -204,7 +204,7 @@ statusbar Normal
|
|||
|
||||
statusbar Automap
|
||||
{
|
||||
drawimage "H2BAR", 0, 135;
|
||||
drawimage "H2BAR", 0, 134;
|
||||
drawimage "KEYBAR", 38, 162;
|
||||
drawkeybar 5, horizontal, 20, 46, 164;
|
||||
drawimage hexenarmor(armor, "ARMSLOT1"), 150, 164;
|
||||
|
|
Loading…
Reference in a new issue