Merge branch 'master' into reverbedit

# Conflicts:
#	wadsrc/static/zscript/menu/optionmenuitems.txt
This commit is contained in:
Christoph Oelckers 2018-01-20 11:44:42 +01:00
commit 2d8e394529
130 changed files with 2933 additions and 1082 deletions

View file

@ -11,7 +11,7 @@ git:
matrix:
include:
- os: osx
osx_image: xcode9.1
osx_image: xcode9.2
env:
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7"

View file

@ -234,6 +234,12 @@ else()
if( APPLE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
set( ALL_C_FLAGS "-static-libgcc" )
endif()
if( NOT APPLE )
# Generic GCC/Clang requires position independent executable to be enabled explicitly
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fPIE" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie" )
endif()
endif()
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )

View file

@ -23,9 +23,9 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#undef PI
#define PI 3.1415926535897932384626433832795029
#if _MSC_VER >= 1911 && defined _M_X64
#if _MSC_VER >= 1911
#pragma float_control(precise, on, push)
#endif // _MSC_VER >= 1911 && _M_X64
#endif // _MSC_VER >= 1911
static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
int count, short* out )
@ -56,9 +56,9 @@ static void gen_sinc( double rolloff, int width, double offset, double spacing,
}
}
#if _MSC_VER >= 1911 && defined _M_X64
#if _MSC_VER >= 1911
#pragma float_control(pop)
#endif // _MSC_VER >= 1911 && _M_X64
#endif // _MSC_VER >= 1911
Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) :
width_( width ),

View file

@ -1169,6 +1169,7 @@ public:
int Score; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything.
FString * Tag; // Strife's tag name.
int DesignatedTeam; // Allow for friendly fire cacluations to be done on non-players.
int friendlyseeblocks; // allow to override friendly search distance calculation
AActor *BlockingMobj; // Actor that blocked the last move
line_t *BlockingLine; // Line that blocked the last move

View file

@ -98,6 +98,23 @@ CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE);
CVAR (Int, am_showtriggerlines, 0, CVAR_ARCHIVE);
CVAR (Int, am_showthingsprites, 0, CVAR_ARCHIVE);
CUSTOM_CVAR (Int, am_emptyspacemargin, 0, CVAR_ARCHIVE)
{
if (self < 0)
{
self = 0;
}
else if (self > 90)
{
self = 90;
}
if (nullptr != StatusBar)
{
AM_NewResolution();
}
}
//=============================================================================
//
// Automap colors
@ -1063,8 +1080,9 @@ static void AM_findMinMaxBoundaries ()
static void AM_calcMinMaxMtoF()
{
double a = SCREENWIDTH / max_w;
double b = StatusBar->GetTopOfStatusbar() / max_h;
const double safe_frame = 1.0 - am_emptyspacemargin / 100.0;
double a = safe_frame * (SCREENWIDTH / max_w);
double b = safe_frame * (StatusBar->GetTopOfStatusbar() / max_h);
min_scale_mtof = a < b ? a : b;
max_scale_mtof = SCREENHEIGHT / (2*PLAYERRADIUS);
@ -2932,7 +2950,7 @@ void AM_drawThings ()
const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0);
frame = &SpriteFrames[spriteIndex];
DAngle angle = 270. -t->Angles.Yaw;
DAngle angle = 270. + 22.5 - t->Angles.Yaw;
if (frame->Texture[0] != frame->Texture[1]) angle += 180. / 16;
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
{

View file

@ -558,7 +558,7 @@ void C_UnbindAll ()
AutomapBindings.UnbindAll();
}
CCMD (unbindall)
UNSAFE_CCMD (unbindall)
{
C_UnbindAll ();
}

View file

@ -467,7 +467,7 @@ CCMD (print)
}
}
CCMD (exec)
UNSAFE_CCMD (exec)
{
if (argv.argc() < 2)
return;
@ -495,7 +495,7 @@ void execLogfile(const char *fn, bool append)
}
}
CCMD (logfile)
UNSAFE_CCMD (logfile)
{
if (Logfile)
@ -651,7 +651,7 @@ CCMD (error)
}
}
CCMD (error_fatal)
UNSAFE_CCMD (error_fatal)
{
if (argv.argc() > 1)
{
@ -674,7 +674,7 @@ CCMD (error_fatal)
//==========================================================================
#if !defined(_WIN32) || !defined(_DEBUG)
CCMD (crashout)
UNSAFE_CCMD (crashout)
{
*(volatile int *)0 = 0;
}
@ -794,7 +794,7 @@ CCMD (warp)
//
//==========================================================================
CCMD (load)
UNSAFE_CCMD (load)
{
if (argv.argc() != 2)
{
@ -819,7 +819,7 @@ CCMD (load)
//
//==========================================================================
CCMD (save)
UNSAFE_CCMD (save)
{
if (argv.argc() < 2 || argv.argc() > 3)
{

View file

@ -627,7 +627,7 @@ void C_InitConsole (int width, int height, bool ingame)
//
//==========================================================================
CCMD (atexit)
UNSAFE_CCMD (atexit)
{
if (argv.argc() == 1)
{

View file

@ -65,7 +65,7 @@ class DWaitingCommand : public DThinker
{
DECLARE_CLASS (DWaitingCommand, DThinker)
public:
DWaitingCommand (const char *cmd, int tics);
DWaitingCommand (const char *cmd, int tics, bool unsafe);
~DWaitingCommand ();
void Serialize(FSerializer &arc);
void Tick ();
@ -75,6 +75,7 @@ private:
char *Command;
int TicsLeft;
bool IsUnsafe;
};
class DStoredCommand : public DThinker
@ -127,6 +128,7 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
Button_AM_ZoomIn, Button_AM_ZoomOut;
bool ParsingKeyConf;
static bool UnsafeExecutionContext;
// To add new actions, go to the console and type "key <action name>".
// This will give you the key value to use in the first column. Then
@ -195,19 +197,22 @@ void DWaitingCommand::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc("command", Command)
("ticsleft", TicsLeft);
("ticsleft", TicsLeft)
("unsafe", IsUnsafe);
}
DWaitingCommand::DWaitingCommand ()
{
Command = NULL;
TicsLeft = 1;
IsUnsafe = false;
}
DWaitingCommand::DWaitingCommand (const char *cmd, int tics)
DWaitingCommand::DWaitingCommand (const char *cmd, int tics, bool unsafe)
{
Command = copystring (cmd);
TicsLeft = tics+1;
IsUnsafe = unsafe;
}
DWaitingCommand::~DWaitingCommand ()
@ -222,7 +227,10 @@ void DWaitingCommand::Tick ()
{
if (--TicsLeft == 0)
{
const bool wasUnsafe = UnsafeExecutionContext;
UnsafeExecutionContext = IsUnsafe;
AddCommandString (Command);
UnsafeExecutionContext = wasUnsafe;
Destroy ();
}
}
@ -650,6 +658,12 @@ void C_DoCommand (const char *cmd, int keynum)
if (args.argc() >= 2)
{ // Set the variable
if (UnsafeExecutionContext && !(var->GetFlags() & CVAR_MOD))
{
Printf(TEXTCOLOR_RED "Cannot set console variable" TEXTCOLOR_GOLD " %s " TEXTCOLOR_RED "from unsafe command\n", var->GetName());
return;
}
var->CmdSet (args[1]);
}
else
@ -670,7 +684,9 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
if (CurrentMenu == nullptr) return 0;
PARAM_PROLOGUE;
PARAM_STRING(cmd);
UnsafeExecutionContext = true;
C_DoCommand(cmd);
UnsafeExecutionContext = false;
return 0;
}
@ -730,7 +746,7 @@ void AddCommandString (char *cmd, int keynum)
// Note that deferred commands lose track of which key
// (if any) they were pressed from.
*brkpt = ';';
Create<DWaitingCommand> (brkpt, tics);
Create<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
}
return;
}
@ -1022,6 +1038,17 @@ void FConsoleCommand::Run (FCommandLine &argv, APlayerPawn *who, int key)
m_RunFunc (argv, who, key);
}
void FUnsafeConsoleCommand::Run (FCommandLine &args, APlayerPawn *instigator, int key)
{
if (UnsafeExecutionContext)
{
Printf(TEXTCOLOR_RED "Cannot execute unsafe command " TEXTCOLOR_GOLD "%s\n", m_Name);
return;
}
FConsoleCommand::Run (args, instigator, key);
}
FConsoleAlias::FConsoleAlias (const char *name, const char *command, bool noSave)
: FConsoleCommand (name, NULL),
bRunning(false), bKill(false)
@ -1342,9 +1369,13 @@ CCMD (alias)
alias = NULL;
}
}
else if (ParsingKeyConf)
{
new FUnsafeConsoleAlias (argv[1], argv[2]);
}
else
{
new FConsoleAlias (argv[1], argv[2], ParsingKeyConf);
new FConsoleAlias (argv[1], argv[2], false);
}
}
}
@ -1482,6 +1513,13 @@ void FConsoleAlias::SafeDelete ()
}
}
void FUnsafeConsoleAlias::Run (FCommandLine &args, APlayerPawn *instigator, int key)
{
UnsafeExecutionContext = true;
FConsoleAlias::Run(args, instigator, key);
UnsafeExecutionContext = false;
}
void FExecList::AddCommand(const char *cmd, const char *file)
{
// Pullins are special and need to be separated from general commands.

View file

@ -127,6 +127,22 @@ protected:
FConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \
void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key)
class FUnsafeConsoleCommand : public FConsoleCommand
{
public:
FUnsafeConsoleCommand (const char *name, CCmdRun RunFunc)
: FConsoleCommand (name, RunFunc)
{
}
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override;
};
#define UNSAFE_CCMD(n) \
static void Cmd_##n (FCommandLine &, APlayerPawn *, int key); \
static FUnsafeConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \
void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key)
const int KEY_DBLCLICKED = 0x8000;
class FConsoleAlias : public FConsoleCommand
@ -147,6 +163,17 @@ protected:
bool bKill;
};
class FUnsafeConsoleAlias : public FConsoleAlias
{
public:
FUnsafeConsoleAlias (const char *name, const char *command)
: FConsoleAlias (name, command, true)
{
}
virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override;
};
// Actions
struct FButtonStatus
{

View file

@ -2490,7 +2490,7 @@ bool D_LoadDehFile(const char *patchfile)
{
FileReader fr;
if (!fr.Open(patchfile))
if (fr.Open(patchfile))
{
PatchSize = fr.GetLength();

View file

@ -781,7 +781,7 @@ void D_Display ()
{
screen->FrameTime = I_msTime();
screen->FrameTime = I_msTimeFS();
TexMan.UpdateAnimations(screen->FrameTime);
R_UpdateSky(screen->FrameTime);
switch (gamestate)
@ -797,7 +797,13 @@ void D_Display ()
case GS_LEVEL:
case GS_TITLELEVEL:
if (!gametic)
{
if (!screen->HasBegun2D())
{
screen->Begin2D(false);
}
break;
}
if (StatusBar != NULL)
{
@ -2815,7 +2821,7 @@ void D_DoomMain (void)
//
//==========================================================================
CCMD(restart)
UNSAFE_CCMD(restart)
{
// remove command line args that would get in the way during restart
Args->RemoveArgs("-iwad");
@ -2911,4 +2917,4 @@ CUSTOM_CVAR(Bool, I_FriendlyWindowTitle, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CV
I_SetWindowTitle(DoomStartupInfo.Name.GetChars());
else
I_SetWindowTitle(NULL);
}
}

View file

@ -510,7 +510,7 @@ public:
crouchdir = 0;
crouching = 0;
crouchviewdelta = 0;
viewheight = mo->ViewHeight;
viewheight = mo ? mo->ViewHeight : 0;
}
}

View file

@ -371,6 +371,7 @@ struct FMapThing
int16_t roll;
uint32_t RenderStyle;
int FloatbobPhase;
int friendlyseeblocks;
};

View file

@ -1743,7 +1743,8 @@ static void G_QueueBody (AActor *body)
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
void G_DoReborn (int playernum, bool freshbot)
{
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn)
if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
!G_SkillProperty(SKILLP_PlayerRespawn))
{
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
{ // Load game from the last point it was saved
@ -1772,7 +1773,7 @@ void G_DoReborn (int playernum, bool freshbot)
}
// spawn at random spot if in deathmatch
if (deathmatch || isUnfriendly)
if ((deathmatch || isUnfriendly) && (level.deathmatchstarts.Size () > 0))
{
G_DeathMatchSpawnPlayer (playernum);
return;
@ -2617,7 +2618,7 @@ CCMD (playdemo)
}
}
CCMD (timedemo)
UNSAFE_CCMD (timedemo)
{
if (argv.argc() > 1)
{

View file

@ -224,7 +224,7 @@ CCMD (map)
//
//==========================================================================
CCMD(recordmap)
UNSAFE_CCMD(recordmap)
{
if (netgame)
{
@ -277,7 +277,7 @@ CCMD(recordmap)
//
//==========================================================================
CCMD (open)
UNSAFE_CCMD (open)
{
if (netgame)
{
@ -1481,6 +1481,8 @@ void G_InitLevelLocals ()
level.outsidefogdensity = info->outsidefogdensity;
level.skyfog = info->skyfog;
level.pixelstretch = info->pixelstretch;
compatflags.Callback();
compatflags2.Callback();
@ -1952,6 +1954,52 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, SetInterMusic)
return 0;
}
//==========================================================================
//
//
//==========================================================================
template <typename T>
inline T VecDiff(const T& v1, const T& v2)
{
T result = v2 - v1;
if (level.subsectors.Size() > 0)
{
const sector_t *const sec1 = P_PointInSector(v1);
const sector_t *const sec2 = P_PointInSector(v2);
if (nullptr != sec1 && nullptr != sec2)
{
result += Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
}
}
return result;
}
DEFINE_ACTION_FUNCTION(FLevelLocals, Vec2Diff)
{
PARAM_PROLOGUE;
PARAM_FLOAT(x1);
PARAM_FLOAT(y1);
PARAM_FLOAT(x2);
PARAM_FLOAT(y2);
ACTION_RETURN_VEC2(VecDiff(DVector2(x1, y1), DVector2(x2, y2)));
}
DEFINE_ACTION_FUNCTION(FLevelLocals, Vec3Diff)
{
PARAM_PROLOGUE;
PARAM_FLOAT(x1);
PARAM_FLOAT(y1);
PARAM_FLOAT(z1);
PARAM_FLOAT(x2);
PARAM_FLOAT(y2);
PARAM_FLOAT(z2);
ACTION_RETURN_VEC3(VecDiff(DVector3(x1, y1, z1), DVector3(x2, y2, z2)));
}
//==========================================================================
//
//
@ -1994,6 +2042,7 @@ DEFINE_FIELD(FLevelLocals, teamdamage)
DEFINE_FIELD(FLevelLocals, fogdensity)
DEFINE_FIELD(FLevelLocals, outsidefogdensity)
DEFINE_FIELD(FLevelLocals, skyfog)
DEFINE_FIELD(FLevelLocals, pixelstretch)
DEFINE_FIELD_BIT(FLevelLocals, flags, noinventorybar, LEVEL_NOINVENTORYBAR)
DEFINE_FIELD_BIT(FLevelLocals, flags, monsterstelefrag, LEVEL_MONSTERSTELEFRAG)
DEFINE_FIELD_BIT(FLevelLocals, flags, actownspecial, LEVEL_ACTOWNSPECIAL)

View file

@ -538,6 +538,7 @@ enum ESkillProperty
SKILLP_EasyKey,
SKILLP_SlowMonsters,
SKILLP_Infight,
SKILLP_PlayerRespawn,
};
enum EFSkillProperty // floating point properties
{
@ -595,6 +596,7 @@ struct FSkillInfo
double FriendlyHealth;
bool NoPain;
int Infighting;
bool PlayerRespawn;
FSkillInfo() {}
FSkillInfo(const FSkillInfo &other)

View file

@ -148,6 +148,7 @@ struct FLevelLocals
int outsidefogdensity;
int skyfog;
float pixelstretch;
bool IsJumpingAllowed() const;
bool IsCrouchingAllowed() const;

View file

@ -2233,7 +2233,7 @@ void G_ParseMapInfo (FString basemapinfo)
}
if (nindex != 2)
{
CommitUMapinfo(&gamedefaults); // UMPAINFOs are collected until a regular MAPINFO is found so that they properly use the base settings.
CommitUMapinfo(&gamedefaults); // UMAPINFOs are collected until a regular MAPINFO is found so that they properly use the base settings.
FMapInfoParser parse(nindex == 1 ? FMapInfoParser::FMT_New : FMapInfoParser::FMT_Unknown);
level_info_t defaultinfo;
parse.ParseMapInfo(lump, gamedefaults, defaultinfo);

View file

@ -50,15 +50,17 @@ DFlashFader::DFlashFader ()
DFlashFader::DFlashFader (float r1, float g1, float b1, float a1,
float r2, float g2, float b2, float a2,
float time, AActor *who)
float time, AActor *who, bool terminate)
: TotalTics ((int)(time*TICRATE)), StartTic (level.time), ForWho (who)
{
Blends[0][0]=r1; Blends[0][1]=g1; Blends[0][2]=b1; Blends[0][3]=a1;
Blends[1][0]=r2; Blends[1][1]=g2; Blends[1][2]=b2; Blends[1][3]=a2;
Terminate = terminate;
}
void DFlashFader::OnDestroy ()
{
if (Terminate) Blends[1][3] = 0.f; // Needed in order to cancel out the secondary fade.
SetBlend (1.f);
Super::OnDestroy();
}

View file

@ -84,19 +84,20 @@ class DFlashFader : public DThinker
public:
DFlashFader (float r1, float g1, float b1, float a1,
float r2, float g2, float b2, float a2,
float time, AActor *who);
float time, AActor *who, bool terminate = false);
void OnDestroy() override;
void Serialize(FSerializer &arc);
void Tick ();
AActor *WhoFor() { return ForWho; }
void Cancel ();
protected:
float Blends[2][4];
int TotalTics;
int StartTic;
TObjPtr<AActor*> ForWho;
bool Terminate;
void SetBlend (float time);
DFlashFader ();
};

View file

@ -96,6 +96,7 @@ CVAR (Int, hud_armor_yellow, 50, CVAR_ARCHIVE) // armor amount less than whic
CVAR (Int, hud_armor_green, 100, CVAR_ARCHIVE) // armor amount above is blue, below is green
CVAR (Bool, hud_berserk_health, true, CVAR_ARCHIVE); // when found berserk pack instead of health box
CVAR (Bool, hud_showangles, false, CVAR_ARCHIVE) // show player's pitch, yaw, roll
CVAR (Int, hudcolor_titl, CR_YELLOW, CVAR_ARCHIVE) // color of automap title
CVAR (Int, hudcolor_time, CR_RED, CVAR_ARCHIVE) // color of level/hub time
@ -907,20 +908,44 @@ static void DrawCoordinates(player_t * CPlayer)
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);
mysnprintf(coordstr, countof(coordstr), "X: %d", int(pos.X));
screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos+2*h, coordstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);
int linenum = 3;
mysnprintf(coordstr, countof(coordstr), "Y: %d", int(pos.Y));
screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos+3*h, coordstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);
typedef struct CoordEntry
{
const char* const format;
double value;
}
CoordEntryList[3];
mysnprintf(coordstr, countof(coordstr), "Z: %d", int(pos.Z));
screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos+4*h, coordstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);
const auto drawentries = [&](CoordEntryList&& entries)
{
for (const auto& entry : entries)
{
mysnprintf(coordstr, countof(coordstr), entry.format, entry.value);
screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos + linenum * h, coordstr,
DTA_KeepRatio, true,
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE);
++linenum;
}
};
drawentries({
{ "X: %.0f", pos.X },
{ "Y: %.0f", pos.Y },
{ "Z: %.0f", pos.Z }
});
if (hud_showangles)
{
const DRotator& angles = CPlayer->mo->Angles;
++linenum;
drawentries({
{ "P: %.1f", angles.Pitch.Degrees },
{ "Y: %.1f", (90.0 - angles.Yaw).Normalized360().Degrees },
{ "R: %.1f", angles.Roll.Degrees },
});
}
}
//---------------------------------------------------------------------------

View file

@ -89,6 +89,7 @@ void FMapInfoParser::ParseSkill ()
skill.FriendlyHealth = 1.;
skill.NoPain = false;
skill.Infighting = 0;
skill.PlayerRespawn = false;
sc.MustGetString();
skill.Name = sc.String;
@ -155,6 +156,10 @@ void FMapInfoParser::ParseSkill ()
{
skill.NoMenu = true;
}
else if (sc.Compare ("playerrespawn"))
{
skill.PlayerRespawn = true;
}
else if (sc.Compare("respawntime"))
{
ParseAssign();
@ -397,6 +402,9 @@ int G_SkillProperty(ESkillProperty prop)
if (AllSkills[gameskill].Infighting == LEVEL2_TOTALINFIGHTING) return 1;
if (AllSkills[gameskill].Infighting == LEVEL2_NOINFIGHTING) return -1;
return infighting;
case SKILLP_PlayerRespawn:
return AllSkills[gameskill].PlayerRespawn;
}
}
return 0;
@ -550,6 +558,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
Infighting = other.Infighting;
ArmorFactor = other.ArmorFactor;
HealthFactor = other.HealthFactor;
PlayerRespawn = other.PlayerRespawn;
return *this;
}

View file

@ -2074,8 +2074,8 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetGlobalACSArrayValue)
enum ENumFlags
{
FNF_FILLZEROS,
FNF_WHENNOTZERO,
FNF_WHENNOTZERO = 0x1,
FNF_FILLZEROS = 0x2,
};
DEFINE_ACTION_FUNCTION(DBaseStatusBar, FormatNumber)

View file

@ -157,7 +157,7 @@ void FGLModelRenderer::DrawElements(int numIndices, size_t offset)
double FGLModelRenderer::GetTimeFloat()
{
return (float)I_msTime() * (float)TICRATE / 1000.0f;
return (double)I_msTime() * (double)TICRATE / 1000.;
}
//===========================================================================

View file

@ -75,7 +75,6 @@
#include "r_videoscale.h"
EXTERN_CVAR(Int, screenblocks)
EXTERN_CVAR(Int, vid_scalemode)
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
@ -312,7 +311,10 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
mSceneViewport.height = height;
// Scale viewports to fit letterbox
if ((gl_scale_viewport && !framebuffer->IsFullscreen() && vid_scalemode == 0) || !FGLRenderBuffers::IsEnabled())
bool notScaled = ((mScreenViewport.width == ViewportScaledWidth(mScreenViewport.width, mScreenViewport.height)) &&
(mScreenViewport.width == ViewportScaledHeight(mScreenViewport.width, mScreenViewport.height)) &&
!ViewportIsScaled43());
if ((gl_scale_viewport && !framebuffer->IsFullscreen() && notScaled) || !FGLRenderBuffers::IsEnabled())
{
mScreenViewport.width = mOutputLetterbox.width;
mScreenViewport.height = mOutputLetterbox.height;

View file

@ -173,7 +173,7 @@ bool FRenderState::ApplyShader()
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeight.Set(mClipHeight);
activeShader->muClipHeightDirection.Set(mClipHeightDirection);
activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * mShaderTimer / 1000.f);
activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.);
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
activeShader->muClipSplit.Set(mClipSplit);

View file

@ -1180,6 +1180,7 @@ void GLHorizonPortal::DrawContents()
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
gl_RenderState.SetObjectColor(origin->specialcolor);
gl_SetPlaneTextureRotation(sp, gltexture);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
@ -1237,6 +1238,7 @@ void GLEEHorizonPortal::DrawContents()
horz.plane.GetFromSector(sector, sector_t::ceiling);
horz.lightlevel = gl_ClampLight(sector->GetCeilingLight());
horz.colormap = sector->Colormap;
horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE)
{
horz.plane.Texheight = r_viewpoint.Pos.Z + fabs(horz.plane.Texheight);
@ -1250,6 +1252,7 @@ void GLEEHorizonPortal::DrawContents()
horz.plane.GetFromSector(sector, sector_t::floor);
horz.lightlevel = gl_ClampLight(sector->GetFloorLight());
horz.colormap = sector->Colormap;
horz.specialcolor = 0xffffffff;
if (portal->mType == PORTS_PLANE)
{
horz.plane.Texheight = r_viewpoint.Pos.Z - fabs(horz.plane.Texheight);

View file

@ -48,6 +48,7 @@ struct GLHorizonInfo
GLSectorPlane plane;
int lightlevel;
FColormap colormap;
PalEntry specialcolor;
};
struct GLSkyInfo

View file

@ -969,7 +969,7 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3);
glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr);
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width*3);
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
M_Free(scr);
}

View file

@ -69,7 +69,7 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
if (!texture[0] || texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
skytexno1 = texno;
x_offset[0] = s->GetTextureXOffset(pos) * (360.f/65536.f);
y_offset = s->GetTextureYOffset(pos);
y_offset = s->GetTextureYOffset(pos) - 28.0;
mirrored = !l->args[2];
}
else

View file

@ -40,6 +40,7 @@
#include "events.h"
#include "actorinlines.h"
#include "r_data/r_vanillatrans.h"
#include "i_time.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -342,10 +343,9 @@ void GLSprite::Draw(int pass)
sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr;
if (cursec != nullptr)
{
PalEntry finalcol(ThingColor.a,
ThingColor.r * cursec->SpecialColors[sector_t::sprites].r / 255,
ThingColor.g * cursec->SpecialColors[sector_t::sprites].g / 255,
ThingColor.b * cursec->SpecialColors[sector_t::sprites].b / 255);
const PalEntry finalcol = fullbright
? ThingColor
: ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
gl_RenderState.SetObjectColor(finalcol);
}
@ -1210,9 +1210,16 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
}
}
x = particle->Pos.X;
y = particle->Pos.Y;
z = particle->Pos.Z;
double timefrac = r_viewpoint.TicFrac;
if (paused || bglobal.freeze)
timefrac = 0.;
float xvf = (particle->Vel.X) * timefrac;
float yvf = (particle->Vel.Y) * timefrac;
float zvf = (particle->Vel.Z) * timefrac;
x = float(particle->Pos.X) + xvf;
y = float(particle->Pos.Y) + yvf;
z = float(particle->Pos.Z) + zvf;
float factor;
if (gl_particles_style == 1) factor = 1.3f / 7.f;

View file

@ -441,6 +441,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
hi.plane.GetFromSector(fs, sector_t::ceiling);
hi.lightlevel = gl_ClampLight(fs->GetCeilingLight());
hi.colormap = fs->Colormap;
hi.specialcolor = fs->SpecialColors[sector_t::ceiling];
if (fs->e->XFloor.ffloors.Size())
{
@ -469,6 +470,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
hi.plane.GetFromSector(fs, sector_t::floor);
hi.lightlevel = gl_ClampLight(fs->GetFloorLight());
hi.colormap = fs->Colormap;
hi.specialcolor = fs->SpecialColors[sector_t::floor];
if (fs->e->XFloor.ffloors.Size())
{
@ -826,7 +828,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
back->GetTexture(sector_t::ceiling) == skyflatnum)
{
// intra-sky lines do not clip the texture at all if there's no upper texture
topleft = topright = texturetop;
topleft = topright = wrap ? 1e16f : texturetop;
}
else
{

View file

@ -385,18 +385,18 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
// now draw the different layers of the weapon.
// For stencil render styles brightmaps need to be disabled.
gl_RenderState.EnableBrightmap(!(RenderStyle.Flags & STYLEF_ColorIsFixed));
PalEntry finalcol(ThingColor.a,
ThingColor.r * viewsector->SpecialColors[sector_t::sprites].r / 255,
ThingColor.g * viewsector->SpecialColors[sector_t::sprites].g / 255,
ThingColor.b * viewsector->SpecialColors[sector_t::sprites].b / 255);
const bool bright = isBright(psp);
const PalEntry finalcol = bright
? ThingColor
: ThingColor.Modulate(viewsector->SpecialColors[sector_t::sprites]);
gl_RenderState.SetObjectColor(finalcol);
if (psp->GetState() != nullptr)
{
FColormap cmc = cm;
int ll = lightlevel;
if (isBright(psp))
if (bright)
{
if (fakesec == viewsector || in_area != area_below)
{
@ -487,4 +487,4 @@ void GLSceneDrawer::DrawTargeterSprites()
{
if (psp->GetState() != nullptr) DrawPSprite(player, psp, psp->x, psp->y, false, 0, false);
}
}
}

View file

@ -50,19 +50,19 @@ void QuadStereo::checkInitialRenderContextState()
{
// Keep trying until we see at least one good OpenGL context to render to
static bool bDecentContextWasFound = false;
if (!bDecentContextWasFound) {
// I'm using a "random" OpenGL call (glGetFramebufferAttachmentParameteriv)
// that appears to correlate with whether the context is ready
GLint attachmentType = GL_NONE;
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
if (attachmentType != GL_NONE) // Finally, a useful OpenGL context
static int contextCheckCount = 0;
if ( (! bDecentContextWasFound) && (contextCheckCount < 200) )
{
contextCheckCount += 1;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // This question is about the main screen display context
GLboolean supportsStereo, supportsBuffered;
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
if (supportsBuffered) // Finally, a useful OpenGL context
{
// This block will be executed exactly ONCE during a game run
bDecentContextWasFound = true; // now we can stop checking every frame...
// Now check whether this context supports hardware stereo
GLboolean supportsStereo, supportsBuffered;
glGetBooleanv(GL_STEREO, &supportsStereo);
glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered);
bQuadStereoSupported = supportsStereo && supportsBuffered;
leftEye.bQuadStereoSupported = bQuadStereoSupported;
rightEye.bQuadStereoSupported = bQuadStereoSupported;

View file

@ -56,7 +56,6 @@
EXTERN_CVAR (Float, vid_brightness)
EXTERN_CVAR (Float, vid_contrast)
EXTERN_CVAR (Bool, vid_vsync)
EXTERN_CVAR(Int, vid_scalemode)
CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
@ -487,7 +486,7 @@ void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int
//
//===========================================================================
void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
const auto &viewport = GLRenderer->mOutputLetterbox;
@ -527,6 +526,10 @@ void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch,
pitch = -w*3;
color_type = SS_RGB;
buffer = ScreenshotBuffer + w * 3 * (h - 1);
// Screenshot should not use gamma correction if it was already applied to rendered image
EXTERN_CVAR(Bool, fullscreen);
gamma = 1 == vid_hwgamma || (2 == vid_hwgamma && !fullscreen) ? 1.0f : Gamma;
}
//===========================================================================

View file

@ -51,7 +51,7 @@ public:
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
// points to the last row in the buffer, which will be the first row output.
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
// Releases the screenshot buffer.
virtual void ReleaseScreenshotBuffer();

View file

@ -44,6 +44,7 @@ RenderContext gl;
EXTERN_CVAR(Bool, gl_legacy_mode)
extern int currentrenderer;
CVAR(Bool, gl_riskymodernpath, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//==========================================================================
//
@ -209,7 +210,10 @@ void gl_LoadExtensions()
// The minimum requirement for the modern render path is GL 3.3.
// Although some GL 3.1 or 3.2 solutions may theoretically work they are usually too broken or too slow.
// unless, of course, we're simply using this as a software backend...
if ((gl_version < 3.3f && (currentrenderer==1)) || gl_version < 3.0f)
float minmodernpath = 3.3f;
if (gl_riskymodernpath)
minmodernpath = 3.1f;
if ((gl_version < minmodernpath && (currentrenderer==1)) || gl_version < 3.0f)
{
gl.legacyMode = true;
gl.lightmethod = LM_LEGACY;

View file

@ -1671,15 +1671,15 @@ void OpenGLSWFrameBuffer::SetBlendingRect(int x1, int y1, int x2, int y2)
//
//==========================================================================
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
/*
LockedRect lrect;
if (!Accel2D)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
return;
}
buffer = nullptr;
@ -1702,6 +1702,7 @@ void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch
buffer = (const uint8_t *)lrect.pBits;
pitch = lrect.Pitch;
color_type = SS_BGRA;
gamma = Gamma;
}
}
*/

View file

@ -44,7 +44,7 @@ public:
int GetPageCount() override;
void SetVSync(bool vsync) override;
void NewRefreshRate() override;
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type) override;
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
void ReleaseScreenshotBuffer() override;
void SetBlendingRect(int x1, int y1, int x2, int y2) override;
bool Begin2D(bool copy3d) override;

View file

@ -164,6 +164,11 @@ uint64_t I_msTime()
return NSToMS(I_nsTime());
}
uint64_t I_msTimeFS() // from "start"
{
return (FirstFrameStartTime == 0) ? 0 : NSToMS(I_nsTime() - FirstFrameStartTime);
}
int I_GetTime()
{
return NSToTic(CurrentFrameStartTime - FirstFrameStartTime);

View file

@ -22,5 +22,8 @@ void I_FreezeTime(bool frozen);
// [RH] Returns millisecond-accurate time
uint64_t I_msTime();
// [SP] Returns millisecond-accurate time from start
uint64_t I_msTimeFS();
// Nanosecond-accurate time
uint64_t I_nsTime();

View file

@ -7,7 +7,7 @@
// Unfortunately, the Scale function still gets badly handled on 32 bit x86 platforms so it's the last remaining piece of inline assembly
// GCC inlines
#if defined(__GNUC__) && defined(__i386__) && !defined(__clang__)
#if defined(__GNUC__) && defined(__i386__) && !defined(__clang__) && !defined(__PIC__)
#ifndef alloca
// MinGW does not seem to come with alloca defined.
#define alloca __builtin_alloca

View file

@ -315,7 +315,7 @@ void M_SaveDefaultsFinal ()
GameConfig = NULL;
}
CCMD (writeini)
UNSAFE_CCMD (writeini)
{
const char *filename = (argv.argc() == 1) ? NULL : argv[1];
if (!M_SaveDefaults (filename))
@ -521,11 +521,11 @@ void WritePCXfile (FileWriter *file, const uint8_t *buffer, const PalEntry *pale
// WritePNGfile
//
void WritePNGfile (FileWriter *file, const uint8_t *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
ESSType color_type, int width, int height, int pitch, float gamma)
{
char software[100];
mysnprintf(software, countof(software), GAMENAME " %s", GetVersionString());
if (!M_CreatePNG (file, buffer, palette, color_type, width, height, pitch) ||
if (!M_CreatePNG (file, buffer, palette, color_type, width, height, pitch, gamma) ||
!M_AppendPNGText (file, "Software", software) ||
!M_FinishPNG (file))
{
@ -626,8 +626,9 @@ void M_ScreenShot (const char *filename)
const uint8_t *buffer;
int pitch;
ESSType color_type;
float gamma;
screen->GetScreenshotBuffer(buffer, pitch, color_type);
screen->GetScreenshotBuffer(buffer, pitch, color_type, gamma);
if (buffer != NULL)
{
PalEntry palette[256];
@ -651,7 +652,7 @@ void M_ScreenShot (const char *filename)
else
{
WritePNGfile(file, buffer, palette, color_type,
screen->GetWidth(), screen->GetHeight(), pitch);
screen->GetWidth(), screen->GetHeight(), pitch, gamma);
}
delete file;
screen->ReleaseScreenshotBuffer();

View file

@ -132,7 +132,7 @@ CVAR(Float, png_gamma, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//==========================================================================
bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
ESSType color_type, int width, int height, int pitch, float gamma)
{
uint8_t work[8 + // signature
12+2*4+5 + // IHDR
@ -157,7 +157,7 @@ bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *palet
MakeChunk (ihdr, MAKE_ID('I','H','D','R'), 2*4+5);
// Assume a display exponent of 2.2 (100000/2.2 ~= 45454.5)
*gama = BigLong (int (45454.5f * (png_gamma == 0.f ? Gamma : png_gamma)));
*gama = BigLong (int (45454.5f * (png_gamma == 0.f ? gamma : png_gamma)));
MakeChunk (gama, MAKE_ID('g','A','M','A'), 4);
if (color_type == SS_PAL)

View file

@ -46,7 +46,7 @@ class FileWriter;
// This function writes the PNG signature and the IHDR, gAMA, PLTE, and IDAT
// chunks.
bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *pal,
ESSType color_type, int width, int height, int pitch);
ESSType color_type, int width, int height, int pitch, float gamma);
// Creates a grayscale 1x1 PNG file. Used for savegames without savepics.
bool M_CreateDummyPNG (FileWriter *file);

View file

@ -735,7 +735,11 @@ void M_Ticker (void)
if (CurrentMenu != nullptr && menuactive != MENU_Off)
{
CurrentMenu->CallTicker();
}
// Check again because menu could be closed from Ticker()
if (CurrentMenu != nullptr && menuactive != MENU_Off)
{
for (int i = 0; i < NUM_MKEYS; ++i)
{
if (MenuButtons[i].bDown)

View file

@ -542,7 +542,7 @@ static bool FindMatchingItem(DMenuItemBase *desc)
{
// Check for presence of menu
auto menu = MenuDescriptors.CheckKey(name);
if (menu == nullptr) return true;
if (menu == nullptr) return false;
}
else if (grp == 4)
{

View file

@ -139,6 +139,7 @@ void ActivateEndGameMenu()
M_ClearMenus();
if (!netgame)
{
G_CheckDemoStatus();
D_StartTitle();
}
});

View file

@ -502,6 +502,7 @@ xx(Roll)
xx(Scale)
xx(ScaleX)
xx(ScaleY)
xx(FriendlySeeBlocks)
xx(Floatbobphase)
xx(Floatbobstrength)
xx(Target)

View file

@ -644,7 +644,7 @@ inline int PitchToACS(DAngle ang)
struct CallReturn
{
CallReturn(int pc, ScriptFunction *func, FBehavior *module, int32_t *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
CallReturn(int pc, ScriptFunction *func, FBehavior *module, const ACSLocalVariables &locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
: ReturnFunction(func),
ReturnModule(module),
ReturnLocals(locals),
@ -656,7 +656,7 @@ struct CallReturn
ScriptFunction *ReturnFunction;
FBehavior *ReturnModule;
int32_t *ReturnLocals;
ACSLocalVariables ReturnLocals;
ACSLocalArrays *ReturnArrays;
int ReturnAddress;
int bDiscardResult;
@ -815,7 +815,7 @@ TArray<FString> ACS_StringBuilderStack;
//
//============================================================================
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__)
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
inline int uallong(const int &foo)
{
return foo;
@ -851,9 +851,25 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
//
//----------------------------------------------------------------------------
struct FACSStackMemory
{
int32_t& operator[](const size_t index)
{
if (index >= STACK_SIZE)
{
I_Error("Corrupted stack pointer in ACS VM");
}
return buffer[index];
}
private:
int32_t buffer[STACK_SIZE];
};
struct FACSStack
{
int32_t buffer[STACK_SIZE];
FACSStackMemory buffer;
int sp;
FACSStack *next;
FACSStack *prev;
@ -1488,7 +1504,20 @@ void P_CollectACSGlobalStrings()
{
for (FACSStack *stack = FACSStack::head; stack != NULL; stack = stack->next)
{
GlobalACSStrings.MarkStringArray(stack->buffer, stack->sp);
const int32_t sp = stack->sp;
if (0 == sp)
{
continue;
}
else if (sp < 0 && sp >= STACK_SIZE)
{
I_Error("Corrupted stack pointer in ACS VM");
}
else
{
GlobalACSStrings.MarkStringArray(&stack->buffer[0], sp);
}
}
FBehavior::StaticMarkLevelVarStrings();
P_MarkWorldVarStrings();
@ -2338,7 +2367,7 @@ void FBehavior::SerializeVarSet (FSerializer &arc, int32_t *vars, int max)
static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset)
{
unsigned count = (LittleShort(static_cast<unsigned short>(((unsigned *)chunk)[1]) - 2)) / 4;
unsigned count = LittleShort(static_cast<unsigned short>(((unsigned *)chunk)[1] - 2)) / 4;
int *sizes = (int *)((uint8_t *)chunk + 10);
arrays->Count = count;
if (count > 0)
@ -3655,6 +3684,12 @@ void DLevelScript::Serialize(FSerializer &arc)
if (arc.isReading())
{
activeBehavior = FBehavior::StaticGetModule(lib);
if (nullptr == activeBehavior)
{
I_Error("Could not find ACS module");
}
pc = activeBehavior->Ofs2PC(pcofs);
}
}
@ -6883,7 +6918,7 @@ inline int getshort (int *&pc)
return res;
}
static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged)
static bool CharArrayParms(int &capacity, int &offset, int &a, FACSStackMemory& Stack, int &sp, bool ranged)
{
if (ranged)
{
@ -6932,7 +6967,7 @@ static void SetMarineSprite(AActor *marine, PClassActor *source)
int DLevelScript::RunScript ()
{
DACSThinker *controller = DACSThinker::ActiveThinker;
int32_t *locals = &Localvars[0];
ACSLocalVariables locals(Localvars);
ACSLocalArrays noarrays;
ACSLocalArrays *localarrays = &noarrays;
ScriptFunction *activeFunction = NULL;
@ -7006,7 +7041,7 @@ int DLevelScript::RunScript ()
}
FACSStack stackobj;
int32_t *Stack = stackobj.buffer;
FACSStackMemory& Stack = stackobj.buffer;
int &sp = stackobj.sp;
int *pc = this->pc;
@ -7300,7 +7335,6 @@ int DLevelScript::RunScript ()
int i;
ScriptFunction *func;
FBehavior *module;
int32_t *mylocals;
if(pcd == PCD_CALLSTACK)
{
@ -7329,9 +7363,9 @@ int DLevelScript::RunScript ()
state = SCRIPT_PleaseRemove;
break;
}
mylocals = locals;
const ACSLocalVariables mylocals = locals;
// The function's first argument is also its first local variable.
locals = &Stack[sp - func->ArgCount];
locals.Reset(&Stack[sp - func->ArgCount], func->ArgCount + func->LocalCount);
// Make space on the stack for any other variables the function uses.
for (i = 0; i < func->LocalCount; ++i)
{
@ -7370,7 +7404,7 @@ int DLevelScript::RunScript ()
sp -= sizeof(CallReturn)/sizeof(int);
retsp = &Stack[sp];
activeBehavior->GetFunctionProfileData(activeFunction)->AddRun(runaway - ret->EntryInstrCount);
sp = int(locals - Stack);
sp = int(locals.GetPointer() - &Stack[0]);
pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress);
activeFunction = ret->ReturnFunction;
activeBehavior = ret->ReturnModule;

View file

@ -147,6 +147,44 @@ struct ProfileCollector
int Index;
};
class ACSLocalVariables
{
public:
ACSLocalVariables(TArray<int32_t> &variables)
: memory(&variables[0])
, count(variables.Size())
{
}
void Reset(int32_t *const memory, const size_t count)
{
// TODO: pointer sanity check?
// TODO: constraints on count?
this->memory = memory;
this->count = count;
}
int32_t& operator[](const size_t index)
{
if (index >= count)
{
I_Error("Out of bounds access to local variables in ACS VM");
}
return memory[index];
}
const int32_t *GetPointer() const
{
return memory;
}
private:
int32_t *memory;
size_t count;
};
struct ACSLocalArrayInfo
{
unsigned int Size;
@ -173,7 +211,7 @@ struct ACSLocalArrays
}
// Bounds-checking Set and Get for local arrays
void Set(int *locals, int arraynum, int arrayentry, int value)
void Set(ACSLocalVariables &locals, int arraynum, int arrayentry, int value)
{
if ((unsigned int)arraynum < Count &&
(unsigned int)arrayentry < Info[arraynum].Size)
@ -181,7 +219,7 @@ struct ACSLocalArrays
locals[Info[arraynum].Offset + arrayentry] = value;
}
}
int Get(int *locals, int arraynum, int arrayentry)
int Get(ACSLocalVariables &locals, int arraynum, int arrayentry)
{
if ((unsigned int)arraynum < Count &&
(unsigned int)arrayentry < Info[arraynum].Size)

View file

@ -3575,17 +3575,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetBlend)
PARAM_FLOAT (alpha);
PARAM_INT (tics);
PARAM_COLOR_DEF (color2);
PARAM_FLOAT_DEF (alpha2);
if (color == MAKEARGB(255,255,255,255))
color = 0;
if (color2 == MAKEARGB(255,255,255,255))
color2 = 0;
if (color2.a == 0)
color2 = color;
// if (color2.a == 0)
// color2 = color;
Create<DFlashFader>(color.r/255.f, color.g/255.f, color.b/255.f, float(alpha),
color2.r/255.f, color2.g/255.f, color2.b/255.f, 0.f,
float(tics)/TICRATE, self);
color2.r/255.f, color2.g/255.f, color2.b/255.f, float(alpha2),
float(tics)/TICRATE, self, true);
return 0;
}

View file

@ -1044,7 +1044,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
player->SetLogNumber(reply->LogNumber);
}
if (replyText != NULL && isconsole)
if (nullptr != replyText && '\0' != replyText[0] && isconsole)
{
TerminalResponse(replyText);
}

View file

@ -711,9 +711,13 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay,
}
picnum = m_Line1->sidedef[0]->GetTexture(side_t::top);
m_Line1->sidedef[0]->SetTexture(side_t::mid, picnum);
m_Line2->sidedef[0]->SetTexture(side_t::mid, picnum);
auto &tex1 = m_Line1->sidedef[0]->textures;
tex1[side_t::mid].InitFrom(tex1[side_t::top]);
auto &tex2 = m_Line2->sidedef[0]->textures;
tex2[side_t::mid].InitFrom(tex2[side_t::top]);
picnum = tex1[side_t::top].texture;
// don't forget texture scaling here!
FTexture *tex = TexMan[picnum];

View file

@ -52,7 +52,7 @@ struct particle_t
double size;
double sizestep;
subsector_t * subsector;
short ttl;
int32_t ttl;
uint8_t bright;
bool notimefreeze;
float fadestep;

View file

@ -1704,7 +1704,7 @@ bool P_LookForEnemies (AActor *actor, INTBOOL allaround, FLookExParams *params)
{
AActor *other;
other = P_BlockmapSearch (actor, 10, LookForEnemiesInBlock, params);
other = P_BlockmapSearch (actor, actor->friendlyseeblocks, LookForEnemiesInBlock, params);
if (other != NULL)
{

View file

@ -1137,7 +1137,8 @@ static void CreateCachedNodes(MapData *map)
if (fw != nullptr)
{
if (fw->Write(compressed, outlen+offset) != 1)
const size_t length = outlen + offset;
if (fw->Write(compressed, length) != length)
{
Printf("Error saving nodes to file %s\n", path.GetChars());
}

View file

@ -903,8 +903,7 @@ void P_AutoUseStrifeHealth (player_t *player)
static inline bool MustForcePain(AActor *target, AActor *inflictor)
{
return (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS));
return (inflictor && (inflictor->flags6 & MF6_FORCEPAIN));
}
static inline bool isFakePain(AActor *target, AActor *inflictor, int damage)
@ -928,6 +927,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
bool invulpain = false;
bool fakedPain = false;
bool forcedPain = false;
bool noPain = false;
int fakeDamage = 0;
int holdDamage = 0;
const int rawdamage = damage;
@ -940,9 +940,14 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
return 0;
}
//Rather than unnecessarily call the function over and over again, let's be a little more efficient.
fakedPain = (isFakePain(target, inflictor, damage));
forcedPain = (MustForcePain(target, inflictor));
// Rather than unnecessarily call the function over and over again, let's be a little more efficient.
// But first, check and see if it's even needed, which it won't be if pain must not be triggered.
noPain = ((flags & DMG_NO_PAIN) || (target->flags5 & MF5_NOPAIN) || (inflictor && (inflictor->flags5 & MF5_PAINLESS)));
if (!noPain)
{
fakedPain = (isFakePain(target, inflictor, damage));
forcedPain = (MustForcePain(target, inflictor));
}
// Spectral targets only take damage from spectral projectiles.
if (target->flags4 & MF4_SPECTRAL && !telefragDamage)
@ -1306,7 +1311,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
{ // player is invulnerable, so don't hurt him
//Make sure no godmodes and NOPAIN flags are found first.
//Then, check to see if the player has NODAMAGE or ALLOWPAIN, or inflictor has CAUSEPAIN.
if ((player->cheats & CF_GODMODE) || (player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NOPAIN))
if ((flags & DMG_NO_PAIN) || (player->cheats & CF_GODMODE) || (player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NOPAIN))
return 0;
else if ((((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
{
@ -1333,7 +1338,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
if (damage <= 0)
{
// [MC] Godmode doesn't need checking here, it's already being handled above.
if ((target->flags5 & MF5_NOPAIN) || (inflictor && (inflictor->flags5 & MF5_PAINLESS)))
if (noPain)
return 0;
// If MF6_FORCEPAIN is set, make the player enter the pain state.
@ -1522,7 +1527,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
fakepain: //Needed so we can skip the rest of the above, but still obey the original rules.
if (!(target->flags5 & MF5_NOPAIN) && (inflictor == NULL || !(inflictor->flags5 & MF5_PAINLESS)) &&
if (!noPain &&
(target->player != NULL || !G_SkillProperty(SKILLP_NoPain)) && !(target->flags & MF_SKULLFLY))
{
painchance = target->PainChance;

View file

@ -437,6 +437,7 @@ enum EDmgFlags
DMG_FOILBUDDHA = 128,
DMG_NO_PROTECT = 256,
DMG_USEANGLE = 512,
DMG_NO_PAIN = 1024,
};

View file

@ -856,7 +856,7 @@ static int LineIsBelow(line_t *line, AActor *actor)
//==========================================================================
static // killough 3/26/98: make static
bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tm)
bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tm, const bool wasfit)
{
line_t *ld = cres.line;
bool rail = false;
@ -902,12 +902,15 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
{
tm.floorz = portz;
tm.floorsector = cres.line->frontsector;
tm.floorpic = cres.line->sidedef[0]->GetTexture(side_t::mid);
tm.floorterrain = 0;
tm.portalstep = true;
tm.portalgroup = cres.line->frontsector->GetOppositePortalGroup(sector_t::ceiling);
if (wasfit)
{
tm.floorz = portz;
tm.floorsector = cres.line->frontsector;
tm.floorpic = cres.line->sidedef[0]->GetTexture(side_t::mid);
tm.floorterrain = 0;
tm.portalstep = true;
tm.portalgroup = cres.line->frontsector->GetOppositePortalGroup(sector_t::ceiling);
}
return true;
}
}
@ -916,7 +919,10 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
{
P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee);
}
tm.thing->BlockingLine = ld;
if (wasfit)
{
tm.thing->BlockingLine = ld;
}
CheckForPushSpecial(ld, 0, tm.thing);
return false;
}
@ -948,12 +954,15 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
if (state == -1) return true;
if (state == 1)
{
// the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line.
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::floor);
if (portalz < tm.ceilingz)
if (wasfit)
{
tm.ceilingz = portalz;
tm.ceilingsector = cres.line->frontsector;
// the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line.
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::floor);
if (portalz < tm.ceilingz)
{
tm.ceilingz = portalz;
tm.ceilingsector = cres.line->frontsector;
}
}
return true;
}
@ -965,12 +974,15 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
if (state == -1) return true;
if (state == 1)
{
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
if (portalz > tm.floorz)
if (wasfit)
{
tm.floorz = portalz;
tm.floorsector = cres.line->frontsector;
tm.floorterrain = 0;
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
if (portalz > tm.floorz)
{
tm.floorz = portalz;
tm.floorsector = cres.line->frontsector;
tm.floorterrain = 0;
}
}
return true;
}
@ -981,7 +993,10 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
{
P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee);
}
tm.thing->BlockingLine = ld;
if (wasfit)
{
tm.thing->BlockingLine = ld;
}
// Calculate line side based on the actor's original position, not the new one.
CheckForPushSpecial(ld, P_PointOnLineSide(cres.Position, ld), tm.thing);
return false;
@ -1000,9 +1015,12 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
double portz = tm.thing->Sector->GetPortalPlaneZ(sector_t::ceiling);
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
{
// Actor is stepping through a portal.
tm.portalstep = true;
tm.portalgroup = tm.thing->Sector->GetOppositePortalGroup(sector_t::ceiling);
if (wasfit)
{
// Actor is stepping through a portal.
tm.portalstep = true;
tm.portalgroup = tm.thing->Sector->GetOppositePortalGroup(sector_t::ceiling);
}
return true;
}
}
@ -1042,41 +1060,44 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
open.bottom += 32;
}
// adjust floor / ceiling heights
if (!(cres.portalflags & FFCF_NOCEILING))
if (wasfit)
{
if (open.top < tm.ceilingz)
// adjust floor / ceiling heights
if (!(cres.portalflags & FFCF_NOCEILING))
{
tm.ceilingz = open.top;
tm.ceilingsector = open.topsec;
tm.ceilingpic = open.ceilingpic;
tm.ceilingline = ld;
tm.thing->BlockingLine = ld;
}
}
// If we are stepping through a portal the line's opening must be checked, regardless of the NOFLOOR flag
if (!(cres.portalflags & FFCF_NOFLOOR) || (tm.portalstep && open.bottomsec->PortalGroup == tm.portalgroup))
{
if (open.bottom > tm.floorz)
{
tm.floorz = open.bottom;
tm.floorsector = open.bottomsec;
tm.floorpic = open.floorpic;
tm.floorterrain = open.floorterrain;
tm.touchmidtex = open.touchmidtex;
tm.abovemidtex = open.abovemidtex;
tm.thing->BlockingLine = ld;
}
else if (open.bottom == tm.floorz)
{
tm.touchmidtex |= open.touchmidtex;
tm.abovemidtex |= open.abovemidtex;
if (open.top < tm.ceilingz)
{
tm.ceilingz = open.top;
tm.ceilingsector = open.topsec;
tm.ceilingpic = open.ceilingpic;
tm.ceilingline = ld;
tm.thing->BlockingLine = ld;
}
}
if (open.lowfloor < tm.dropoffz)
// If we are stepping through a portal the line's opening must be checked, regardless of the NOFLOOR flag
if (!(cres.portalflags & FFCF_NOFLOOR) || (tm.portalstep && open.bottomsec->PortalGroup == tm.portalgroup))
{
tm.dropoffz = open.lowfloor;
if (open.bottom > tm.floorz)
{
tm.floorz = open.bottom;
tm.floorsector = open.bottomsec;
tm.floorpic = open.floorpic;
tm.floorterrain = open.floorterrain;
tm.touchmidtex = open.touchmidtex;
tm.abovemidtex = open.abovemidtex;
tm.thing->BlockingLine = ld;
}
else if (open.bottom == tm.floorz)
{
tm.touchmidtex |= open.touchmidtex;
tm.abovemidtex |= open.abovemidtex;
}
if (open.lowfloor < tm.dropoffz)
{
tm.dropoffz = open.lowfloor;
}
}
}
@ -1881,7 +1902,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
while (it.Next(&lcres))
{
bool thisresult = PIT_CheckLine(it, lcres, it.Box(), tm);
bool thisresult = PIT_CheckLine(it, lcres, it.Box(), tm, good);
good &= thisresult;
if (thisresult)
{
@ -2763,9 +2784,8 @@ DEFINE_ACTION_FUNCTION(AActor, TryMove)
//
//==========================================================================
bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags)
static bool P_CheckMove(AActor *thing, const DVector2 &pos, FCheckPosition& tm, int flags)
{
FCheckPosition tm;
double newz = thing->Z();
auto f1 = thing->flags & MF_PICKUP;
@ -2858,6 +2878,28 @@ bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags)
return true;
}
bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags)
{
FCheckPosition tm;
return P_CheckMove(thing, pos, tm, flags);
}
DEFINE_ACTION_FUNCTION(AActor, CheckMove)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT_DEF(flags);
PARAM_POINTER_DEF(tm, FCheckPosition);
if (tm == nullptr)
{
ACTION_RETURN_BOOL(P_CheckMove(self, DVector2(x, y), flags));
}
else
{
ACTION_RETURN_BOOL(P_CheckMove(self, DVector2(x, y), *tm, flags));
}
}
//==========================================================================
@ -5920,10 +5962,7 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos)
}
bool isgood = P_CheckPosition(thing, thing->Pos(), tm);
// This is essentially utterly broken because it even uses the return from a failed P_CheckPosition but the entire logic will break down if that isn't done.
// However, if tm.floorz is greater than tm.ceilingz we have a real problem that needs to be dealt with exolicitly.
if (!(thing->flags4 & MF4_ACTLIKEBRIDGE) && tm.floorz <= tm.ceilingz)
if (!(thing->flags4 & MF4_ACTLIKEBRIDGE))
{
thing->floorz = tm.floorz;
thing->ceilingz = tm.ceilingz;

View file

@ -343,6 +343,16 @@ void AActor::UnlinkFromWorld (FLinkContext *ctx)
}
BlockNode = NULL;
}
ClearRenderSectorList();
ClearRenderLineList();
}
DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER_DEF(ctx, FLinkContext);
self->UnlinkFromWorld(ctx); // fixme
return 0;
}
@ -429,15 +439,6 @@ bool AActor::FixMapthingPos()
return success;
}
DEFINE_ACTION_FUNCTION(AActor, UnlinkFromWorld)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_POINTER_DEF(ctx, FLinkContext);
self->UnlinkFromWorld(ctx); // fixme
return 0;
}
//==========================================================================
//
// P_SetThingPosition
@ -1274,20 +1275,21 @@ void FMultiBlockThingsIterator::Reset()
//
//===========================================================================
class DBlockThingsIterator : public DObject, public FMultiBlockThingsIterator
class DBlockThingsIterator : public DObject
{
DECLARE_ABSTRACT_CLASS(DBlockThingsIterator, DObject);
FPortalGroupArray check;
FMultiBlockThingsIterator iterator;
public:
FMultiBlockThingsIterator::CheckResult cres;
bool Next()
{
return FMultiBlockThingsIterator::Next(&cres);
return iterator.Next(&cres);
}
DBlockThingsIterator(AActor *origin, double checkradius = -1, bool ignorerestricted = false)
: FMultiBlockThingsIterator(check, origin, checkradius, ignorerestricted)
: iterator(check, origin, checkradius, ignorerestricted)
{
cres.thing = nullptr;
cres.Position.Zero();
@ -1295,7 +1297,7 @@ public:
}
DBlockThingsIterator(double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec)
: FMultiBlockThingsIterator(check, checkx, checky, checkz, checkh, checkradius, ignorerestricted, newsec)
: iterator(check, checkx, checky, checkz, checkh, checkradius, ignorerestricted, newsec)
{
cres.thing = nullptr;
cres.Position.Zero();

View file

@ -355,6 +355,7 @@ DEFINE_FIELD(AActor, BloodColor)
DEFINE_FIELD(AActor, BloodTranslation)
DEFINE_FIELD(AActor, RenderHidden)
DEFINE_FIELD(AActor, RenderRequired)
DEFINE_FIELD(AActor, friendlyseeblocks)
//==========================================================================
//
@ -533,6 +534,7 @@ void AActor::Serialize(FSerializer &arc)
A("stealthalpha", StealthAlpha)
A("renderhidden", RenderHidden)
A("renderrequired", RenderRequired);
A("friendlyseeblocks", friendlyseeblocks);
}
#undef A
@ -823,16 +825,24 @@ bool AActor::GiveInventory(PClassActor *type, int amount, bool givecheat)
item->ClearCounters();
if (!givecheat || amount > 0)
{
if (type->IsDescendantOf (PClass::FindActor(NAME_BasicArmorPickup)) || type->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus)))
if (type->IsDescendantOf(NAME_BasicArmorPickup) || type->IsDescendantOf(NAME_BasicArmorBonus))
{
item->IntVar(NAME_SaveAmount) *= amount;
}
else
{
if (!givecheat)
item->Amount = amount;
if (givecheat)
{
const AInventory *const haveitem = FindInventory(type);
item->Amount = MIN(amount, nullptr == haveitem
? static_cast<AInventory*>(GetDefaultByType(type))->MaxAmount
: haveitem->MaxAmount);
}
else
item->Amount = MIN (amount, item->MaxAmount);
{
item->Amount = amount;
}
}
}
if (!item->CallTryPickup (this))
@ -5648,7 +5658,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
{ // Give all cards in death match mode.
p->mo->GiveDeathmatchInventory ();
}
else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn) && state == PST_REBORN && oldactor != NULL)
else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn ||
!!G_SkillProperty(SKILLP_PlayerRespawn)) && state == PST_REBORN && oldactor != NULL)
{ // Special inventory handling for respawning in coop
p->mo->FilterCoopRespawnInventory (oldactor);
}
@ -6018,6 +6029,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
mobj->SpawnPoint = mthing->pos;
mobj->SpawnAngle = mthing->angle;
mobj->SpawnFlags = mthing->flags;
if (mthing->friendlyseeblocks > 0)
mobj->friendlyseeblocks = mthing->friendlyseeblocks;
if (mthing->FloatbobPhase >= 0 && mthing->FloatbobPhase < 64) mobj->FloatBobPhase = mthing->FloatbobPhase;
if (mthing->Gravity < 0) mobj->Gravity = -mthing->Gravity;
else if (mthing->Gravity > 0) mobj->Gravity *= mthing->Gravity;
@ -8454,5 +8467,6 @@ void PrintMiscActorInfo(AActor *query)
Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n",
query->Speed, query->Vel.X, query->Vel.Y, query->Vel.Z, query->Vel.Length());
Printf("Scale: x:%f, y:%f\n", query->Scale.X, query->Scale.Y);
Printf("FriendlySeeBlocks: %d\n", query->friendlyseeblocks);
}
}

View file

@ -116,6 +116,7 @@
#include "events.h"
#include "types.h"
#include "i_time.h"
#include "scripting/vm/vm.h"
#include "fragglescript/t_fs.h"
@ -552,6 +553,18 @@ void MapData::GetChecksum(uint8_t cksum[16])
md5.Final(cksum);
}
DEFINE_ACTION_FUNCTION(FLevelLocals, GetChecksum)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
char md5string[33];
for(int j = 0; j < 16; ++j)
{
sprintf(md5string + j * 2, "%02x", level.md5[j]);
}
ACTION_RETURN_STRING((const char*)md5string);
}
//===========================================================================
//
@ -1818,6 +1831,7 @@ void P_LoadThings2 (MapData * map)
mti[i].Alpha = -1;
mti[i].Health = 1;
mti[i].FloatbobPhase = -1;
mti[i].friendlyseeblocks = -1;
}
delete[] mtp;
}
@ -3627,7 +3641,7 @@ void P_SetupLevel (const char *lumpname, int position)
bool buildmap;
const int *oldvertextable = NULL;
level.ShaderStartTime = I_msTime(); // indicate to the shader system that the level just started
level.ShaderStartTime = I_msTimeFS(); // indicate to the shader system that the level just started
// This is motivated as follows:
@ -3815,8 +3829,6 @@ void P_SetupLevel (const char *lumpname, int position)
P_LoadThings (map);
else
P_LoadThings2 (map); // [RH] Load Hexen-style things
SetCompatibilityParams();
}
else
{
@ -3825,6 +3837,8 @@ void P_SetupLevel (const char *lumpname, int position)
times[0].Unclock();
}
SetCompatibilityParams();
times[6].Clock();
P_LoopSidedefs (true);
times[6].Unclock();

View file

@ -799,6 +799,11 @@ public:
th->Scale.X = th->Scale.Y = CheckFloat(key);
break;
case NAME_FriendlySeeBlocks:
CHECK_N(Zd | Zdt)
th->friendlyseeblocks = CheckInt(key);
break;
default:
CHECK_N(Zd | Zdt)
if (0 == strnicmp("user_", key.GetChars(), 5))

View file

@ -333,7 +333,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
args->v1 = &clippedvert[numclipvert - 1];
args->v2 = &clippedvert[i - 1];
args->v3 = &clippedvert[i - 2];
if (is_frontfacing(args) && args->CalculateGradients())
if (is_frontfacing(args) == ccw && args->CalculateGradients())
ScreenTriangle::Draw(args, thread);
}
}
@ -344,7 +344,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
args->v1 = &clippedvert[0];
args->v2 = &clippedvert[i - 1];
args->v3 = &clippedvert[i];
if (!is_frontfacing(args) && args->CalculateGradients())
if (is_frontfacing(args) != ccw && args->CalculateGradients())
ScreenTriangle::Draw(args, thread);
}
}

View file

@ -34,7 +34,10 @@ EXTERN_CVAR(Int, gl_particles_style)
void RenderPolyParticle::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
{
DVector3 pos = particle->Pos;
double timefrac = r_viewpoint.TicFrac;
if (paused || bglobal.freeze)
timefrac = 0.;
DVector3 pos = particle->Pos + (particle->Vel * timefrac);
double psize = particle->size / 8.0;
double zpos = pos.Z;

View file

@ -588,6 +588,12 @@ void ProcessKeyboardEvent(NSEvent* theEvent)
void ProcessKeyboardFlagsEvent(NSEvent* theEvent)
{
if (GUICapture)
{
// Ignore events from modifier keys in menu/console/chat
return;
}
static const uint32_t FLAGS_MASK =
NSDeviceIndependentModifierFlagsMask & ~NSNumericPadKeyMask;
@ -601,23 +607,15 @@ void ProcessKeyboardFlagsEvent(NSEvent* theEvent)
}
event_t event = {};
event.type = modifiers > oldModifiers ? EV_KeyDown : EV_KeyUp;
event.data1 = ModifierToDIK(deltaModifiers);
oldModifiers = modifiers;
// Caps Lock is a modifier key which generates one event per state change
// but not per actual key press or release. So treat any event as key down
// Also its event should be not be posted in menu and console
if (DIK_CAPITAL == event.data1)
{
if (GUICapture)
{
return;
}
// Caps Lock is a modifier key which generates one event per state change
// but not per actual key press or release. So treat any event as key down
event.type = EV_KeyDown;
}

View file

@ -60,6 +60,7 @@
// ---------------------------------------------------------------------------
CVAR (Bool, i_soundinbackground, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
EXTERN_CVAR(Int, vid_defwidth )
EXTERN_CVAR(Int, vid_defheight)
EXTERN_CVAR(Bool, vid_vsync )
@ -225,14 +226,7 @@ void OriginalMainTry(int argc, char** argv)
namespace
{
const int ARGC_MAX = 64;
int s_argc;
char* s_argv[ARGC_MAX];
TArray<FString> s_argvStorage;
bool s_restartedFromWADPicker;
TArray<FString> s_argv;
void NewFailure()
@ -323,7 +317,7 @@ ApplicationController* appCtrl;
{
ZD_UNUSED(aNotification);
S_SetSoundPaused(0);
S_SetSoundPaused((!!i_soundinbackground) || 0);
}
@ -347,7 +341,17 @@ ApplicationController* appCtrl;
FConsoleWindow::CreateInstance();
atterm(FConsoleWindow::DeleteInstance);
exit(OriginalMain(s_argc, s_argv));
const size_t argc = s_argv.Size();
TArray<char*> argv(argc + 1, true);
for (size_t i = 0; i < argc; ++i)
{
argv[i] = s_argv[i].LockBuffer();
}
argv[argc] = nullptr;
exit(OriginalMain(argc, &argv[0]));
}
@ -355,20 +359,13 @@ ApplicationController* appCtrl;
{
ZD_UNUSED(theApplication);
if (s_restartedFromWADPicker
|| 0 == [filename length]
|| s_argc + 2 >= ARGC_MAX)
{
return FALSE;
}
// Some parameters from command line are passed to this function
// These parameters need to be skipped to avoid duplication
// Note: SDL has different approach to fix this issue, see the same method in SDLMain.m
const char* const charFileName = [filename UTF8String];
for (int i = 0; i < s_argc; ++i)
for (size_t i = 0, count = s_argv.Size(); i < count; ++i)
{
if (0 == strcmp(s_argv[i], charFileName))
{
@ -376,11 +373,8 @@ ApplicationController* appCtrl;
}
}
s_argvStorage.Push("-file");
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
s_argvStorage.Push([filename UTF8String]);
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
s_argv.Push("-file");
s_argv.Push([filename UTF8String]);
return TRUE;
}
@ -538,21 +532,12 @@ void ReleaseApplicationController()
int main(int argc, char** argv)
{
for (int i = 0; i <= argc; ++i)
for (int i = 0; i < argc; ++i)
{
const char* const argument = argv[i];
if (NULL == argument || '\0' == argument[0])
{
continue;
}
if (0 == strcmp(argument, "-wad_picker_restart"))
{
s_restartedFromWADPicker = true;
}
#if _DEBUG
else if (0 == strcmp(argument, "-wait_for_debugger"))
if (0 == strcmp(argument, "-wait_for_debugger"))
{
NSAlert* alert = [[NSAlert alloc] init];
[alert setMessageText:@GAMENAME];
@ -561,11 +546,8 @@ int main(int argc, char** argv)
[alert runModal];
}
#endif // _DEBUG
else
{
s_argvStorage.Push(argument);
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
}
s_argv.Push(argument);
}
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

View file

@ -418,7 +418,6 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters)
executablePath = @"/usr/bin/arch";
}
[arguments addObject:@"-wad_picker_restart"];
[arguments addObject:@"-iwad"];
[arguments addObject:[NSString stringWithUTF8String:wad.Path]];

View file

@ -62,6 +62,7 @@ extern int paused;
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, i_soundinbackground, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
EXTERN_CVAR (Bool, fullscreen)
@ -312,7 +313,7 @@ void MessagePump (const SDL_Event &sev)
{
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_FOCUS_LOST:
S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED);
S_SetSoundPaused((!!i_soundinbackground) || sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED);
break;
}
break;

View file

@ -78,6 +78,30 @@ const uint8_t IcePalette[16][3] =
{ 148,148,172 }
};
static bool IndexOutOfRange(const int color)
{
const bool outOfRange = color < 0 || color > 255;
if (outOfRange)
{
Printf("Palette index %i is out of range [0..255]\n", color);
}
return outOfRange;
}
static bool IndexOutOfRange(const int start, const int end)
{
const bool outOfRange = IndexOutOfRange(start);
return IndexOutOfRange(end) || outOfRange;
}
static bool IndexOutOfRange(const int start1, const int end1, const int start2, const int end2)
{
const bool outOfRange = IndexOutOfRange(start1, end1);
return IndexOutOfRange(start2, end2) || outOfRange;
}
/****************************************************/
/****************************************************/
@ -348,6 +372,11 @@ FNativePalette *FRemapTable::GetNative()
void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
{
if (IndexOutOfRange(start, end, pal1, pal2))
{
return;
}
double palcol, palstep;
if (start > end)
@ -368,7 +397,7 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
palstep = (pal2 - palcol) / (end - start);
for (int i = start; i <= end; palcol += palstep, ++i)
{
int j = GPalette.Remap[i], k = GPalette.Remap[int(palcol)];
int j = GPalette.Remap[i], k = GPalette.Remap[int(round(palcol))];
Remap[j] = k;
Palette[j] = GPalette.BaseColors[k];
Palette[j].a = j == 0 ? 0 : 255;
@ -383,6 +412,11 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2)
{
if (IndexOutOfRange(start, end))
{
return;
}
double r1 = _r1;
double g1 = _g1;
double b1 = _b1;
@ -442,6 +476,11 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in
void FRemapTable::AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2)
{
if (IndexOutOfRange(start, end))
{
return;
}
r1 = clamp(r1, 0.0, 2.0);
g1 = clamp(g1, 0.0, 2.0);
b1 = clamp(b1, 0.0, 2.0);
@ -490,6 +529,11 @@ void FRemapTable::AddDesaturation(int start, int end, double r1, double g1, doub
void FRemapTable::AddColourisation(int start, int end, int r, int g, int b)
{
if (IndexOutOfRange(start, end))
{
return;
}
for (int i = start; i < end; ++i)
{
double br = GPalette.BaseColors[i].r;
@ -515,6 +559,11 @@ void FRemapTable::AddColourisation(int start, int end, int r, int g, int b)
void FRemapTable::AddTint(int start, int end, int r, int g, int b, int amount)
{
if (IndexOutOfRange(start, end))
{
return;
}
for (int i = start; i < end; ++i)
{
float br = GPalette.BaseColors[i].r;

View file

@ -394,7 +394,7 @@ public:
}
// Moves a plane up/down by hdiff units
double GetChangedHeight(double hdiff)
double GetChangedHeight(double hdiff) const
{
return D - hdiff * normal.Z;
}
@ -1139,7 +1139,15 @@ struct side_t
double yScale;
TObjPtr<DInterpolation*> interpolation;
FTextureID texture;
//int Light;
void InitFrom(const part &other)
{
if (texture.isNull()) texture = other.texture;
if (0.0 == xOffset) xOffset = other.xOffset;
if (0.0 == yOffset) yOffset = other.yOffset;
if (1.0 == xScale && 0.0 != other.xScale) xScale = other.xScale;
if (1.0 == yScale && 0.0 != other.yScale) yScale = other.yScale;
}
};
sector_t* sector; // Sector the SideDef is facing.

View file

@ -8091,7 +8091,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
{
bool error;
PFunction *afd = FindClassMemberFunction(ccls, ctx.Class, MethodName, ScriptPosition, &error);
if ((afd->Variants[0].Flags & VARF_Method) && (afd->Variants[0].Flags & VARF_Virtual))
if ((nullptr != afd) && (afd->Variants[0].Flags & VARF_Method) && (afd->Variants[0].Flags & VARF_Virtual))
{
staticonly = false;
novirtual = true;
@ -8935,7 +8935,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
else
{
bool writable;
ArgList[i] = ArgList[i]->Resolve(ctx); // nust be resolved before the address is requested.
ArgList[i] = ArgList[i]->Resolve(ctx); // must be resolved before the address is requested.
if (ArgList[i] != nullptr && ArgList[i]->ValueType != TypeNullPtr)
{
if (type == ArgList[i]->ValueType && type->isRealPointer() && type->toPointer()->PointedType->isStruct())

View file

@ -51,6 +51,7 @@ typedef TArray<uint32_t> FDynArray_I32;
typedef TArray<float> FDynArray_F32;
typedef TArray<double> FDynArray_F64;
typedef TArray<void*> FDynArray_Ptr;
typedef TArray<DObject*> FDynArray_Obj;
typedef TArray<FString> FDynArray_String;
//-----------------------------------------------------
@ -672,6 +673,112 @@ DEFINE_ACTION_FUNCTION(FDynArray_Ptr, Clear)
}
//-----------------------------------------------------
//
// Object array
//
//-----------------------------------------------------
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Copy)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_POINTER(other, FDynArray_Obj);
*self = *other;
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Move)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_POINTER(other, FDynArray_Obj);
*self = std::move(*other);
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Find)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_OBJECT(val, DObject);
ACTION_RETURN_INT(self->Find(val));
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Push)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_OBJECT(val, DObject);
GC::WriteBarrier(val);
ACTION_RETURN_INT(self->Push(val));
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Pop)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
ACTION_RETURN_BOOL(self->Pop());
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Delete)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_INT(index);
PARAM_INT_DEF(count);
self->Delete(index, count);
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Insert)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_INT(index);
PARAM_OBJECT(val, DObject);
GC::WriteBarrier(val);
self->Insert(index, val);
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, ShrinkToFit)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
self->ShrinkToFit();
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Grow)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_INT(count);
self->Grow(count);
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Resize)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_INT(count);
self->Resize(count);
return 0;
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Reserve)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
PARAM_INT(count);
ACTION_RETURN_INT(self->Reserve(count));
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Max)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
ACTION_RETURN_INT(self->Max());
}
DEFINE_ACTION_FUNCTION(FDynArray_Obj, Clear)
{
PARAM_SELF_STRUCT_PROLOGUE(FDynArray_Obj);
self->Clear();
return 0;
}
//-----------------------------------------------------
//
// String array
@ -781,4 +888,5 @@ DEFINE_FIELD_NAMED_X(DynArray_I32, FArray, Count, Size)
DEFINE_FIELD_NAMED_X(DynArray_F32, FArray, Count, Size)
DEFINE_FIELD_NAMED_X(DynArray_F64, FArray, Count, Size)
DEFINE_FIELD_NAMED_X(DynArray_Ptr, FArray, Count, Size)
DEFINE_FIELD_NAMED_X(DynArray_Obj, FArray, Count, Size)
DEFINE_FIELD_NAMED_X(DynArray_String, FArray, Count, Size)

View file

@ -2050,7 +2050,10 @@ PDynArray *NewDynArray(PType *type)
break;
case REGT_POINTER:
backingname = "DynArray_Ptr";
if (type->isObjectPointer())
backingname = "DynArray_Obj";
else
backingname = "DynArray_Ptr";
break;
default:

View file

@ -1627,7 +1627,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
}
else
{
Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName());
Error(field, "%s: Base type for dynamic array types must be integral, but got %s", name.GetChars(), ftype->DescriptiveName());
}
}
else

View file

@ -708,7 +708,7 @@ ADD_STAT(music)
//
//==========================================================================
CCMD (writeopl)
UNSAFE_CCMD (writeopl)
{
if (argv.argc() == 2)
{
@ -746,7 +746,7 @@ CCMD (writeopl)
//
//==========================================================================
CCMD (writewave)
UNSAFE_CCMD (writewave)
{
if (argv.argc() >= 2 && argv.argc() <= 3)
{
@ -784,7 +784,7 @@ CCMD (writewave)
//
//==========================================================================
CCMD (writemidi)
UNSAFE_CCMD (writemidi)
{
if (argv.argc() != 2)
{

View file

@ -649,18 +649,11 @@ void CALLBACK WinMIDIDevice::CallbackFunc(HMIDIOUT hOut, UINT uMsg, DWORD_PTR dw
// are done by sending MIDI channel volume messages to the stream, not
// through midiOutSetVolume().)
//
// This is using VC++'s __uuidof extension instead of the the CLSID_ and
// IID_ definitions because I couldn't figure out why it wasn't finding them
// when linking, and __uuidof circumvents that problem. I'd also be
// surprised if w32api includes any WASAPI stuff any time soon, so it's no
// big loss making this VC++-specific for the time being
//
//==========================================================================
static bool IgnoreMIDIVolume(UINT id)
{
MIDIOUTCAPS caps;
bool mustcheck = false;
if (MMSYSERR_NOERROR == midiOutGetDevCaps(id, &caps, sizeof(caps)))
{
@ -668,7 +661,7 @@ static bool IgnoreMIDIVolume(UINT id)
{
// We cannot determine what this is so we have to assume the worst, as the default
// devive's volume control is irreparably broken.
mustcheck = true;
return true;
}
// The Microsoft GS Wavetable Synth advertises itself as MIDIDEV_SWSYNTH with a VOLUME control.
// If the one we're using doesn't match that, we don't need to bother checking the name.
@ -676,28 +669,8 @@ static bool IgnoreMIDIVolume(UINT id)
{
if (strncmp(caps.szPname, "Microsoft GS", 12) == 0)
{
mustcheck = true;
}
}
if (mustcheck)
{
#ifndef __GNUC__
IMMDeviceEnumerator *enumerator;
// Now try to create an IMMDeviceEnumerator interface. If it succeeds,
// we know we're using the new audio stack introduced with Vista and
// should ignore this MIDI device's volume control.
if (SUCCEEDED(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), (void**)&enumerator))
&& enumerator != nullptr)
{
enumerator->Release();
return true;
}
#else
// assume the worst and consider volume control broken.
return true;
#endif
}
}
return false;

View file

@ -592,6 +592,12 @@ CCMD(printstats)
CCMD(finishgame)
{
bool gamestatecheck = gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE;
if (!gamestatecheck)
{
Printf("Cannot use 'finishgame' while not in a game!\n");
return;
}
// This CCMD simulates an end-of-game action and exists to end mods that never exit their last level.
Net_WriteByte(DEM_FINISHGAME);
}

View file

@ -225,7 +225,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
}
screen->GetFlashedPalette (palette);
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch());
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch(), Gamma);
pic->Unlock ();
delete pic;
}
@ -399,4 +399,4 @@ uint32_t FSoftwareRenderer::GetCaps()
FlagSet |= RFF_COLORMAP;
return (uint32_t)FlagSet;
}
}

View file

@ -77,7 +77,15 @@ namespace swrenderer
double xscale, yscale;
int x1, x2, y1, y2;
sector_t* heightsec = NULL;
double timefrac = r_viewpoint.TicFrac;
if (paused || bglobal.freeze)
timefrac = 0.;
double ippx = particle->Pos.X + particle->Vel.X * timefrac;
double ippy = particle->Pos.Y + particle->Vel.Y * timefrac;
double ippz = particle->Pos.Z + particle->Vel.Z * timefrac;
RenderPortal *renderportal = thread->Portal.get();
// [ZZ] Particle not visible through the portal plane
@ -85,8 +93,8 @@ namespace swrenderer
return;
// transform the origin point
tr_x = particle->Pos.X - thread->Viewport->viewpoint.Pos.X;
tr_y = particle->Pos.Y - thread->Viewport->viewpoint.Pos.Y;
tr_x = ippx - thread->Viewport->viewpoint.Pos.X;
tr_y = ippy - thread->Viewport->viewpoint.Pos.Y;
tz = tr_x * thread->Viewport->viewpoint.TanCos + tr_y * thread->Viewport->viewpoint.TanSin;
@ -121,7 +129,7 @@ namespace swrenderer
auto viewport = thread->Viewport.get();
yscale = xscale; // YaspectMul is not needed for particles as they should always be square
ty = (particle->Pos.Z - viewport->viewpoint.Pos.Z) * thread->Viewport->YaspectMul;
ty = (ippz - viewport->viewpoint.Pos.Z) * thread->Viewport->YaspectMul;
y1 = xs_RoundToInt(viewport->CenterY - (ty + psize) * yscale);
y2 = xs_RoundToInt(viewport->CenterY - (ty - psize) * yscale);
@ -184,9 +192,9 @@ namespace swrenderer
map = GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true);
}
if (botpic != skyflatnum && particle->Pos.Z < botplane->ZatPoint(particle->Pos))
if (botpic != skyflatnum && ippz < botplane->ZatPoint(particle->Pos))
return;
if (toppic != skyflatnum && particle->Pos.Z >= topplane->ZatPoint(particle->Pos))
if (toppic != skyflatnum && ippz >= topplane->ZatPoint(particle->Pos))
return;
// store information in a vissprite
@ -199,7 +207,7 @@ namespace swrenderer
// vis->yscale *= InvZtoScale;
vis->depth = (float)tz;
vis->idepth = float(1 / tz);
vis->gpos = { (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z };
vis->gpos = { (float)ippx, (float)ippy, (float)ippz };
vis->y1 = y1;
vis->y2 = y2;
vis->x1 = x1;

View file

@ -175,15 +175,14 @@ protected:
struct TexPart
{
int16_t OriginX, OriginY;
uint8_t Rotate;
uint8_t op;
FRemapTable *Translation;
PalEntry Blend;
FTexture *Texture;
blend_t Alpha;
TexPart();
FRemapTable *Translation = nullptr;
FTexture *Texture = nullptr;
PalEntry Blend = 0;
blend_t Alpha = FRACUNIT;
int16_t OriginX = 0;
int16_t OriginY = 0;
uint8_t Rotate = 0;
uint8_t op = OP_COPY;
};
struct TexInit
@ -797,23 +796,6 @@ FTexture *FMultiPatchTexture::GetRawTexture()
return NumParts == 1 ? Parts->Texture : this;
}
//==========================================================================
//
// FMultiPatchTexture :: TexPart :: TexPart
//
//==========================================================================
FMultiPatchTexture::TexPart::TexPart()
{
OriginX = OriginY = 0;
Rotate = 0;
Texture = NULL;
Translation = NULL;
Blend = 0;
Alpha = FRACUNIT;
op = OP_COPY;
}
//==========================================================================
//
// FTextureManager :: AddTexturesLump
@ -1369,7 +1351,7 @@ void FMultiPatchTexture::ResolvePatches()
{
if (Parts[i].Texture == nullptr)
{
memcpy(&Parts[i], &Parts[i + 1], NumParts - i - 1);
memcpy(&Parts[i], &Parts[i + 1], (NumParts - i - 1) * sizeof(TexPart));
i--;
NumParts--;
}

View file

@ -332,6 +332,8 @@ static int ParseMapEntry(FScanner &scanner, UMapEntry *val)
int ParseUMapInfo(int lumpnum)
{
P_LoadTranslator(gameinfo.translator);
FScanner scanner(lumpnum);
unsigned int i;

View file

@ -959,6 +959,19 @@ void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t re
#endif
}
DEFINE_ACTION_FUNCTION(_Screen, DrawLine)
{
PARAM_PROLOGUE;
PARAM_INT(x0);
PARAM_INT(y0);
PARAM_INT(x1);
PARAM_INT(y1);
PARAM_INT(color);
if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
screen->DrawLine(x0, y0, x1, y1, -1, color);
return 0;
}
void DCanvas::DrawPixel(int x, int y, int palColor, uint32_t realcolor)
{
#ifndef NO_SWRENDER

View file

@ -329,12 +329,13 @@ void DCanvas::Dim (PalEntry color)
//
//==========================================================================
void DCanvas::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void DCanvas::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
Lock(true);
buffer = GetBuffer();
pitch = IsBgra() ? GetPitch() * 4 : GetPitch();
color_type = IsBgra() ? SS_BGRA : SS_PAL;
gamma = Gamma;
}
//==========================================================================

View file

@ -256,7 +256,7 @@ public:
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
// points to the last row in the buffer, which will be the first row output.
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma);
// Releases the screenshot buffer.
virtual void ReleaseScreenshotBuffer();

View file

@ -1755,13 +1755,13 @@ void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2)
//
//==========================================================================
void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
D3DLOCKED_RECT lrect;
if (!Accel2D)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
return;
}
buffer = NULL;
@ -1784,6 +1784,7 @@ void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &col
buffer = (const uint8_t *)lrect.pBits;
pitch = lrect.Pitch;
color_type = SS_BGRA;
gamma = Gamma;
}
}
}

View file

@ -53,6 +53,7 @@ EXTERN_CVAR (Bool, fullscreen)
EXTERN_CVAR (Bool, swtruecolor)
EXTERN_CVAR (Float, vid_winscale)
EXTERN_CVAR (Bool, vid_forceddraw)
EXTERN_CVAR (Bool, win_borderless)
CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -413,6 +414,13 @@ void I_RestoreWindowedPos ()
}
MoveWindow (Window, winx, winy, winw, winh, TRUE);
if (win_borderless && !Args->CheckParm("-0"))
{
LONG lStyle = GetWindowLong(Window, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
SetWindowLong(Window, GWL_STYLE, lStyle);
SetWindowPos(Window, HWND_TOP, 0, 0, scrwidth, scrheight, 0);
}
if (win_maximized && !Args->CheckParm("-0"))
ShowWindow(Window, SW_MAXIMIZE);
}
@ -432,6 +440,18 @@ CUSTOM_CVAR(Bool, swtruecolor, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITC
}
}
CUSTOM_CVAR(Bool, win_borderless, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
// Just reinit the window. Saves a lot of trouble.
if (!fullscreen)
{
NewWidth = screen->VideoWidth;
NewHeight = screen->VideoHeight;
NewBits = DisplayBits;
setmodeneeded = true;
}
}
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
NewWidth = screen->VideoWidth;

View file

@ -160,6 +160,7 @@ BOOL AppActive = TRUE;
int SessionState = 0;
int BlockMouseMove;
CVAR (Bool, i_soundinbackground, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, norawinput, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
@ -551,7 +552,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
}
S_SetSoundPaused (wParam);
S_SetSoundPaused ((!!i_soundinbackground) || wParam);
break;
case WM_WTSSESSION_CHANGE:

View file

@ -1130,7 +1130,7 @@ void Win32GLFrameBuffer::InitializeState()
bool Win32GLFrameBuffer::CanUpdate()
{
if (!AppActive) return false;
if (!AppActive && IsFullscreen()) return false;
return true;
}

View file

@ -124,7 +124,7 @@ public:
bool PaintToWindow ();
void SetVSync (bool vsync);
void NewRefreshRate();
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
void ReleaseScreenshotBuffer();
void SetBlendingRect (int x1, int y1, int x2, int y2);
bool Begin2D (bool copy3d);

View file

@ -833,3 +833,14 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6
{
polyobj
}
3D8ED20BF5CAAE6D6AE0E10999C75084 // hgarden.pk3 map01
{
// spawn trees on top of arches
setthingz 399 168
setthingz 400 168
setthingz 401 168
setthingz 402 168
setthingz 403 168
setthingz 404 168
}

View file

@ -0,0 +1,9 @@
DBIGFONT, SBIGFONT
Taken from sp_usimp.zip (Ultimate Simplicity) by Agent Spork
sp_usimp.txt contains the following permissions:
Authors MAY use the contents of this file as a base for modification or
reuse. Permissions have been obtained from original authors for any of
their resources modified or included in this file.

Binary file not shown.

View file

@ -1778,7 +1778,7 @@ MOUSEMNU_LOOKSTRAFE = "Lookstrafe";
// Joystick Menu
JOYMNU_CONFIG = "CONFIGURE CONTROLLER";
JOYMNU_TITLE = "CONFIGURE CONTROLLER";
JOYMNU_OPTIONS = "CONTROLLER OPTIONS";
JOYMNU_NOMENU = "Block controller input in menu";
@ -1796,6 +1796,9 @@ PLYRMNU_PLAYERGENDER = "Gender";
PLYRMNU_AUTOAIM = "Autoaim";
PLYRMNU_SWITCHONPICKUP = "Switch on pickup";
PLYRMNU_ALWAYSRUN = "Always Run";
PLYRMNU_PRESSSPACE = "PRESS \cjSPACE";
PLYRMNU_SEEFRONT = "TO SEE FRONT";
PLYRMNU_SEEBACK = "TO SEE BACK";
// Display Options
DSPLYMNU_TITLE = "DISPLAY OPTIONS";
@ -1942,6 +1945,7 @@ AUTOMAPMNU_SHOWKEYS = "Show keys (cheat)";
AUTOMAPMNU_SHOWTRIGGERLINES = "Show trigger lines";
AUTOMAPMNU_SHOWTHINGSPRITES = "Show things as sprites";
AUTOMAPMNU_PTOVERLAY = "Overlay portals";
AUTOMAPMNU_EMPTYSPACEMARGIN = "Empty space margin";
// Automap Controls
MAPCNTRLMNU_TITLE = "CUSTOMIZE MAP CONTROLS";
@ -2129,6 +2133,7 @@ SNDMNU_SFXVOLUME = "Sounds volume";
SNDMNU_MENUVOLUME = "Menu volume";
SNDMNU_MUSICVOLUME = "Music volume";
SNDMNU_MIDIDEVICE = "MIDI device";
SNDMNU_BACKGROUND = "Sound in Background";
SNDMNU_UNDERWATERREVERB = "Underwater reverb";
SNDMNU_RANDOMIZEPITCHES = "Randomize pitches";
SNDMNU_CHANNELS = "Sound channels";
@ -2161,11 +2166,10 @@ ADVSNDMNU_FLUIDSYNTH = "FluidSynth";
ADVSNDMNU_FLUIDPATCHSET = "Patch set";
ADVSNDMNU_FLUIDGAIN = "Gain";
ADVSNDMNU_REVERB = "Reverb";
ADVSNDMNU_FLUIDVOICES = "MIDI voices";
ADVSNDMNU_CHORUS = "Chorus";
ADVSNDMNU_TIMIDITY = "Timidity++";
ADVSNDMNU_TIMIDITYEXE = "Path for executable";
ADVSNDMNU_TIMIDITYCONFIG = "Timidity config file";
ADVSNDMNU_TIMIDITYCHORUS = "Chorus";
ADVSNDMNU_TIMIDITYVOLUME = "Relative volume";
ADVSNDMNU_WILDMIDI = "WildMidi";
ADVSNDMNU_WILDMIDICONFIG = "WildMidi config file";
@ -2183,13 +2187,14 @@ MODMNU_CHIPOMATIC = "Chip-o-matic";
RNDMNU_TITLE = "CHANGE RENDERER";
RNDMNU_RENDERER = "Hardware Acceleration";
RNDMNU_TRUECOLOR = "Software Truecolor Mode";
RNDMNU_POLY = "Poly Renderer (experimental)";
RNDMNU_POLY = "Poly Renderer (experimental)";
RNDMNU_CANVAS = "Software Canvas";
// Video Options
VIDMNU_TITLE = "VIDEO MODE";
VIDMNU_FULLSCREEN = "Fullscreen";
VIDMNU_HIDPI = "Retina/HiDPI support";
VIDMNU_BRDLSS = "Borderless Windowed Mode";
VIDMNU_ASPECTRATIO = "Aspect ratio";
VIDMNU_FORCEASPECT = "Force aspect ratio";
VIDMNU_CROPASPECT = "Forced ratio style";
@ -2724,7 +2729,7 @@ GLPREFMNU_AMBLIGHT = "Ambient light level";
GLPREFMNU_RENDERQUALITY = "Rendering quality";
GLPREFMNU_MENUBLUR = "Menu Blur";
GLPREFMNU_VRMODE = "Stereo 3D VR";
GLPREFMNU_VRQUADSTEREO = "Enable Quad Stereo";
GLPREFMNU_VRQUADSTEREO = "Enable Quad Stereo (Requires Restart)";
GLPREFMNU_MULTISAMPLE = "Multisample";
GLPREFMNU_TONEMAP = "Tonemap Mode";
GLPREFMNU_BLOOM = "Bloom effect";
@ -2797,7 +2802,6 @@ OPTVAL_TRANSLUCENTFUZZ = "Translucent fuzz";
OPTVAL_NOISE = "Noise";
OPTVAL_SMOOTHNOISE = "Smooth Noise";
OPTVAL_JAGGEDFUZZ = "Jagged fuzz";
OPTVAL_NORMAL = "Normal";
OPTVAL_GREENMAGENTA = "Green/Magenta";
OPTVAL_REDCYAN = "Red/Cyan";
OPTVAL_AMBERBLUE = "Amber/Blue";

File diff suppressed because it is too large Load diff

View file

@ -608,7 +608,7 @@ OptionValue "Inversion"
OptionMenu "JoystickConfigMenu" protected
{
Title "$JOY_CONFIG"
Title "$JOYMNU_TITLE"
Class "JoystickConfigMenu"
// Will be filled in by joystick code.
}
@ -1091,6 +1091,7 @@ OptionMenu AutomapOptions protected
Option "$AUTOMAPMNU_TEXTURED", "am_textured", "OnOff"
Option "$AUTOMAPMNU_FOLLOW", "am_followplayer", "OnOff"
Option "$AUTOMAPMNU_PTOVERLAY", "am_portaloverlay", "OnOff"
Slider "$AUTOMAPMNU_EMPTYSPACEMARGIN", "am_emptyspacemargin", 0, 90, 5, 0
StaticText " "
Option "$AUTOMAPMNU_SHOWITEMS", "am_showitems", "OnOff"
Option "$AUTOMAPMNU_SHOWMONSTERS", "am_showmonsters", "OnOff"
@ -1615,6 +1616,8 @@ OptionMenu SoundOptions protected
Option "$SNDMNU_RANDOMIZEPITCHES", "snd_pitched", "OnOff"
Slider "$SNDMNU_CHANNELS", "snd_channels", 64, 256, 8, 0
StaticText " "
Option "$SNDMNU_BACKGROUND", "i_soundinbackground", "OnOff"
StaticText " "
ifoption(openal)
{
@ -1677,7 +1680,8 @@ OptionMenu AdvSoundOptions protected
SubMenu "$ADVSNDMNU_SELCONFIG", "FluidPatchsetMenu"
Slider "$ADVSNDMNU_FLUIDGAIN", "fluid_gain", 0, 10, 0.5, 1
Option "$ADVSNDMNU_REVERB", "fluid_reverb", "OnOff"
Slider "$ADVSNDMNU_FLUIDVOICES", "fluid_voices", 16, 4096, 16, 1
Option "$ADVSNDMNU_CHORUS", "fluid_chorus", "OnOff"
Slider "$ADVSNDMNU_MIDIVOICES", "fluid_voices", 16, 4096, 16, 0
// Leaving out the more advanced stuff for now.
StaticText " "
StaticText "$ADVSNDMNU_TIMIDITY", 1
@ -1689,7 +1693,7 @@ OptionMenu AdvSoundOptions protected
TextField "$ADVSNDMNU_TIMIDITYCONFIG", "timidity_config"
SubMenu "$ADVSNDMNU_SELCONFIG", "TimidityConfigMenu"
Option "$ADVSNDMNU_REVERB", "timidity_reverb", "OnOff"
Option "$ADVSNDMNU_TIMIDITYCHORUS", "timidity_chorus", "OnOff"
Option "$ADVSNDMNU_CHORUS", "timidity_chorus", "OnOff"
Slider "$ADVSNDMNU_TIMIDITYVOLUME", "timidity_mastervolume", 0, 4, 0.2, 1
StaticText " "
StaticText "$ADVSNDMNU_WILDMIDI", 1
@ -1872,10 +1876,17 @@ OptionMenu VideoModeMenu protected
Title "$VIDMNU_TITLE"
Option "$VIDMNU_FULLSCREEN", "fullscreen", "YesNo"
IfOption(Mac)
{
Option "$VIDMNU_HIDPI", "vid_hidpi", "YesNo"
}
IfOption(Windows)
{
Option "$VIDMNU_BRDLSS", "win_borderless", "YesNo"
}
Option "$VIDMNU_ASPECTRATIO", "menu_screenratios", "Ratios"
Option "$VIDMNU_FORCEASPECT", "vid_aspect", "ForceRatios"
Option "$VIDMNU_CROPASPECT", "vid_cropaspect", "CropAspect"

Binary file not shown.

View file

@ -203,6 +203,7 @@ class Actor : Thinker native
native readonly int BloodTranslation;
native int RenderHidden;
native int RenderRequired;
native readonly int FriendlySeeBlocks;
meta String Obituary; // Player was killed by this actor
meta String HitObituary; // Player was killed by this actor in melee
@ -292,6 +293,7 @@ class Actor : Thinker native
property RipLevelMax: RipLevelMax;
property RenderHidden: RenderHidden;
property RenderRequired: RenderRequired;
property FriendlySeeBlocks: FriendlySeeBlocks;
// need some definition work first
//FRenderStyle RenderStyle;
@ -372,6 +374,7 @@ class Actor : Thinker native
BurnHeight -1;
RenderHidden 0;
RenderRequired 0;
FriendlySeeBlocks 10; // 10 (blocks) * 128 (one map unit block)
}
// Functions
@ -624,6 +627,7 @@ class Actor : Thinker native
}
native bool TryMove(vector2 newpos, int dropoff, bool missilecheck = false, FCheckPosition tm = null);
native bool CheckMove(vector2 newpos, int flags = 0, FCheckPosition tm = null);
native void NewChaseDir();
native void RandomChaseDir();
native bool CheckMissileRange();
@ -1030,7 +1034,7 @@ class Actor : Thinker native
native void A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, double size = 1, double angle = 0, double xoff = 0, double yoff = 0, double zoff = 0, double velx = 0, double vely = 0, double velz = 0, double accelx = 0, double accely = 0, double accelz = 0, double startalphaf = 1, double fadestepf = -1, double sizestep = 0);
native void A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
native void A_DropInventory(class<Inventory> itemtype, int amount = -1);
native void A_SetBlend(color color1, double alpha, int tics, color color2 = 0);
native void A_SetBlend(color color1, double alpha, int tics, color color2 = 0, double alpha2 = 0.);
deprecated("2.3") native void A_ChangeFlag(string flagname, bool value);
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);
native void A_RaiseMaster(int flags = 0);

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