Merge branch 'gzdoom' into materials
22
README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Welcome to GZDoom!
|
||||
|
||||
[![Build Status](https://ci.appveyor.com/api/projects/status/github/coelckers/gzdoom?branch=master&svg=true)](https://ci.appveyor.com/project/coelckers/gzdoom) [![Build Status](https://travis-ci.org/coelckers/gzdoom.svg?branch=master)](https://travis-ci.org/coelckers/gzdoom)
|
||||
|
||||
## GZDoom is a modder-friendly OpenGL source port based on the DOOM engine
|
||||
|
||||
Copyright (c) 1998-2018 ZDoom + GZDoom teams, and contributors
|
||||
|
||||
Doom Source (c) 1997 id Software, Raven Software, and contributors
|
||||
|
||||
Please see license files for individual contributor licenses
|
||||
|
||||
Special thanks to Coraline of the 3DGE team for allowing us to use her README.md as a template for this one.
|
||||
|
||||
### Licensed under the GPL v3 (or greater)
|
||||
##### https://www.gnu.org/licenses/quick-guide-gplv3.en.html
|
||||
---
|
||||
|
||||
## How to build GZDoom
|
||||
|
||||
To build GZDoom, please see the [wiki](https://zdoom.org/wiki/) and see the "Programmer's Corner" on the bottom-right corner of the page to build for your platform.
|
||||
|
|
@ -283,6 +283,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
|
||||
For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it
|
||||
will be used as the name of the script to execute, and arg0 will be ignored.
|
||||
On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color.
|
||||
}
|
||||
|
||||
|
||||
|
@ -426,6 +427,9 @@ floor_reflect and ceiling_reflect.
|
|||
1.28 28.01.2017
|
||||
sector material colors.
|
||||
|
||||
1.29 04.02.2018
|
||||
arg0str in dynamic lights.
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
||||
|
|
|
@ -511,7 +511,7 @@ set( PLAT_SDL_SOURCES
|
|||
posix/sdl/st_start.cpp )
|
||||
set( PLAT_UNIX_SOURCES
|
||||
posix/unix/i_specialpaths.cpp
|
||||
posix/unix/iwadpicker_gtk.cpp )
|
||||
posix/unix/gtk_dialogs.cpp )
|
||||
set( PLAT_OSX_SOURCES
|
||||
posix/osx/iwadpicker_cocoa.mm
|
||||
posix/osx/i_specialpaths.mm
|
||||
|
|
|
@ -681,7 +681,7 @@ UNSAFE_CCMD (crashout)
|
|||
#endif
|
||||
|
||||
|
||||
CCMD (dir)
|
||||
UNSAFE_CCMD (dir)
|
||||
{
|
||||
FString dir, path;
|
||||
char curdir[256];
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "colormatcher.h"
|
||||
#include "menu/menu.h"
|
||||
#include "vm.h"
|
||||
#include "v_text.h"
|
||||
|
||||
struct FLatchedValue
|
||||
{
|
||||
|
@ -1706,6 +1707,16 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter)
|
|||
|
||||
EXTERN_CVAR(Bool, sv_cheats);
|
||||
|
||||
static bool IsUnsafe(const FBaseCVar *const var)
|
||||
{
|
||||
const bool unsafe = UnsafeExecutionContext && !(var->GetFlags() & CVAR_MOD);
|
||||
if (unsafe)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Cannot set console variable" TEXTCOLOR_GOLD " %s " TEXTCOLOR_RED "from unsafe command\n", var->GetName());
|
||||
}
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
void FBaseCVar::CmdSet (const char *newval)
|
||||
{
|
||||
if ((GetFlags() & CVAR_CHEAT) && !sv_cheats)
|
||||
|
@ -1713,6 +1724,10 @@ void FBaseCVar::CmdSet (const char *newval)
|
|||
Printf("sv_cheats must be true to set this console variable.\n");
|
||||
return;
|
||||
}
|
||||
else if (IsUnsafe(this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UCVarValue val;
|
||||
|
||||
|
@ -1799,6 +1814,11 @@ CCMD (toggle)
|
|||
{
|
||||
if ( (var = FindCVar (argv[1], &prev)) )
|
||||
{
|
||||
if (IsUnsafe(var))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
val = var->GetGenericRep (CVAR_Bool);
|
||||
val.Bool = !val.Bool;
|
||||
var->SetGenericRep (val, CVAR_Bool);
|
||||
|
|
|
@ -127,8 +127,24 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
|||
Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp,
|
||||
Button_AM_ZoomIn, Button_AM_ZoomOut;
|
||||
|
||||
bool ParsingKeyConf;
|
||||
static bool UnsafeExecutionContext;
|
||||
bool ParsingKeyConf, UnsafeExecutionContext;
|
||||
|
||||
class UnsafeExecutionScope
|
||||
{
|
||||
const bool wasEnabled;
|
||||
|
||||
public:
|
||||
explicit UnsafeExecutionScope(const bool enable = true)
|
||||
: wasEnabled(UnsafeExecutionContext)
|
||||
{
|
||||
UnsafeExecutionContext = enable;
|
||||
}
|
||||
|
||||
~UnsafeExecutionScope()
|
||||
{
|
||||
UnsafeExecutionContext = wasEnabled;
|
||||
}
|
||||
};
|
||||
|
||||
// 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
|
||||
|
@ -227,10 +243,8 @@ void DWaitingCommand::Tick ()
|
|||
{
|
||||
if (--TicsLeft == 0)
|
||||
{
|
||||
const bool wasUnsafe = UnsafeExecutionContext;
|
||||
UnsafeExecutionContext = IsUnsafe;
|
||||
UnsafeExecutionScope scope;
|
||||
AddCommandString (Command);
|
||||
UnsafeExecutionContext = wasUnsafe;
|
||||
Destroy ();
|
||||
}
|
||||
}
|
||||
|
@ -658,12 +672,6 @@ 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
|
||||
|
@ -684,9 +692,9 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
|
|||
if (CurrentMenu == nullptr) return 0;
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_STRING(cmd);
|
||||
UnsafeExecutionContext = true;
|
||||
PARAM_BOOL(unsafe);
|
||||
UnsafeExecutionScope scope(unsafe);
|
||||
C_DoCommand(cmd);
|
||||
UnsafeExecutionContext = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1515,9 +1523,8 @@ void FConsoleAlias::SafeDelete ()
|
|||
|
||||
void FUnsafeConsoleAlias::Run (FCommandLine &args, APlayerPawn *instigator, int key)
|
||||
{
|
||||
UnsafeExecutionContext = true;
|
||||
UnsafeExecutionScope scope;
|
||||
FConsoleAlias::Run(args, instigator, key);
|
||||
UnsafeExecutionContext = false;
|
||||
}
|
||||
|
||||
void FExecList::AddCommand(const char *cmd, const char *file)
|
||||
|
|
|
@ -200,7 +200,7 @@ extern FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
|
|||
Button_User1, Button_User2, Button_User3, Button_User4,
|
||||
Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp,
|
||||
Button_AM_ZoomIn, Button_AM_ZoomOut;
|
||||
extern bool ParsingKeyConf;
|
||||
extern bool ParsingKeyConf, UnsafeExecutionContext;
|
||||
|
||||
void ResetButtonTriggers (); // Call ResetTriggers for all buttons
|
||||
void ResetButtonStates (); // Same as above, but also clear bDown
|
||||
|
|
|
@ -280,7 +280,7 @@ void PClass::StaticShutdown ()
|
|||
|
||||
// This must be done in two steps because the native classes are not ordered by inheritance,
|
||||
// so all meta data must be gone before deleting the actual class objects.
|
||||
for (auto cls : AllClasses) cls->DestroyMeta(cls->Meta);
|
||||
for (auto cls : AllClasses) if (cls->Meta != nullptr) cls->DestroyMeta(cls->Meta);
|
||||
for (auto cls : AllClasses) delete cls;
|
||||
// Unless something went wrong, anything left here should be class and type objects only, which do not own any scripts.
|
||||
bShutdown = true;
|
||||
|
|
|
@ -2599,7 +2599,7 @@ void G_DeferedPlayDemo (const char *name)
|
|||
gameaction = (gameaction == ga_loadgame) ? ga_loadgameplaydemo : ga_playdemo;
|
||||
}
|
||||
|
||||
CCMD (playdemo)
|
||||
UNSAFE_CCMD (playdemo)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
|
|
|
@ -220,7 +220,21 @@ void AWeapon::MarkPrecacheSounds() const
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool AWeapon::CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo, int ammocount)
|
||||
bool AWeapon::CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo, int ammocount)
|
||||
{
|
||||
IFVIRTUAL(AWeapon, CheckAmmo)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this, fireMode, autoSwitch, requireAmmo, ammocount };
|
||||
VMReturn ret;
|
||||
int retval;
|
||||
ret.IntAt(&retval);
|
||||
VMCall(func, params, 5, &ret, 1);
|
||||
return !!retval;
|
||||
}
|
||||
return CheckAmmo(fireMode, autoSwitch, requireAmmo, ammocount);
|
||||
}
|
||||
|
||||
bool AWeapon::DoCheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo, int ammocount)
|
||||
{
|
||||
int altFire;
|
||||
int count1, count2;
|
||||
|
@ -293,7 +307,7 @@ DEFINE_ACTION_FUNCTION(AWeapon, CheckAmmo)
|
|||
PARAM_BOOL(autoswitch);
|
||||
PARAM_BOOL_DEF(require);
|
||||
PARAM_INT_DEF(ammocnt);
|
||||
ACTION_RETURN_BOOL(self->CheckAmmo(mode, autoswitch, require, ammocnt));
|
||||
ACTION_RETURN_BOOL(self->DoCheckAmmo(mode, autoswitch, require, ammocnt));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -306,7 +320,21 @@ DEFINE_ACTION_FUNCTION(AWeapon, CheckAmmo)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse)
|
||||
bool AWeapon::DepleteAmmo(bool altFire, bool checkEnough, int ammouse)
|
||||
{
|
||||
IFVIRTUAL(AWeapon, DepleteAmmo)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this, altFire, checkEnough, ammouse };
|
||||
VMReturn ret;
|
||||
int retval;
|
||||
ret.IntAt(&retval);
|
||||
VMCall(func, params, 4, &ret, 1);
|
||||
return !!retval;
|
||||
}
|
||||
return DoDepleteAmmo(altFire, checkEnough, ammouse);
|
||||
}
|
||||
|
||||
bool AWeapon::DoDepleteAmmo (bool altFire, bool checkEnough, int ammouse)
|
||||
{
|
||||
if (!((dmflags & DF_INFINITE_AMMO) || (Owner->FindInventory (PClass::FindActor(NAME_PowerInfiniteAmmo), true) != nullptr)))
|
||||
{
|
||||
|
@ -357,7 +385,7 @@ DEFINE_ACTION_FUNCTION(AWeapon, DepleteAmmo)
|
|||
PARAM_BOOL(altfire);
|
||||
PARAM_BOOL_DEF(checkenough);
|
||||
PARAM_INT_DEF(ammouse);
|
||||
ACTION_RETURN_BOOL(self->DepleteAmmo(altfire, checkenough, ammouse));
|
||||
ACTION_RETURN_BOOL(self->DoDepleteAmmo(altfire, checkenough, ammouse));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -142,7 +142,9 @@ public:
|
|||
EitherFire
|
||||
};
|
||||
bool CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo=false, int ammocount = -1);
|
||||
bool DoCheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo, int ammocount);
|
||||
bool DepleteAmmo (bool altFire, bool checkEnough=true, int ammouse = -1);
|
||||
bool DoDepleteAmmo(bool altFire, bool checkEnough, int ammouse);
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -648,7 +648,8 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
|
||||
// If this is co-op, respawn any dead players now so they can
|
||||
// keep their inventory on the next map.
|
||||
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn) && !deathmatch && player->playerstate == PST_DEAD)
|
||||
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn || !!G_SkillProperty(SKILLP_PlayerRespawn))
|
||||
&& !deathmatch && player->playerstate == PST_DEAD)
|
||||
{
|
||||
// Copied from the end of P_DeathThink [[
|
||||
player->cls = NULL; // Force a new class if the player is using a random class
|
||||
|
@ -2028,6 +2029,10 @@ DEFINE_FIELD(FLevelLocals, F1Pic)
|
|||
DEFINE_FIELD(FLevelLocals, maptype)
|
||||
DEFINE_FIELD(FLevelLocals, Music)
|
||||
DEFINE_FIELD(FLevelLocals, musicorder)
|
||||
DEFINE_FIELD(FLevelLocals, skytexture1)
|
||||
DEFINE_FIELD(FLevelLocals, skytexture2)
|
||||
DEFINE_FIELD(FLevelLocals, skyspeed1)
|
||||
DEFINE_FIELD(FLevelLocals, skyspeed2)
|
||||
DEFINE_FIELD(FLevelLocals, total_secrets)
|
||||
DEFINE_FIELD(FLevelLocals, found_secrets)
|
||||
DEFINE_FIELD(FLevelLocals, total_items)
|
||||
|
@ -2093,3 +2098,19 @@ CCMD(skyfog)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZScript counterpart to ACS ChangeSky, uses TextureIDs
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeSky)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(sky1);
|
||||
PARAM_INT(sky2);
|
||||
sky1texture = self->skytexture1 = FSetTextureID(sky1);
|
||||
sky2texture = self->skytexture2 = FSetTextureID(sky2);
|
||||
R_InitSkyMap();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
// Note: This should be replaced with proper shader based lighting.
|
||||
double x, y;
|
||||
decal->GetXY(seg->sidedef, x, y);
|
||||
gl_SetDynSpriteLight(NULL, x, y, zpos, sub);
|
||||
gl_SetDynSpriteLight(nullptr, x, y, zpos - decalheight * 0.5f, sub);
|
||||
}
|
||||
|
||||
// alpha color only has an effect when using an alpha texture.
|
||||
|
|
|
@ -842,7 +842,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
|
|||
stereo3dMode.SetUp();
|
||||
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
|
||||
{
|
||||
if (eye_ix > 0)
|
||||
if (eye_ix > 0 && camera->player)
|
||||
SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes
|
||||
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
|
||||
eye->SetUp();
|
||||
|
|
|
@ -987,9 +987,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
RenderStyle.CheckFuzz();
|
||||
if (RenderStyle.BlendOp == STYLEOP_Fuzz)
|
||||
{
|
||||
if (gl_fuzztype != 0 && !gl.legacyMode)
|
||||
if (gl_fuzztype != 0 && !gl.legacyMode && !(RenderStyle.Flags & STYLEF_InvertSource))
|
||||
{
|
||||
// Todo: implement shader selection here
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
OverrideShader = SHADER_NoTexture + gl_fuzztype;
|
||||
trans = 0.99f; // trans may not be 1 here
|
||||
|
|
|
@ -74,7 +74,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
|||
while (node)
|
||||
{
|
||||
light=node->lightsource;
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self || !self) && !(light->lightflags&LF_DONTLIGHTACTORS))
|
||||
{
|
||||
float dist;
|
||||
FVector3 L;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "gl/stereo3d/gl_sidebyside3d.h"
|
||||
#include "gl/stereo3d/gl_interleaved3d.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "version.h"
|
||||
|
||||
// Set up 3D-specific console variables:
|
||||
CVAR(Int, vr_mode, 0, CVAR_GLOBALCONFIG)
|
||||
|
@ -42,7 +43,10 @@ CVAR(Bool, vr_swap_eyes, false, CVAR_GLOBALCONFIG)
|
|||
// For broadest GL compatibility, require user to explicitly enable quad-buffered stereo mode.
|
||||
// Setting vr_enable_quadbuffered_stereo does not automatically invoke quad-buffered stereo,
|
||||
// but makes it possible for subsequent "vr_mode 7" to invoke quad-buffered stereo
|
||||
CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
Printf("You must restart " GAMENAME " to switch quad stereo mode\n");
|
||||
}
|
||||
|
||||
// intraocular distance in meters
|
||||
CVAR(Float, vr_ipd, 0.062f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // METERS
|
||||
|
|
|
@ -673,7 +673,7 @@ void M_ScreenShot (const char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD (screenshot)
|
||||
UNSAFE_CCMD (screenshot)
|
||||
{
|
||||
if (argv.argc() == 1)
|
||||
G_ScreenShot (NULL);
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "vm.h"
|
||||
#include "events.h"
|
||||
#include "gl/renderer/gl_renderer.h" // for menu blur
|
||||
#include "scripting/types.h"
|
||||
|
||||
//
|
||||
// Todo: Move these elsewhere
|
||||
|
@ -1180,6 +1181,8 @@ DMenuItemBase * CreateOptionMenuItemCommand(const char *label, FName cmd, bool c
|
|||
VMValue params[] = { p, &namestr, cmd.GetIndex(), centered };
|
||||
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
|
||||
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
|
||||
auto unsafe = dyn_cast<PField>(c->FindSymbol("mUnsafe", false));
|
||||
unsafe->Type->SetValue(reinterpret_cast<uint8_t*>(p) + unsafe->Offset, 0);
|
||||
return (DMenuItemBase*)p;
|
||||
}
|
||||
|
||||
|
|
|
@ -835,12 +835,12 @@ inline int uallong(const int &foo)
|
|||
//============================================================================
|
||||
|
||||
// ACS variables with world scope
|
||||
int32_t ACS_WorldVars[NUM_WORLDVARS];
|
||||
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
|
||||
static BoundsCheckingArray<int32_t, NUM_WORLDVARS> ACS_WorldVars;
|
||||
static BoundsCheckingArray<FWorldGlobalArray, NUM_WORLDVARS> ACS_WorldArrays;
|
||||
|
||||
// ACS variables with global scope
|
||||
int32_t ACS_GlobalVars[NUM_GLOBALVARS];
|
||||
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
|
||||
BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
|
||||
BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -851,21 +851,7 @@ 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];
|
||||
};
|
||||
using FACSStackMemory = BoundsCheckingArray<int32_t, STACK_SIZE>;
|
||||
|
||||
struct FACSStack
|
||||
{
|
||||
|
@ -1470,10 +1456,10 @@ void ACSStringPool::UnlockForLevel(int lnum)
|
|||
|
||||
void P_MarkWorldVarStrings()
|
||||
{
|
||||
GlobalACSStrings.MarkStringArray(ACS_WorldVars, countof(ACS_WorldVars));
|
||||
for (size_t i = 0; i < countof(ACS_WorldArrays); ++i)
|
||||
GlobalACSStrings.MarkStringArray(ACS_WorldVars.Pointer(), ACS_WorldVars.Size());
|
||||
for (size_t i = 0; i < ACS_WorldArrays.Size(); ++i)
|
||||
{
|
||||
GlobalACSStrings.MarkStringMap(ACS_WorldArrays[i]);
|
||||
GlobalACSStrings.MarkStringMap(ACS_WorldArrays.Pointer()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1485,10 +1471,10 @@ void P_MarkWorldVarStrings()
|
|||
|
||||
void P_MarkGlobalVarStrings()
|
||||
{
|
||||
GlobalACSStrings.MarkStringArray(ACS_GlobalVars, countof(ACS_GlobalVars));
|
||||
for (size_t i = 0; i < countof(ACS_GlobalArrays); ++i)
|
||||
GlobalACSStrings.MarkStringArray(ACS_GlobalVars.Pointer(), ACS_GlobalVars.Size());
|
||||
for (size_t i = 0; i < ACS_GlobalArrays.Size(); ++i)
|
||||
{
|
||||
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays[i]);
|
||||
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays.Pointer()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1571,14 +1557,14 @@ void P_ClearACSVars(bool alsoglobal)
|
|||
{
|
||||
int i;
|
||||
|
||||
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
|
||||
ACS_WorldVars.Fill(0);
|
||||
for (i = 0; i < NUM_WORLDVARS; ++i)
|
||||
{
|
||||
ACS_WorldArrays[i].Clear ();
|
||||
}
|
||||
if (alsoglobal)
|
||||
{
|
||||
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
|
||||
ACS_GlobalVars.Fill(0);
|
||||
for (i = 0; i < NUM_GLOBALVARS; ++i)
|
||||
{
|
||||
ACS_GlobalArrays[i].Clear ();
|
||||
|
@ -1726,10 +1712,10 @@ static void ReadArrayVars (FSerializer &file, FWorldGlobalArray *vars, size_t co
|
|||
|
||||
void P_ReadACSVars(FSerializer &arc)
|
||||
{
|
||||
ReadVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
|
||||
ReadVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
|
||||
ReadArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
|
||||
ReadArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
|
||||
ReadVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
|
||||
ReadVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
|
||||
ReadArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
|
||||
ReadArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
|
||||
GlobalACSStrings.ReadStrings(arc, "acsglobalstrings");
|
||||
}
|
||||
|
||||
|
@ -1741,10 +1727,10 @@ void P_ReadACSVars(FSerializer &arc)
|
|||
|
||||
void P_WriteACSVars(FSerializer &arc)
|
||||
{
|
||||
WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
|
||||
WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
|
||||
WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
|
||||
WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
|
||||
WriteVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
|
||||
WriteVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
|
||||
WriteArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
|
||||
WriteArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
|
||||
GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
|
||||
}
|
||||
|
||||
|
@ -9852,7 +9838,7 @@ scriptwait:
|
|||
if (STACK(2) != 0)
|
||||
{
|
||||
AActor *marine;
|
||||
NActorIterator iterator("ScriptedMarine", STACK(2));
|
||||
NActorIterator iterator(NAME_ScriptedMarine, STACK(2));
|
||||
|
||||
while ((marine = iterator.Next()) != NULL)
|
||||
{
|
||||
|
@ -9861,7 +9847,7 @@ scriptwait:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (activator != nullptr && activator->IsKindOf (PClass::FindClass("ScriptedMarine")))
|
||||
if (activator != nullptr && activator->IsKindOf (NAME_ScriptedMarine))
|
||||
{
|
||||
SetMarineWeapon(activator, STACK(1));
|
||||
}
|
||||
|
@ -9878,7 +9864,7 @@ scriptwait:
|
|||
if (STACK(2) != 0)
|
||||
{
|
||||
AActor *marine;
|
||||
NActorIterator iterator("ScriptedMarine", STACK(2));
|
||||
NActorIterator iterator(NAME_ScriptedMarine, STACK(2));
|
||||
|
||||
while ((marine = iterator.Next()) != NULL)
|
||||
{
|
||||
|
@ -9887,7 +9873,7 @@ scriptwait:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (activator != nullptr && activator->IsKindOf("ScriptedMarine"))
|
||||
if (activator != nullptr && activator->IsKindOf(NAME_ScriptedMarine))
|
||||
{
|
||||
SetMarineSprite(activator, type);
|
||||
}
|
||||
|
|
31
src/p_acs.h
|
@ -60,13 +60,32 @@ struct InitIntToZero
|
|||
};
|
||||
typedef TMap<int32_t, int32_t, THashTraits<int32_t>, InitIntToZero> FWorldGlobalArray;
|
||||
|
||||
// ACS variables with world scope
|
||||
extern int32_t ACS_WorldVars[NUM_WORLDVARS];
|
||||
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
|
||||
// Type of elements count is unsigned int instead of size_t to match ACSStringPool interface
|
||||
template <typename T, unsigned int N>
|
||||
struct BoundsCheckingArray
|
||||
{
|
||||
T &operator[](const unsigned int index)
|
||||
{
|
||||
if (index >= N)
|
||||
{
|
||||
I_Error("Out of bounds memory access in ACS VM");
|
||||
}
|
||||
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
T *Pointer() { return buffer; }
|
||||
unsigned int Size() const { return N; }
|
||||
|
||||
void Fill(const T &value) { std::fill(std::begin(buffer), std::end(buffer), value); }
|
||||
|
||||
private:
|
||||
T buffer[N];
|
||||
};
|
||||
|
||||
// ACS variables with global scope
|
||||
extern int32_t ACS_GlobalVars[NUM_GLOBALVARS];
|
||||
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
|
||||
extern BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
|
||||
extern BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
|
||||
|
||||
#define LIBRARYID_MASK 0xFFF00000
|
||||
#define LIBRARYID_SHIFT 20
|
||||
|
@ -359,7 +378,7 @@ public:
|
|||
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
|
||||
const char *LookupString (uint32_t index) const;
|
||||
|
||||
int32_t *MapVars[NUM_MAPVARS];
|
||||
BoundsCheckingArray<int32_t *, NUM_MAPVARS> MapVars;
|
||||
|
||||
static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0);
|
||||
static void StaticLoadDefaultModules ();
|
||||
|
|
|
@ -1216,7 +1216,7 @@ errorout:
|
|||
return false;
|
||||
}
|
||||
|
||||
CCMD(clearnodecache)
|
||||
UNSAFE_CCMD(clearnodecache)
|
||||
{
|
||||
TArray<FFileList> list;
|
||||
FString path = M_GetCachePath(false);
|
||||
|
|
|
@ -809,11 +809,13 @@ bool FMultiBlockLinesIterator::GoUp(double x, double y)
|
|||
{
|
||||
if (!cursector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling));
|
||||
portalflags = FFCF_NOFLOOR;
|
||||
return true;
|
||||
if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling)))
|
||||
{
|
||||
portalflags = FFCF_NOFLOOR;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else continueup = false;
|
||||
continueup = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -830,11 +832,13 @@ bool FMultiBlockLinesIterator::GoDown(double x, double y)
|
|||
{
|
||||
if (!cursector->PortalBlocksMovement(sector_t::floor))
|
||||
{
|
||||
startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor));
|
||||
portalflags = FFCF_NOCEILING;
|
||||
return true;
|
||||
if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor)))
|
||||
{
|
||||
portalflags = FFCF_NOCEILING;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else continuedown = false;
|
||||
continuedown = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -906,14 +910,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMultiBlockLinesIterator::startIteratorForGroup(int group)
|
||||
bool FMultiBlockLinesIterator::startIteratorForGroup(int group)
|
||||
{
|
||||
offset = Displacements.getOffset(basegroup, group);
|
||||
offset.X += checkpoint.X;
|
||||
offset.Y += checkpoint.Y;
|
||||
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset);
|
||||
// If we ended up in a different group,
|
||||
// presumably because the spot to be checked is too far outside the actual portal group,
|
||||
// the search needs to abort.
|
||||
if (cursector->PortalGroup != group) return false;
|
||||
bbox.setBox(offset.X, offset.Y, checkpoint.Z);
|
||||
blockIterator.init(bbox);
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -240,7 +240,7 @@ class FMultiBlockLinesIterator
|
|||
|
||||
bool GoUp(double x, double y);
|
||||
bool GoDown(double x, double y);
|
||||
void startIteratorForGroup(int group);
|
||||
bool startIteratorForGroup(int group);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -6101,6 +6101,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
|
|||
if (mthing->arg0str != NAME_None)
|
||||
{
|
||||
PalEntry color = V_GetColor(nullptr, mthing->arg0str);
|
||||
light->args[0] = color.r;
|
||||
light->args[1] = color.g;
|
||||
light->args[2] = color.b;
|
||||
}
|
||||
else if (light->lightflags & LF_SPOT)
|
||||
{
|
||||
|
@ -7766,7 +7769,13 @@ FState *AActor::GetRaiseState()
|
|||
void AActor::Revive()
|
||||
{
|
||||
AActor *info = GetDefault();
|
||||
FLinkContext ctx;
|
||||
|
||||
bool flagchange = (flags & (MF_NOBLOCKMAP | MF_NOSECTOR)) != (info->flags & (MF_NOBLOCKMAP | MF_NOSECTOR));
|
||||
|
||||
if (flagchange) UnlinkFromWorld(&ctx);
|
||||
flags = info->flags;
|
||||
if (flagchange) LinkToWorld(&ctx);
|
||||
flags2 = info->flags2;
|
||||
flags3 = info->flags3;
|
||||
flags4 = info->flags4;
|
||||
|
|
|
@ -1659,7 +1659,7 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
|
|||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||
PARAM_INT(pos);
|
||||
PARAM_FLOAT(o);
|
||||
self->SetXScale(pos, o);
|
||||
self->SetYScale(pos, o);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -955,8 +955,8 @@ static bool EditTraceResult (uint32_t flags, FTraceResults &res)
|
|||
// [ZZ] here go the methods for the ZScript interface
|
||||
//
|
||||
//==========================================================================
|
||||
IMPLEMENT_CLASS(DTracer, false, false)
|
||||
DEFINE_FIELD_X(Tracer, DTracer, Results)
|
||||
IMPLEMENT_CLASS(DLineTracer, false, false)
|
||||
DEFINE_FIELD(DLineTracer, Results)
|
||||
|
||||
// define TraceResults fields
|
||||
DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Sector, HitSector)
|
||||
|
@ -978,9 +978,9 @@ DEFINE_FIELD_X(TraceResults, FTraceResults, CrossedWaterPos)
|
|||
DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWater)
|
||||
DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWaterPos)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DTracer, Trace)
|
||||
DEFINE_ACTION_FUNCTION(DLineTracer, Trace)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DTracer);
|
||||
PARAM_SELF_PROLOGUE(DLineTracer);
|
||||
/*bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, double maxDist,
|
||||
ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0,
|
||||
ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL);*/
|
||||
|
@ -1001,13 +1001,13 @@ DEFINE_ACTION_FUNCTION(DTracer, Trace)
|
|||
|
||||
// Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags)
|
||||
bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist,
|
||||
(ActorFlag)0xFFFFFFFF, 0xFFFFFFFF, nullptr, self->Results, traceFlags, &DTracer::TraceCallback, self);
|
||||
(ActorFlag)0xFFFFFFFF, 0xFFFFFFFF, nullptr, self->Results, traceFlags, &DLineTracer::TraceCallback, self);
|
||||
ACTION_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
ETraceStatus DTracer::TraceCallback(FTraceResults& res, void* pthis)
|
||||
ETraceStatus DLineTracer::TraceCallback(FTraceResults& res, void* pthis)
|
||||
{
|
||||
DTracer* self = (DTracer*)pthis;
|
||||
DLineTracer* self = (DLineTracer*)pthis;
|
||||
// "res" here should refer to self->Results anyway.
|
||||
|
||||
// patch results a bit. modders don't expect it to work like this most likely.
|
||||
|
@ -1036,13 +1036,13 @@ ETraceStatus DTracer::TraceCallback(FTraceResults& res, void* pthis)
|
|||
return self->CallZScriptCallback();
|
||||
}
|
||||
|
||||
ETraceStatus DTracer::CallZScriptCallback()
|
||||
ETraceStatus DLineTracer::CallZScriptCallback()
|
||||
{
|
||||
IFVIRTUAL(DTracer, TraceCallback)
|
||||
IFVIRTUAL(DLineTracer, TraceCallback)
|
||||
{
|
||||
int status;
|
||||
VMReturn results[1] = { &status };
|
||||
VMValue params[1] = { (DTracer*)this };
|
||||
VMValue params[1] = { (DLineTracer*)this };
|
||||
VMCall(func, params, 1, results, 1);
|
||||
return (ETraceStatus)status;
|
||||
}
|
||||
|
|
|
@ -113,9 +113,9 @@ bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, d
|
|||
ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL);
|
||||
|
||||
// [ZZ] this is the object that's used for ZScript
|
||||
class DTracer : public DObject
|
||||
class DLineTracer : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DTracer, DObject)
|
||||
DECLARE_CLASS(DLineTracer, DObject)
|
||||
public:
|
||||
FTraceResults Results;
|
||||
static ETraceStatus TraceCallback(FTraceResults& res, void* pthis);
|
||||
|
|
|
@ -73,6 +73,10 @@ extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(c
|
|||
void Mac_I_FatalError(const char* errortext);
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
void Linux_I_FatalError(const char* errortext);
|
||||
#endif
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
@ -268,6 +272,10 @@ int main (int argc, char **argv)
|
|||
Mac_I_FatalError(error.GetMessage());
|
||||
#endif // __APPLE__
|
||||
|
||||
#ifdef __linux__
|
||||
Linux_I_FatalError(error.GetMessage());
|
||||
#endif // __linux__
|
||||
|
||||
exit (-1);
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -79,6 +79,7 @@ extern "C"
|
|||
#ifndef NO_GTK
|
||||
bool I_GtkAvailable ();
|
||||
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
||||
void I_FatalError_Gtk(const char* errortext);
|
||||
#elif defined(__APPLE__)
|
||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
||||
#endif
|
||||
|
@ -157,6 +158,37 @@ bool gameisdead;
|
|||
void Mac_I_FatalError(const char* errortext);
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
void Linux_I_FatalError(const char* errortext)
|
||||
{
|
||||
// Close window or exit fullscreen and release mouse capture
|
||||
SDL_Quit();
|
||||
|
||||
const char *str;
|
||||
if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0)
|
||||
{
|
||||
FString cmd;
|
||||
cmd << "kdialog --title \"" GAMESIG " ";
|
||||
cmd << GetVersionString() << ": No IWAD found\" ";
|
||||
cmd << "--msgbox \"" << errortext << "\"";
|
||||
popen(cmd, "r");
|
||||
}
|
||||
#ifndef NO_GTK
|
||||
else if (I_GtkAvailable())
|
||||
{
|
||||
I_FatalError_Gtk(errortext);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
FString message;
|
||||
message << GAMESIG " ";
|
||||
message << GetVersionString() << ": No IWAD found";
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, message, errortext, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void I_FatalError (const char *error, ...)
|
||||
{
|
||||
static bool alreadyThrown = false;
|
||||
|
@ -175,6 +207,10 @@ void I_FatalError (const char *error, ...)
|
|||
#ifdef __APPLE__
|
||||
Mac_I_FatalError(errortext);
|
||||
#endif // __APPLE__
|
||||
|
||||
#ifdef __linux__
|
||||
Linux_I_FatalError(errortext);
|
||||
#endif
|
||||
|
||||
// Record error to log (if logging)
|
||||
if (Logfile)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** iwadpicker_gtk.cpp
|
||||
** gtk_dialogs.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2008-2016 Braden Obrzut
|
||||
|
@ -126,12 +126,16 @@ DYN_GTK_SYM(gtk_window_new);
|
|||
DYN_GTK_SYM(gtk_window_set_gravity);
|
||||
DYN_GTK_SYM(gtk_window_set_position);
|
||||
DYN_GTK_SYM(gtk_window_set_title);
|
||||
DYN_GTK_SYM(gtk_window_set_resizable);
|
||||
DYN_GTK_SYM(gtk_dialog_run);
|
||||
DYN_GTK_SYM(gtk_dialog_get_type);
|
||||
|
||||
// Gtk3 Only
|
||||
DYN_GTK_OPT3_SYM(gtk_box_new, GtkWidget *(*)(GtkOrientation, gint));
|
||||
DYN_GTK_OPT3_SYM(gtk_button_box_new, GtkWidget *(*)(GtkOrientation));
|
||||
DYN_GTK_OPT3_SYM(gtk_widget_set_halign, void(*)(GtkWidget *, GtkAlign));
|
||||
DYN_GTK_OPT3_SYM(gtk_widget_set_valign, void(*)(GtkWidget *, GtkAlign));
|
||||
DYN_GTK_OPT3_SYM(gtk_message_dialog_new, GtkWidget* (*)(GtkWindow*, GtkDialogFlags, GtkMessageType, GtkButtonsType, const gchar*, ...));
|
||||
|
||||
// Gtk2 Only
|
||||
DYN_GTK_OPT2_SYM(gtk_misc_get_type, GType(*)());
|
||||
|
@ -342,6 +346,70 @@ static int PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
|||
return i;
|
||||
}
|
||||
|
||||
static void ShowError(const char* errortext)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *vbox = nullptr;
|
||||
GtkWidget *bbox = nullptr;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Fatal error");
|
||||
gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_gravity (GTK_WINDOW(window), GDK_GRAVITY_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW(window), false);
|
||||
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
|
||||
g_signal_connect (window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
|
||||
g_signal_connect (window, "key_press_event", G_CALLBACK(CheckEscape), NULL);
|
||||
|
||||
// Create the vbox container.
|
||||
if (gtk_box_new) // Gtk3
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
else if (gtk_vbox_new) // Gtk2
|
||||
vbox = gtk_vbox_new (FALSE, 10);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER(window), vbox);
|
||||
|
||||
// Create the label.
|
||||
widget = gtk_label_new ((const gchar *) errortext);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0);
|
||||
|
||||
if (gtk_widget_set_halign && gtk_widget_set_valign) // Gtk3
|
||||
{
|
||||
gtk_widget_set_halign (widget, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (widget, GTK_ALIGN_START);
|
||||
}
|
||||
else if (gtk_misc_set_alignment && gtk_misc_get_type) // Gtk2
|
||||
gtk_misc_set_alignment (GTK_MISC(widget), 0, 0);
|
||||
|
||||
// Create the Exit button box.
|
||||
if (gtk_button_box_new) // Gtk3
|
||||
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
else if (gtk_hbutton_box_new) // Gtk2
|
||||
bbox = gtk_hbutton_box_new ();
|
||||
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_box_set_spacing (GTK_BOX(bbox), 10);
|
||||
gtk_box_pack_end (GTK_BOX(vbox), bbox, false, false, 0);
|
||||
|
||||
// Create the cancel button.
|
||||
widget = gtk_button_new_with_label ("Exit");
|
||||
gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0);
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window);
|
||||
|
||||
// Finally we can show everything.
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
if (GTK_IS_WINDOW(window))
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
// If we don't do this, then the X window might not actually disappear.
|
||||
while (g_main_context_iteration (NULL, FALSE)) {}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Gtk
|
||||
|
||||
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
||||
|
@ -349,6 +417,10 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
|||
return Gtk::PickIWad (wads, numwads, showwin, defaultiwad);
|
||||
}
|
||||
|
||||
void I_FatalError_Gtk(const char* errortext) {
|
||||
Gtk::ShowError(errortext);
|
||||
}
|
||||
|
||||
bool I_GtkAvailable()
|
||||
{
|
||||
using namespace Gtk;
|
|
@ -2999,7 +2999,7 @@ CCMD (cd_resume)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD (playlist)
|
||||
UNSAFE_CCMD (playlist)
|
||||
{
|
||||
int argc = argv.argc();
|
||||
|
||||
|
|
|
@ -124,13 +124,13 @@ CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
currSong->FluidSettingNum("synth.gain", self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, fluid_reverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR(Bool, fluid_reverb, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (currSong != NULL)
|
||||
currSong->FluidSettingInt("synth.reverb.active", self);
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, fluid_chorus, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR(Bool, fluid_chorus, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (currSong != NULL)
|
||||
currSong->FluidSettingInt("synth.chorus.active", self);
|
||||
|
|
|
@ -1206,8 +1206,21 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName)
|
|||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(texid);
|
||||
const FTexture* const tex = TexMan.ByIndex(texid);
|
||||
ACTION_RETURN_STRING(nullptr == tex ? FString() : tex->Name);
|
||||
auto tex = TexMan.ByIndex(texid);
|
||||
FString retval;
|
||||
|
||||
if (tex != nullptr)
|
||||
{
|
||||
if (tex->Name.IsNotEmpty()) retval = tex->Name;
|
||||
else
|
||||
{
|
||||
// Textures for full path names do not have their own name, they merely link to the source lump.
|
||||
auto lump = tex->GetSourceLump();
|
||||
if (Wads.GetLinkedTexture(lump) == tex)
|
||||
retval = Wads.GetLumpFullName(lump);
|
||||
}
|
||||
}
|
||||
ACTION_RETURN_STRING(retval);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -376,6 +376,14 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
|
|||
setlinespecial 1008 Door_Open 0 64 0 0 0
|
||||
}
|
||||
|
||||
7ED9800213C00D6E7FB98652AB48B3DE // Ultimate Simplicity, map04
|
||||
{
|
||||
// Add missing map spots on easy and medium skills
|
||||
// Demons will teleport into starting room making 100% kills possible
|
||||
setthingskills 31 31
|
||||
setthingskills 32 31
|
||||
}
|
||||
|
||||
1891E029994B023910CFE0B3209C3CDB // Ultimate Simplicity, map07
|
||||
{
|
||||
// It is possible to get stuck on skill 0 or 1 when no shots have been fired
|
||||
|
@ -386,6 +394,13 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
|
|||
setlinespecial 411 NoiseAlert 0 0 0 0 0
|
||||
}
|
||||
|
||||
F0E6F30F57B0425F17E43600AA813E80 // Ultimate Simplicity, map11
|
||||
{
|
||||
// If door (sector #309) is closed it cannot be open again
|
||||
// from one side potentially blocking level progression
|
||||
clearlinespecial 2445
|
||||
}
|
||||
|
||||
952CC8D03572E17BA550B01B366EFBB9 // Cheogsh map01
|
||||
{
|
||||
// make the blue key spawn above the 3D floor
|
||||
|
@ -685,6 +700,10 @@ EBDAC00E9D25D884B2C8F4B1F0390539 // doom2.wad map21
|
|||
setsectoroffset 50 ceil -56
|
||||
setsectoroffset 54 ceil -56
|
||||
}
|
||||
94893A0DC429A22ADC4B3A73DA537E16 // DOOM2.WAD map25
|
||||
{
|
||||
rebuildnodes
|
||||
}
|
||||
110F84DE041052B59307FAF0293E6BC0 // Doom II, map27
|
||||
{
|
||||
setsectorspecial 93 0
|
||||
|
@ -844,3 +863,8 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6
|
|||
setthingz 403 168
|
||||
setthingz 404 168
|
||||
}
|
||||
|
||||
6D4156EE0D12B77AD143A37C4D3DCF98 // dmonfear.wad map22
|
||||
{
|
||||
shorttex
|
||||
}
|
||||
|
|
3
wadsrc/static/credits/rsmk.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
These sprites were made by Talon1024 and have been put in the public domain:
|
||||
|
||||
https://forum.zdoom.org/viewtopic.php?f=15&t=59245
|
|
@ -2729,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 (Requires Restart)";
|
||||
GLPREFMNU_VRQUADSTEREO = "Enable Quad Stereo";
|
||||
GLPREFMNU_MULTISAMPLE = "Multisample";
|
||||
GLPREFMNU_TONEMAP = "Tonemap Mode";
|
||||
GLPREFMNU_BLOOM = "Bloom effect";
|
||||
|
|
|
@ -118,7 +118,7 @@ DoomEdNums
|
|||
9851 = SpotLightPulseAdditive
|
||||
9852 = SpotLightFlickerAdditive
|
||||
9853 = SectorSpotLightAdditive
|
||||
9854 = SpotLightFlickerRandomSubtractive
|
||||
9854 = SpotLightFlickerRandomAdditive
|
||||
9860 = SpotLightSubtractive
|
||||
9861 = SpotLightPulseSubtractive
|
||||
9862 = SpotLightFlickerSubtractive
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#define FRACBITS 16
|
||||
#define fixed_t int
|
||||
|
||||
int fuzz_random_x_offset[FUZZ_RANDOM_X_SIZE] =
|
||||
{
|
||||
int fuzz_random_x_offset[FUZZ_RANDOM_X_SIZE] = int[]
|
||||
(
|
||||
75, 76, 21, 91, 56, 33, 62, 99, 61, 79,
|
||||
95, 54, 41, 18, 69, 43, 49, 59, 10, 84,
|
||||
94, 17, 57, 46, 9, 39, 55, 34,100, 81,
|
||||
|
@ -17,16 +17,16 @@ int fuzz_random_x_offset[FUZZ_RANDOM_X_SIZE] =
|
|||
65, 15, 97, 20, 67, 74, 98, 85, 60, 68,
|
||||
19, 26, 8, 87, 86, 64, 11, 37, 31, 47,
|
||||
25, 5, 50, 51, 23, 2, 93, 70, 40, 45
|
||||
};
|
||||
);
|
||||
|
||||
int fuzzoffset[FUZZTABLE] =
|
||||
{
|
||||
int fuzzoffset[FUZZTABLE] = int[]
|
||||
(
|
||||
6, 11, 6, 11, 6, 6, 11, 6, 6, 11,
|
||||
6, 6, 6, 11, 6, 6, 6, 11, 15, 18,
|
||||
21, 6, 11, 15, 6, 6, 6, 6, 11, 6,
|
||||
11, 6, 6, 11, 15, 6, 6, 11, 15, 18,
|
||||
21, 6, 6, 6, 6, 11, 6, 6, 11, 6
|
||||
};
|
||||
);
|
||||
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
|
|
BIN
wadsrc/static/sprites/rsmka0.png
Normal file
After Width: | Height: | Size: 992 B |
BIN
wadsrc/static/sprites/rsmkb0.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
wadsrc/static/sprites/rsmkc0.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
wadsrc/static/sprites/rsmkd0.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
wadsrc/static/sprites/rsmke0.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
|
@ -524,7 +524,7 @@ struct TraceResults native
|
|||
native vector3 Crossed3DWaterPos;
|
||||
}
|
||||
|
||||
class Tracer : Object native
|
||||
class LineTracer : Object native
|
||||
{
|
||||
native @TraceResults Results;
|
||||
native bool Trace(vector3 start, Sector sec, vector3 direction, double maxDist, ETraceFlags traceFlags);
|
||||
|
@ -591,6 +591,10 @@ struct LevelLocals native
|
|||
native readonly int maptype;
|
||||
native readonly String Music;
|
||||
native readonly int musicorder;
|
||||
native readonly TextureID skytexture1;
|
||||
native readonly TextureID skytexture2;
|
||||
native float skyspeed1;
|
||||
native float skyspeed2;
|
||||
native int total_secrets;
|
||||
native int found_secrets;
|
||||
native int total_items;
|
||||
|
@ -640,7 +644,9 @@ struct LevelLocals native
|
|||
native static clearscope vector3 Vec3Diff(vector3 v1, vector3 v2);
|
||||
|
||||
native String GetChecksum() const;
|
||||
|
||||
|
||||
native void ChangeSky( TextureID sky1, TextureID sky2 );
|
||||
|
||||
String TimeFormatted(bool totals = false)
|
||||
{
|
||||
int sec = Thinker.Tics2Seconds(totals? totaltime : time);
|
||||
|
|
|
@ -78,8 +78,8 @@ class Weapon : StateProvider native
|
|||
Stop;
|
||||
}
|
||||
|
||||
native bool CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo = false, int ammocount = -1);
|
||||
native bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1);
|
||||
native virtual bool CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo = false, int ammocount = -1);
|
||||
native virtual bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1);
|
||||
|
||||
virtual State GetReadyState ()
|
||||
{
|
||||
|
|
|
@ -128,16 +128,18 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu
|
|||
{
|
||||
private String ccmd; // do not allow access to this from the outside.
|
||||
bool mCloseOnSelect;
|
||||
private bool mUnsafe;
|
||||
|
||||
OptionMenuItemCommand Init(String label, Name command, bool centered = false, bool closeonselect = false)
|
||||
{
|
||||
Super.Init(label, command, 0, centered);
|
||||
ccmd = command;
|
||||
mCloseOnSelect = closeonselect;
|
||||
mUnsafe = true;
|
||||
return self;
|
||||
}
|
||||
|
||||
private native static void DoCommand(String cmd); // This is very intentionally limited to this menu item to prevent abuse.
|
||||
private native static void DoCommand(String cmd, bool unsafe); // This is very intentionally limited to this menu item to prevent abuse.
|
||||
|
||||
override bool Activate()
|
||||
{
|
||||
|
@ -151,7 +153,7 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu
|
|||
if (m.GetItem(mAction) != self) return false;
|
||||
}
|
||||
Menu.MenuSound("menu/choose");
|
||||
DoCommand(ccmd);
|
||||
DoCommand(ccmd, mUnsafe);
|
||||
if (mCloseOnSelect)
|
||||
{
|
||||
let curmenu = Menu.GetCurrentMenu();
|
||||
|
|
|
@ -528,7 +528,7 @@ class PlayerPawn : Actor native
|
|||
if (level.time >= player.respawn_time || ((player.cmd.buttons & BT_USE) && player.Bot == NULL))
|
||||
{
|
||||
player.cls = NULL; // Force a new class if the player is using a random class
|
||||
player.playerstate = (multiplayer || (level.AllowRespawn) || sv_singleplayerrespawn)? PST_REBORN : PST_ENTER;
|
||||
player.playerstate = (multiplayer || level.AllowRespawn || sv_singleplayerrespawn || G_SkillPropertyInt(SKILLP_PlayerRespawn)) ? PST_REBORN : PST_ENTER;
|
||||
if (special1 > 2)
|
||||
{
|
||||
special1 = 0;
|
||||
|
|
Before Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 380 B |
Before Width: | Height: | Size: 255 B |