Merge remote-tracking branch 'remotes/ZDoom/gzdoom/staging' into gzd_staging

This commit is contained in:
nashmuhandes 2023-08-22 09:09:51 +08:00
commit 9e0bf90be6
177 changed files with 4290 additions and 12626 deletions

View file

@ -1,4 +1,4 @@
cmake_minimum_required( VERSION 3.1.0 )
cmake_minimum_required( VERSION 3.16.0 )
include(precompiled_headers)
@ -97,7 +97,7 @@ else()
if( NOT DYN_GTK )
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${GTK3_LIBRARIES} )
endif()
include_directories( ${GTK3_INCLUDE_DIRS} )
include_directories( SYSTEM ${GTK3_INCLUDE_DIRS} )
link_directories( ${GTK3_LIBRARY_DIRS} )
else()
pkg_check_modules( GTK2 gtk+-2.0 )
@ -105,7 +105,7 @@ else()
if( NOT DYN_GTK )
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${GTK2_LIBRARIES} )
endif()
include_directories( ${GTK2_INCLUDE_DIRS} )
include_directories( SYSTEM ${GTK2_INCLUDE_DIRS} )
link_directories( ${GTK2_LIBRARY_DIRS} )
else()
set( NO_GTK ON )
@ -132,7 +132,7 @@ else()
# Non-Windows version also needs SDL except native OS X backend
if( NOT APPLE OR NOT OSX_COCOA_BACKEND )
find_package( SDL2 REQUIRED )
include_directories( "${SDL2_INCLUDE_DIR}" )
include_directories( SYSTEM "${SDL2_INCLUDE_DIR}" )
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${SDL2_LIBRARY}" )
endif()
@ -143,7 +143,7 @@ if( NOT NO_OPENAL )
find_package( OpenAL )
mark_as_advanced(CLEAR OPENAL_INCLUDE_DIR)
if( OPENAL_INCLUDE_DIR )
include_directories( ${OPENAL_INCLUDE_DIR} )
include_directories( SYSTEM ${OPENAL_INCLUDE_DIR} )
mark_as_advanced(CLEAR OPENAL_LIBRARY)
if( OPENAL_LIBRARY )
set( PROJECT_LIBRARIES ${OPENAL_LIBRARY} ${PROJECT_LIBRARIES} )
@ -278,10 +278,7 @@ endif()
# Check for thread_local keyword, it's optional at the moment
CHECK_CXX_SOURCE_COMPILES("thread_local int i; int main() { i = 0; }"
HAVE_THREAD_LOCAL)
if( NOT HAVE_THREAD_LOCAL )
if ( NOT (cxx_thread_local IN_LIST CMAKE_CXX_COMPILE_FEATURES) )
message( SEND_ERROR "C++ compiler doesn't support thread_local storage duration specifier" )
endif()
@ -373,17 +370,17 @@ endif()
if( VPX_FOUND )
add_definitions( "-DUSE_LIBVPX=1" )
include_directories( "${VPX_INCLUDE_DIR}" )
include_directories( SYSTEM "${VPX_INCLUDE_DIR}" )
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${VPX_LIBRARIES} )
else()
message( SEND_ERROR "Could not find libvpx" )
endif()
include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}")
include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}")
if( ${HAVE_VM_JIT} )
add_definitions( -DHAVE_VM_JIT )
include_directories( "${ASMJIT_INCLUDE_DIR}" )
include_directories( SYSTEM "${ASMJIT_INCLUDE_DIR}" )
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ASMJIT_LIBRARIES}")
endif()
@ -407,7 +404,7 @@ set( PLAT_WIN32_SOURCES
)
if (HAVE_VULKAN)
set (PLAT_WIN32_SOURCES ${PLAT_WIN32_SOURCES} common/platform/win32/win32vulkanvideo.cpp )
list (APPEND PLAT_WIN32_SOURCES common/platform/win32/win32vulkanvideo.cpp )
endif()
# todo: implement an actual crash catcher for ARM
@ -698,10 +695,6 @@ set( VM_JIT_SOURCES
common/scripting/jit/jit_store.cpp
)
# This is disabled for now because I cannot find a way to give the .pch file a different name.
# Visual C++ 2015 seems hell-bent on only allowing one .pch file with the same name as the executable.
#enable_precompiled_headers( g_pch2.h FASTMATH_PCH_SOURCES )
# Enable fast math for some sources
set( FASTMATH_SOURCES
rendering/swrenderer/r_all.cpp
@ -760,7 +753,7 @@ set (VULKAN_SOURCES
)
if (HAVE_VULKAN)
set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${VULKAN_SOURCES})
list (APPEND FASTMATH_SOURCES ${VULKAN_SOURCES})
endif()
set (FASTMATH_SOURCES ${FASTMATH_SOURCES})
@ -1016,6 +1009,7 @@ set (PCH_SOURCES
common/textures/formats/stbtexture.cpp
common/textures/formats/anmtexture.cpp
common/textures/formats/startscreentexture.cpp
common/textures/formats/qoitexture.cpp
common/textures/hires/hqresize.cpp
common/models/models_md3.cpp
common/models/models_md2.cpp
@ -1054,7 +1048,6 @@ set (PCH_SOURCES
common/utility/i_time.cpp
common/utility/m_argv.cpp
common/utility/s_playlist.cpp
common/utility/zstrformat.cpp
common/utility/name.cpp
common/utility/r_memory.cpp
common/thirdparty/base64.cpp
@ -1157,14 +1150,7 @@ else()
set( NOT_COMPILED_SOURCE_FILES ${NOT_COMPILED_SOURCE_FILES} ${VM_JIT_SOURCES} )
endif()
if( MSVC )
enable_precompiled_headers( g_pch.h PCH_SOURCES )
else()
# Temporary solution for compilers other than MSVC
set_source_files_properties( ${PCH_SOURCES} PROPERTIES COMPILE_FLAGS "-include g_pch.h" )
endif()
add_executable( zdoom WIN32 MACOSX_BUNDLE
set( ZDOOM_SOURCES
${HEADER_FILES}
${NOT_COMPILED_SOURCE_FILES}
${SYSTEM_SOURCES}
@ -1172,6 +1158,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
${PCH_SOURCES}
common/utility/x86.cpp
common/thirdparty/strnatcmp.c
common/thirdparty/stb/stb_sprintf.c
common/utility/zstring.cpp
common/utility/findfile.cpp
common/thirdparty/math/asin.c
@ -1194,10 +1181,18 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
common/thirdparty/math/fastsin.cpp
)
set( ZDOOM_NONPCH_SOURCES ${ZDOOM_SOURCES} )
list( REMOVE_ITEM ZDOOM_NONPCH_SOURCES ${PCH_SOURCES} )
add_executable( zdoom WIN32 MACOSX_BUNDLE ${ZDOOM_SOURCES} )
target_precompile_headers( zdoom PRIVATE g_pch.h )
set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${ZD_FASTMATH_FLAG} )
set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" )
set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" )
set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE )
set_source_files_properties( ${ZDOOM_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE )
if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
@ -1212,15 +1207,18 @@ if( UNIX )
endif()
endif()
target_link_libraries( zdoom ${PROJECT_LIBRARIES} gdtoa lzma ${ZMUSIC_LIBRARIES} )
target_link_libraries( zdoom ${PROJECT_LIBRARIES} lzma ${ZMUSIC_LIBRARIES} )
include_directories( .
include_directories(
BEFORE
.
common/audio/sound
common/audio/music
common/2d
common/cutscenes
common/thirdparty/libsmackerdec/include
common/thirdparty
common/thirdparty/stb
common/textures
common/textures/formats
common/textures/hires
@ -1264,9 +1262,7 @@ include_directories( .
scripting
scripting/zscript
rendering
../libraries/gdtoa
../libraries/ZVulkan/include
${CMAKE_BINARY_DIR}/libraries/gdtoa
${SYSTEM_SOURCES_DIR}
)
@ -1457,6 +1453,7 @@ source_group("Common\\Third Party" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_D
source_group("Common\\Third Party\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/math/.+")
source_group("Common\\Third Party\\RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/rapidjson/.+")
source_group("Common\\Third Party\\SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/sfmt/.+")
source_group("Common\\Third Party\\stb" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/thirdparty/stb/.+")
source_group("Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/utility/.+")
source_group("Utility\\Node Builder" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/utility/nodebuilder/.+")
source_group("Utility\\Smackerdec" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/smackerdec/.+")

View file

@ -2018,6 +2018,9 @@ void DAutomap::drawSubsectors()
PalEntry flatcolor;
mpoint_t originpt;
auto lm = getRealLightmode(Level, false);
bool softlightramp = !V_IsHardwareRenderer() || lm == ELightMode::Doom || lm == ELightMode::DoomDark;
auto &subsectors = Level->subsectors;
for (unsigned i = 0; i < subsectors.Size(); ++i)
{
@ -2192,15 +2195,14 @@ void DAutomap::drawSubsectors()
// Why the +12? I wish I knew, but experimentation indicates it
// is necessary in order to best reproduce Doom's original lighting.
double fadelevel;
if (!V_IsHardwareRenderer() || primaryLevel->lightMode == ELightMode::DoomDark || primaryLevel->lightMode == ELightMode::Doom || primaryLevel->lightMode == ELightMode::ZDoomSoftware || primaryLevel->lightMode == ELightMode::DoomSoftware)
if (softlightramp)
{
double map = (NUMCOLORMAPS * 2.) - ((floorlight + 12) * (NUMCOLORMAPS / 128.));
fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0);
}
else
{
// The hardware renderer's light modes 0, 1 and 4 use a linear light scale which must be used here as well. Otherwise the automap gets too dark.
// for the hardware renderer's light modes that use a linear light scale this must do the same. Otherwise the automap gets too dark.
fadelevel = 1. - clamp(floorlight, 0, 255) / 255.f;
}

View file

@ -68,7 +68,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Clear, Shape2DTransform_Clear)
static void Shape2DTransform_Rotate(DShape2DTransform* self, double angle)
{
self->transform = DMatrix3x3::Rotate2D(DEG2RAD(angle)) * self->transform;
self->transform = DMatrix3x3::Rotate2D(angle) * self->transform;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Rotate, Shape2DTransform_Rotate)

View file

@ -197,7 +197,7 @@ FileReader FSF2Reader::OpenFile(const char *name)
FZipPatReader::FZipPatReader(const char *filename)
{
mAllowAbsolutePaths = true;
resf = FResourceFile::OpenResourceFile(filename, true);
resf = FResourceFile::OpenResourceFile(filename);
}
FZipPatReader::~FZipPatReader()

View file

@ -38,6 +38,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>
#include <memory>
#include "i_sound.h"
#include "i_music.h"

View file

@ -397,7 +397,7 @@ const char *FBaseCVar::ToString (UCVarValue value, ECVarType type)
case CVAR_Float:
IGNORE_FORMAT_PRE
mysnprintf (cstrbuf, countof(cstrbuf), "%H", value.Float);
mysnprintf (cstrbuf, countof(cstrbuf), "%g", value.Float);
IGNORE_FORMAT_POST
break;
@ -489,7 +489,7 @@ UCVarValue FBaseCVar::FromFloat (float value, ECVarType type)
case CVAR_String:
IGNORE_FORMAT_PRE
mysnprintf (cstrbuf, countof(cstrbuf), "%H", value);
mysnprintf (cstrbuf, countof(cstrbuf), "%g", value);
IGNORE_FORMAT_POST
ret.String = cstrbuf;
break;

View file

@ -87,8 +87,8 @@ VMFunction* LookupFunction(const char* qname, bool validate)
size_t p = strcspn(qname, ".");
if (p == 0)
I_Error("Call to undefined function %s", qname);
FString clsname(qname, p);
FString funcname = qname + p + 1;
FName clsname(qname, p, true);
FName funcname(qname + p + 1, true);
auto func = PClass::FindFunction(clsname, funcname);
if (func == nullptr)

View file

@ -120,6 +120,11 @@ bool M_LoadJoystickConfig(IJoystickConfig *joy)
{
return false;
}
value = GameConfig->GetValueForKey("Enabled");
if (value != NULL)
{
joy->SetEnabled((bool)atoi(value));
}
value = GameConfig->GetValueForKey("Sensitivity");
if (value != NULL)
{
@ -176,6 +181,10 @@ void M_SaveJoystickConfig(IJoystickConfig *joy)
if (GameConfig != NULL && M_SetJoystickConfigSection(joy, true, GameConfig))
{
GameConfig->ClearCurrentSection();
if (!joy->GetEnabled())
{
GameConfig->SetValueForKey("Enabled", "0");
}
if (!joy->IsSensitivityDefault())
{
mysnprintf(value, countof(value), "%g", joy->GetSensitivity());

View file

@ -18,7 +18,7 @@ enum EJoyAxis
};
// Generic configuration interface for a controller.
struct NOVTABLE IJoystickConfig
struct IJoystickConfig
{
virtual ~IJoystickConfig() = 0;
@ -36,6 +36,9 @@ struct NOVTABLE IJoystickConfig
virtual void SetAxisMap(int axis, EJoyAxis gameaxis) = 0;
virtual void SetAxisScale(int axis, float scale) = 0;
virtual bool GetEnabled() = 0;
virtual void SetEnabled(bool enabled) = 0;
// Used by the saver to not save properties that are at their defaults.
virtual bool IsSensitivityDefault() = 0;
virtual bool IsAxisDeadZoneDefault(int axis) = 0;

View file

@ -7,8 +7,9 @@
# define ATTRIBUTE(attrlist)
#endif
// This header collects all things printf, so that this doesn't need to pull in other, far more dirty headers, just for outputting some text.
#include "stb_sprintf.h"
// This header collects all things printf, so that this doesn't need to pull in other, far more dirty headers, just for outputting some text.
extern "C" int mysnprintf(char* buffer, size_t count, const char* format, ...) ATTRIBUTE((format(printf, 3, 4)));
extern "C" int myvsnprintf(char* buffer, size_t count, const char* format, va_list argptr) ATTRIBUTE((format(printf, 3, 0)));

View file

@ -55,6 +55,7 @@
#include "textures.h"
#include "texturemanager.h"
#include "base64.h"
#include "vm.h"
extern DObject *WP_NOCHANGE;
bool save_full = false; // for testing. Should be removed afterward.
@ -1567,6 +1568,35 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary
}
}
template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& func, VMFunction**)
{
if (arc.isWriting())
{
arc.WriteKey(key);
if (func) arc.w->String(func->QualifiedName);
else arc.w->Null();
}
else
{
func = nullptr;
auto val = arc.r->FindKey(key);
if (val != nullptr && val->IsString())
{
auto qname = val->GetString();
size_t p = strcspn(qname, ".");
if (p != 0)
{
FName clsname(qname, p, true);
FName funcname(qname + p + 1, true);
func = PClass::FindFunction(clsname, funcname);
}
}
}
return arc;
}
//==========================================================================
//
// Handler to retrieve a numeric value of any kind.

View file

@ -310,6 +310,7 @@ inline FSerializer& Serialize(FSerializer& arc, const char* key, BitArray& value
template<> FSerializer& Serialize(FSerializer& arc, const char* key, PClass*& clst, PClass** def);
template<> FSerializer& Serialize(FSerializer& arc, const char* key, FFont*& font, FFont** def);
template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def);
template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& dict, VMFunction** def);
inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector3 &p, DVector3 *def)
{

View file

@ -39,7 +39,6 @@
#include "resourcefile.h"
#include "cmdlib.h"
#include "printf.h"
@ -189,7 +188,7 @@ class F7ZFile : public FResourceFile
public:
F7ZFile(const char * filename, FileReader &filer);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual ~F7ZFile();
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -216,7 +215,7 @@ F7ZFile::F7ZFile(const char * filename, FileReader &filer)
//
//==========================================================================
bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter)
bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf)
{
Archive = new C7zArchive(Reader);
int skipped = 0;
@ -227,25 +226,21 @@ bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter)
{
delete Archive;
Archive = NULL;
if (!quiet)
if (res == SZ_ERROR_UNSUPPORTED)
{
Printf("\n" TEXTCOLOR_RED "%s: ", FileName.GetChars());
if (res == SZ_ERROR_UNSUPPORTED)
{
Printf("Decoder does not support this archive\n");
}
else if (res == SZ_ERROR_MEM)
{
Printf("Cannot allocate memory\n");
}
else if (res == SZ_ERROR_CRC)
{
Printf("CRC error\n");
}
else
{
Printf("error #%d\n", res);
}
Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.GetChars());
}
else if (res == SZ_ERROR_MEM)
{
Printf(FSMessageLevel::Error, "Cannot allocate memory\n");
}
else if (res == SZ_ERROR_CRC)
{
Printf(FSMessageLevel::Error, "CRC error\n");
}
else
{
Printf(FSMessageLevel::Error, "error #%d\n", res);
}
return false;
}
@ -308,7 +303,7 @@ bool F7ZFile::Open(bool quiet, LumpFilterInfo *filter)
if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0]))
{
if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.GetChars());
return false;
}
}
@ -356,7 +351,7 @@ int F7ZLump::FillCache()
//
//==========================================================================
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[k7zSignatureSize];
@ -368,7 +363,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpF
if (!memcmp(head, k7zSignature, k7zSignatureSize))
{
auto rf = new F7ZFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -38,7 +38,6 @@
#include "resourcefile.h"
#include "cmdlib.h"
#include "printf.h"
#include "findfile.h"
//==========================================================================
@ -67,12 +66,12 @@ class FDirectory : public FResourceFile
TArray<FDirectoryLump> Lumps;
const bool nosubdir;
int AddDirectory(const char *dirpath);
int AddDirectory(const char* dirpath, FileSystemMessageFunc Printf);
void AddEntry(const char *fullpath, int size);
public:
FDirectory(const char * dirname, bool nosubdirflag = false);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -110,7 +109,7 @@ FDirectory::FDirectory(const char * directory, bool nosubdirflag)
//
//==========================================================================
int FDirectory::AddDirectory(const char *dirpath)
int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf)
{
void * handle;
int count = 0;
@ -122,7 +121,7 @@ int FDirectory::AddDirectory(const char *dirpath)
handle = I_FindFirst(dirmatch.GetChars(), &find);
if (handle == ((void *)(-1)))
{
Printf("Could not scan '%s': %s\n", dirpath, strerror(errno));
Printf(FSMessageLevel::Error, "Could not scan '%s': %s\n", dirpath, strerror(errno));
}
else
{
@ -148,7 +147,7 @@ int FDirectory::AddDirectory(const char *dirpath)
}
FString newdir = dirpath;
newdir << fi << '/';
count += AddDirectory(newdir);
count += AddDirectory(newdir, Printf);
}
else
{
@ -193,9 +192,9 @@ int FDirectory::AddDirectory(const char *dirpath)
//
//==========================================================================
bool FDirectory::Open(bool quiet, LumpFilterInfo* filter)
bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
NumLumps = AddDirectory(FileName);
NumLumps = AddDirectory(FileName, Printf);
PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter);
return true;
}
@ -265,10 +264,10 @@ int FDirectoryLump::FillCache()
//
//==========================================================================
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag, LumpFilterInfo* filter)
FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
auto rf = new FDirectory(filename, nosubdirflag);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter, Printf)) return rf;
delete rf;
return nullptr;
}

View file

@ -34,7 +34,6 @@
*/
#include "resourcefile.h"
#include "printf.h"
//==========================================================================
//
@ -72,7 +71,7 @@ class FGrpFile : public FUncompressedFile
{
public:
FGrpFile(const char * filename, FileReader &file);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter);
};
@ -93,7 +92,7 @@ FGrpFile::FGrpFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FGrpFile::Open(bool quiet, LumpFilterInfo*)
bool FGrpFile::Open(LumpFilterInfo* filter)
{
GrpHeader header;
@ -129,7 +128,7 @@ bool FGrpFile::Open(bool quiet, LumpFilterInfo*)
//
//==========================================================================
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[12];
@ -141,7 +140,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, Lump
if (!memcmp(head, "KenSilverman", 12))
{
auto rf = new FGrpFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -34,7 +34,6 @@
#include "resourcefile.h"
#include "cmdlib.h"
#include "printf.h"
//==========================================================================
//
@ -46,7 +45,7 @@ class FLumpFile : public FUncompressedFile
{
public:
FLumpFile(const char * filename, FileReader &file);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter);
};
@ -67,7 +66,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FLumpFile::Open(bool quiet, LumpFilterInfo*)
bool FLumpFile::Open(LumpFilterInfo*)
{
FString name(ExtractFileBase(FileName, true));
@ -78,10 +77,6 @@ bool FLumpFile::Open(bool quiet, LumpFilterInfo*)
Lumps[0].LumpSize = (int)Reader.GetLength();
Lumps[0].Flags = 0;
NumLumps = 1;
if (!quiet)
{
Printf("\n");
}
return true;
}
@ -91,11 +86,11 @@ bool FLumpFile::Open(bool quiet, LumpFilterInfo*)
//
//==========================================================================
FResourceFile *CheckLump(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
// always succeeds
auto rf = new FLumpFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;
return NULL;

View file

@ -33,7 +33,6 @@
*/
#include "resourcefile.h"
#include "printf.h"
//==========================================================================
//
@ -65,7 +64,7 @@ class FPakFile : public FUncompressedFile
{
public:
FPakFile(const char * filename, FileReader &file);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter);
};
@ -88,7 +87,7 @@ FPakFile::FPakFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FPakFile::Open(bool quiet, LumpFilterInfo* filter)
bool FPakFile::Open(LumpFilterInfo* filter)
{
dpackheader_t header;
@ -123,7 +122,7 @@ bool FPakFile::Open(bool quiet, LumpFilterInfo* filter)
//
//==========================================================================
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[4];
@ -135,7 +134,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, Lump
if (!memcmp(head, "PACK", 4))
{
auto rf = new FPakFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -35,8 +35,6 @@
#include "resourcefile.h"
#include "printf.h"
//==========================================================================
//
//
@ -111,7 +109,7 @@ class FRFFFile : public FResourceFile
public:
FRFFFile(const char * filename, FileReader &file);
virtual ~FRFFFile();
virtual bool Open(bool quiet, LumpFilterInfo* filter);
virtual bool Open(LumpFilterInfo* filter);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};
@ -134,7 +132,7 @@ FRFFFile::FRFFFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FRFFFile::Open(bool quiet, LumpFilterInfo*)
bool FRFFFile::Open(LumpFilterInfo*)
{
RFFLump *lumps;
RFFInfo header;
@ -237,7 +235,7 @@ int FRFFLump::FillCache()
//
//==========================================================================
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[4];
@ -249,7 +247,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, Lump
if (!memcmp(head, "RFF\x1a", 4))
{
auto rf = new FRFFFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -34,7 +34,6 @@
*/
#include "resourcefile.h"
#include "printf.h"
//==========================================================================
//
@ -46,7 +45,7 @@ class FSSIFile : public FUncompressedFile
{
public:
FSSIFile(const char * filename, FileReader &file);
bool Open(bool quiet, int version, int lumpcount, LumpFilterInfo* filter);
bool Open(int version, int lumpcount, LumpFilterInfo* filter);
};
@ -68,7 +67,7 @@ FSSIFile::FSSIFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FSSIFile::Open(bool quiet, int version, int lumpcount, LumpFilterInfo*)
bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*)
{
NumLumps = lumpcount*2;
Lumps.Resize(lumpcount*2);
@ -115,7 +114,7 @@ bool FSSIFile::Open(bool quiet, int version, int lumpcount, LumpFilterInfo*)
//
//==========================================================================
FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter)
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char zerobuf[72];
char buf[72];
@ -146,7 +145,7 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, Lump
if (!skipstring(70)) return nullptr;
}
auto ssi = new FSSIFile(filename, file);
if (ssi->Open(filename, version, numfiles, filter)) return ssi;
if (ssi->Open(version, numfiles, filter)) return ssi;
file = std::move(ssi->Reader); // to avoid destruction of reader
delete ssi;
}

View file

@ -35,7 +35,6 @@
#include <ctype.h>
#include "resourcefile.h"
#include "v_text.h"
#include "filesystem.h"
#include "engineerrors.h"
@ -125,13 +124,13 @@ class FWadFile : public FResourceFile
TArray<FWadFileLump> Lumps;
bool IsMarker(int lump, const char *marker);
void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack=false);
void SkinHack ();
void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, FileSystemMessageFunc Printf, bool flathack=false);
void SkinHack (FileSystemMessageFunc Printf);
public:
FWadFile(const char * filename, FileReader &file);
FResourceLump *GetLump(int lump) { return &Lumps[lump]; }
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
};
@ -154,7 +153,7 @@ FWadFile::FWadFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FWadFile::Open(bool quiet, LumpFilterInfo*)
bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf)
{
wadinfo_t header;
uint32_t InfoTableOfs;
@ -176,7 +175,8 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*)
// Check again to detect broken wads
if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize)
{
I_Error("Cannot load broken WAD file %s\n", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.GetChars());
return false;
}
}
@ -212,7 +212,7 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*)
{
if (Lumps[i].LumpSize != 0)
{
Printf(PRINT_HIGH, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName());
Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName());
Lumps[i].LumpNameSetup("");
}
Lumps[i].LumpSize = Lumps[i].Position = 0;
@ -221,18 +221,15 @@ bool FWadFile::Open(bool quiet, LumpFilterInfo*)
GenerateHash(); // Do this before the lump processing below.
if (!quiet) // don't bother with namespaces in quiet mode. We won't need them.
{
SetNamespace("S_START", "S_END", ns_sprites);
SetNamespace("F_START", "F_END", ns_flats, true);
SetNamespace("C_START", "C_END", ns_colormaps);
SetNamespace("A_START", "A_END", ns_acslibrary);
SetNamespace("TX_START", "TX_END", ns_newtextures);
SetNamespace("V_START", "V_END", ns_strifevoices);
SetNamespace("HI_START", "HI_END", ns_hires);
SetNamespace("VX_START", "VX_END", ns_voxels);
SkinHack();
}
SetNamespace("S_START", "S_END", ns_sprites, Printf);
SetNamespace("F_START", "F_END", ns_flats, Printf, true);
SetNamespace("C_START", "C_END", ns_colormaps, Printf);
SetNamespace("A_START", "A_END", ns_acslibrary, Printf);
SetNamespace("TX_START", "TX_END", ns_newtextures, Printf);
SetNamespace("V_START", "V_END", ns_strifevoices, Printf);
SetNamespace("HI_START", "HI_END", ns_hires, Printf);
SetNamespace("VX_START", "VX_END", ns_voxels, Printf);
SkinHack(Printf);
return true;
}
@ -273,7 +270,7 @@ struct Marker
unsigned int index;
};
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack)
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, FileSystemMessageFunc Printf, bool flathack)
{
bool warned = false;
int numstartmarkers = 0, numendmarkers = 0;
@ -300,7 +297,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
{
if (numendmarkers == 0) return; // no markers found
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker);
if (flathack)
@ -314,7 +311,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
{
// We can't add this to the flats namespace but
// it needs to be flagged for the texture manager.
DPrintf(DMSG_NOTIFY, "Marking %s as potential flat\n", Lumps[ii].getName());
Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.GetChars(), Lumps[ii].getName());
Lumps[ii].Flags |= LUMPF_MAYBEFLAT;
}
}
@ -328,7 +325,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
int start, end;
if (markers[i].markertype != 0)
{
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker);
i++;
continue;
}
@ -337,21 +334,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
// skip over subsequent x_START markers
while (i < markers.Size() && markers[i].markertype == 0)
{
Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", startmarker);
Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), startmarker);
i++;
continue;
}
// same for x_END markers
while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1))
{
Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker);
Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), endmarker);
i++;
continue;
}
// We found a starting marker but no end marker. Ignore this block.
if (i >= markers.Size())
{
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker);
Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), startmarker, endmarker);
end = NumLumps;
}
else
@ -360,14 +357,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
}
// we found a marked block
DPrintf(DMSG_NOTIFY, "Found %s block at (%d-%d)\n", startmarker, markers[start].index, end);
Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.GetChars(), startmarker, markers[start].index, end);
for(int j = markers[start].index + 1; j < end; j++)
{
if (Lumps[j].Namespace != ns_global)
{
if (!warned)
{
Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found (lump %d)\n", j);
Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.GetChars(), j);
}
warned = true;
}
@ -377,7 +374,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
// ignore sprite lumps smaller than 8 bytes (the smallest possible)
// in size -- this was used by some dmadds wads
// as an 'empty' graphics resource
DPrintf(DMSG_WARNING, " Skipped empty sprite %s (lump %d)\n", Lumps[j].getName(), j);
Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.GetChars(), Lumps[j].getName(), j);
}
else
{
@ -401,7 +398,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
//
//==========================================================================
void FWadFile::SkinHack ()
void FWadFile::SkinHack (FileSystemMessageFunc Printf)
{
// this being static is not a problem. The only relevant thing is that each skin gets a different number.
static int namespc = ns_firstskin;
@ -447,11 +444,8 @@ void FWadFile::SkinHack ()
}
if (skinned && hasmap)
{
Printf (TEXTCOLOR_BLUE
"The maps in %s will not be loaded because it has a skin.\n"
TEXTCOLOR_BLUE
"You should remove the skin from the wad to play these maps.\n",
FileName.GetChars());
Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.GetChars());
Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n");
}
}
@ -462,7 +456,7 @@ void FWadFile::SkinHack ()
//
//==========================================================================
FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[4];
@ -474,7 +468,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, Lump
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
{
auto rf = new FWadFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -35,7 +35,6 @@
*/
#include "resourcefile.h"
#include "printf.h"
#include "cmdlib.h"
//==========================================================================
@ -68,7 +67,7 @@ class FWHResFile : public FUncompressedFile
FString basename;
public:
FWHResFile(const char * filename, FileReader &file);
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter);
};
@ -92,7 +91,7 @@ FWHResFile::FWHResFile(const char *filename, FileReader &file)
//
//==========================================================================
bool FWHResFile::Open(bool quiet, LumpFilterInfo*)
bool FWHResFile::Open(LumpFilterInfo*)
{
int directory[1024];
@ -129,7 +128,7 @@ bool FWHResFile::Open(bool quiet, LumpFilterInfo*)
//
//==========================================================================
FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory.
{
@ -149,7 +148,7 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, Lu
checkpos += (length+4095) / 4096;
}
auto rf = new FWHResFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;
}

View file

@ -37,7 +37,6 @@
#include "file_zip.h"
#include "cmdlib.h"
#include "printf.h"
#include "w_zip.h"
#include "ancientzip.h"
@ -52,50 +51,42 @@
static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags)
{
try
switch (Method)
{
switch (Method)
{
case METHOD_STORED:
{
Reader.Read(Cache, LumpSize);
break;
}
case METHOD_DEFLATE:
case METHOD_BZIP2:
case METHOD_LZMA:
{
FileReader frz;
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); }))
{
frz.Read(Cache, LumpSize);
}
break;
}
// Fixme: These should also use a stream
case METHOD_IMPLODE:
{
FZipExploder exploder;
exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags);
break;
}
case METHOD_SHRINK:
{
ShrinkLoop((unsigned char *)Cache, LumpSize, Reader, CompressedSize);
break;
}
default:
assert(0);
return false;
}
case METHOD_STORED:
{
Reader.Read(Cache, LumpSize);
break;
}
catch (CRecoverableError &err)
case METHOD_DEFLATE:
case METHOD_BZIP2:
case METHOD_LZMA:
{
Printf("%s\n", err.GetMessage());
FileReader frz;
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); }))
{
frz.Read(Cache, LumpSize);
}
break;
}
// Fixme: These should also use a stream
case METHOD_IMPLODE:
{
FZipExploder exploder;
exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags);
break;
}
case METHOD_SHRINK:
{
ShrinkLoop((unsigned char *)Cache, LumpSize, Reader, CompressedSize);
break;
}
default:
assert(0);
return false;
}
return true;
@ -173,7 +164,7 @@ FZipFile::FZipFile(const char * filename, FileReader &file)
Lumps = NULL;
}
bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
bool zip64 = false;
uint32_t centraldir = Zip_FindCentralDir(Reader, &zip64);
@ -183,7 +174,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (centraldir == 0)
{
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.GetChars());
return false;
}
@ -199,7 +190,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (info.NumEntries != info.NumEntriesOnAllDisks ||
info.FirstDisk != 0 || info.DiskNumber != 0)
{
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars());
return false;
}
@ -218,7 +209,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (info.NumEntries != info.NumEntriesOnAllDisks ||
info.FirstDisk != 0 || info.DiskNumber != 0)
{
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars());
return false;
}
@ -257,7 +248,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
{
free(directory);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars());
return false;
}
@ -323,7 +314,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
{
free(directory);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars());
Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars());
return false;
}
@ -350,7 +341,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
zip_fh->Method != METHOD_IMPLODE &&
zip_fh->Method != METHOD_SHRINK)
{
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method);
Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method);
skipped++;
continue;
}
@ -358,7 +349,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
zip_fh->Flags = LittleShort(zip_fh->Flags);
if (zip_fh->Flags & ZF_ENCRYPTED)
{
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars());
Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars());
skipped++;
continue;
}
@ -385,7 +376,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff)
{
// The file system is limited to 32 bit file sizes;
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars());
Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars());
skipped++;
continue;
}
@ -508,7 +499,16 @@ int FZipLump::FillCache()
Owner->Reader.Seek(Position, FileReader::SeekSet);
Cache = new char[LumpSize];
UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
try
{
UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
}
catch (const CRecoverableError& )
{
// this cannot propagate the exception but also has no means to handle the error message. Damn...
// At least don't return uninitialized memory here.
memset(Cache, 0, LumpSize);
}
RefCount = 1;
return 1;
}
@ -532,7 +532,7 @@ int FZipLump::GetFileOffset()
//
//==========================================================================
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
char head[4];
@ -544,7 +544,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, Lump
if (!memcmp(head, "PK\x3\x4", 4))
{
auto rf = new FZipFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
if (rf->Open(filter, Printf)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -41,7 +41,7 @@ class FZipFile : public FResourceFile
public:
FZipFile(const char * filename, FileReader &file);
virtual ~FZipFile();
bool Open(bool quiet, LumpFilterInfo* filter);
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
};

View file

@ -152,7 +152,7 @@ struct FileSystem::LumpRecord
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void PrintLastError ();
static void PrintLastError (FileSystemMessageFunc Printf);
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -162,7 +162,7 @@ FileSystem fileSystem;
FileSystem::FileSystem()
{
// This is needed to initialize the LumpRecord array, which depends on data only available here.
// Cannot be defaulted! This is needed to initialize the LumpRecord array, which depends on data only available here.
}
FileSystem::~FileSystem ()
@ -199,14 +199,14 @@ void FileSystem::DeleteAll ()
//
//==========================================================================
void FileSystem::InitSingleFile(const char* filename, bool quiet)
bool FileSystem::InitSingleFile(const char* filename, FileSystemMessageFunc Printf)
{
TArray<FString> filenames;
filenames.Push(filename);
InitMultipleFiles(filenames, true);
return InitMultipleFiles(filenames, nullptr, Printf);
}
void FileSystem::InitMultipleFiles (TArray<FString> &filenames, bool quiet, LumpFilterInfo* filter, bool allowduplicates, FILE* hashfile)
bool FileSystem::InitMultipleFiles (TArray<FString> &filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates, FILE* hashfile)
{
int numfiles;
@ -232,7 +232,7 @@ void FileSystem::InitMultipleFiles (TArray<FString> &filenames, bool quiet, Lump
for(unsigned i=0;i<filenames.Size(); i++)
{
AddFile (filenames[i], nullptr, quiet, filter, hashfile);
AddFile (filenames[i], nullptr, filter, Printf, hashfile);
if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/");
FStringf path("filter/%s", Files.Last()->GetHash().GetChars());
@ -242,13 +242,13 @@ void FileSystem::InitMultipleFiles (TArray<FString> &filenames, bool quiet, Lump
NumEntries = FileInfo.Size();
if (NumEntries == 0)
{
if (!quiet) I_FatalError("W_InitMultipleFiles: no files found");
else return;
return false;
}
if (filter && filter->postprocessFunc) filter->postprocessFunc();
// [RH] Set up hash table
InitHashChains ();
return true;
}
//==========================================================================
@ -308,7 +308,7 @@ int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, in
// [RH] Removed reload hack
//==========================================================================
void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, LumpFilterInfo* filter, FILE* hashfile)
void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile)
{
int startlump;
bool isdir = false;
@ -319,10 +319,10 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L
// Does this exist? If so, is it a directory?
if (!DirEntryExists(filename, &isdir))
{
if (!quiet)
if (Printf)
{
Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename);
PrintLastError();
Printf(FSMessageLevel::Error, "%s: File or Directory not found\n", filename);
PrintLastError(Printf);
}
return;
}
@ -331,10 +331,10 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L
{
if (!filereader.OpenFile(filename))
{ // Didn't find file
if (!quiet)
if (Printf)
{
Printf(TEXTCOLOR_RED "%s: File not found\n", filename);
PrintLastError();
Printf(FSMessageLevel::Error, "%s: File not found\n", filename);
PrintLastError(Printf);
}
return;
}
@ -342,19 +342,20 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L
}
else filereader = std::move(*filer);
if (!batchrun && !quiet) Printf (" adding %s", filename);
startlump = NumEntries;
FResourceFile *resfile;
if (!isdir)
resfile = FResourceFile::OpenResourceFile(filename, filereader, quiet, false, filter);
resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf);
else
resfile = FResourceFile::OpenDirectory(filename, quiet, filter);
resfile = FResourceFile::OpenDirectory(filename, filter, Printf);
if (resfile != NULL)
{
if (!quiet && !batchrun) Printf(", %d lumps\n", resfile->LumpCount());
if (!batchrun && Printf)
Printf(FSMessageLevel::Message, "adding %s, %d lumps\n", filename, resfile->LumpCount());
uint32_t lumpstart = FileInfo.Size();
@ -376,11 +377,11 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, bool quiet, L
FString path;
path.Format("%s:%s", filename, lump->getName());
auto embedded = lump->NewReader();
AddFile(path, &embedded, quiet, filter, hashfile);
AddFile(path, &embedded, filter, Printf, hashfile);
}
}
if (hashfile && !quiet)
if (hashfile)
{
uint8_t cksum[16];
char cksumout[33];
@ -1647,7 +1648,7 @@ __declspec(dllimport) void * __stdcall LocalFree (void *);
__declspec(dllimport) unsigned long __stdcall GetLastError ();
}
static void PrintLastError ()
static void PrintLastError (FileSystemMessageFunc Printf)
{
char *lpMsgBuf;
FormatMessageA(0x1300 /*FORMAT_MESSAGE_ALLOCATE_BUFFER |
@ -1660,14 +1661,14 @@ static void PrintLastError ()
0,
NULL
);
Printf (TEXTCOLOR_RED " %s\n", lpMsgBuf);
Printf (FSMessageLevel::Error, " %s\n", lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
}
#else
static void PrintLastError ()
static void PrintLastError (FileSystemMessageFunc Printf)
{
Printf (TEXTCOLOR_RED " %s\n", strerror(errno));
Printf(FSMessageLevel::Error, " %s\n", strerror(errno));
}
#endif
@ -1681,21 +1682,3 @@ FResourceLump* FileSystem::GetFileAt(int no)
{
return FileInfo[no].lump;
}
#include "c_dispatch.h"
CCMD(fs_dir)
{
int numfiles = fileSystem.GetNumEntries();
for (int i = 0; i < numfiles; i++)
{
auto container = fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i));
auto fn1 = fileSystem.GetFileFullName(i);
auto fns = fileSystem.GetFileShortName(i);
auto fnid = fileSystem.GetResourceId(i);
auto length = fileSystem.FileLength(i);
bool hidden = fileSystem.FindFile(fn1) != i;
Printf(PRINT_HIGH | PRINT_NONOTIFY, "%s%-64s %-15s (%5d) %10d %s %s\n", hidden ? TEXTCOLOR_RED : TEXTCOLOR_UNTRANSLATED, fn1, fns, fnid, length, container, hidden ? "(h)" : "");
}
}

View file

@ -57,7 +57,7 @@ struct FolderEntry
class FileSystem
{
public:
FileSystem ();
FileSystem();
~FileSystem ();
// The wadnum for the IWAD
@ -67,9 +67,9 @@ public:
int GetMaxIwadNum() { return MaxIwadIndex; }
void SetMaxIwadNum(int x) { MaxIwadIndex = x; }
void InitSingleFile(const char *filename, bool quiet = false);
void InitMultipleFiles (TArray<FString> &filenames, bool quiet = false, LumpFilterInfo* filter = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr);
void AddFile (const char *filename, FileReader *wadinfo, bool quiet, LumpFilterInfo* filter, FILE* hashfile);
bool InitSingleFile(const char *filename, FileSystemMessageFunc Printf = nullptr);
bool InitMultipleFiles (TArray<FString> &filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr);
void AddFile (const char *filename, FileReader *wadinfo, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile);
int CheckIfResourceFileLoaded (const char *name) noexcept;
void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {}

View file

@ -223,46 +223,54 @@ int FResourceLump::Unlock()
//
//==========================================================================
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckLump(const char *filename,FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosub, LumpFilterInfo* filter);
FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckLump };
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckWHRes, CheckLump };
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter)
static int nulPrintf(FSMessageLevel msg, const char* fmt, ...)
{
return 0;
}
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
if (Printf == nullptr) Printf = nulPrintf;
for(size_t i = 0; i < countof(funcs) - containeronly; i++)
{
FResourceFile *resfile = funcs[i](filename, file, quiet, filter);
FResourceFile *resfile = funcs[i](filename, file, filter, Printf);
if (resfile != NULL) return resfile;
}
return NULL;
}
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter)
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
return DoOpenResourceFile(filename, file, quiet, containeronly, filter);
return DoOpenResourceFile(filename, file, containeronly, filter, Printf);
}
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool quiet, bool containeronly, LumpFilterInfo* filter)
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
FileReader file;
if (!file.OpenFile(filename)) return nullptr;
return DoOpenResourceFile(filename, file, quiet, containeronly, filter);
return DoOpenResourceFile(filename, file, containeronly, filter, Printf);
}
FResourceFile *FResourceFile::OpenDirectory(const char *filename, bool quiet, LumpFilterInfo* filter)
FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf)
{
return CheckDir(filename, quiet, false, filter);
if (Printf == nullptr) Printf = nulPrintf;
return CheckDir(filename, false, filter, Printf);
}
//==========================================================================

View file

@ -8,6 +8,7 @@
#include "files.h"
#include "zstring.h"
// user context in which the file system gets opened. This also contains a few callbacks to avoid direct dependencies on the engine.
struct LumpFilterInfo
{
TArray<FString> gameTypeFilter; // this can contain multiple entries
@ -20,6 +21,20 @@ struct LumpFilterInfo
std::function<void()> postprocessFunc;
};
enum class FSMessageLevel
{
Error = 1,
Warning = 2,
Attention = 3,
Message = 4,
DebugWarn = 5,
DebugNotify = 6,
};
// pass the text output function as parameter to avoid a hard dependency on higher level code.
using FileSystemMessageFunc = int(*)(FSMessageLevel msglevel, const char* format, ...);
class FResourceFile;
// [RH] Namespaces from BOOM.
@ -151,12 +166,12 @@ private:
int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max);
bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end);
void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max);
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter);
static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf);
public:
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, bool quiet = false, bool containeronly = false, LumpFilterInfo* filter = nullptr);
static FResourceFile *OpenDirectory(const char *filename, bool quiet = false, LumpFilterInfo* filter = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr);
virtual ~FResourceFile();
// If this FResourceFile represents a directory, the Reader object is not usable so don't return it.
FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; }

View file

@ -119,6 +119,20 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, GetNumAxes)
ACTION_RETURN_INT(self->GetNumAxes());
}
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetEnabled)
{
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
ACTION_RETURN_BOOL(self->GetEnabled());
}
DEFINE_ACTION_FUNCTION(IJoystickConfig, SetEnabled)
{
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
PARAM_BOOL(enabled);
self->SetEnabled(enabled);
return 0;
}
void UpdateJoystickMenu(IJoystickConfig *selected)
{

View file

@ -104,6 +104,9 @@ public:
virtual bool IsAxisMapDefault(int axis);
virtual bool IsAxisScaleDefault(int axis);
virtual bool GetEnabled();
virtual void SetEnabled(bool enabled);
virtual void SetDefaultConfig();
virtual FString GetIdentifier();
@ -165,6 +168,7 @@ private:
TArray<DigitalButton> m_buttons;
TArray<DigitalButton> m_POVs;
bool m_enabled;
bool m_useAxesPolling;
io_object_t m_notification;
@ -279,6 +283,7 @@ IOKitJoystick::IOKitJoystick(const io_object_t device)
: m_interface(CreateDeviceInterface(device))
, m_queue(CreateDeviceQueue(m_interface))
, m_sensitivity(DEFAULT_SENSITIVITY)
, m_enabled(true)
, m_useAxesPolling(true)
, m_notification(0)
{
@ -430,6 +435,17 @@ bool IOKitJoystick::IsAxisScaleDefault(int axis)
: true;
}
bool IOKitJoystick::GetEnabled()
{
return m_enabled;
}
void IOKitJoystick::SetEnabled(bool enabled)
{
m_enabled = enabled;
}
#undef IS_AXIS_VALID
void IOKitJoystick::SetDefaultConfig()
@ -547,7 +563,7 @@ void IOKitJoystick::Update()
if (kIOReturnSuccess == eventResult)
{
if (use_joystick)
if (use_joystick && m_enabled)
{
ProcessAxis(event) || ProcessButton(event) || ProcessPOV(event);
}
@ -557,7 +573,7 @@ void IOKitJoystick::Update()
Printf(TEXTCOLOR_RED "IOHIDQueueInterface::getNextEvent() failed with code 0x%08X\n", eventResult);
}
ProcessAxes();
if(m_enabled) ProcessAxes();
}

View file

@ -44,7 +44,7 @@
class SDLInputJoystick: public IJoystickConfig
{
public:
SDLInputJoystick(int DeviceIndex) : DeviceIndex(DeviceIndex), Multiplier(1.0f)
SDLInputJoystick(int DeviceIndex) : DeviceIndex(DeviceIndex), Multiplier(1.0f) , Enabled(true)
{
Device = SDL_JoystickOpen(DeviceIndex);
if(Device != NULL)
@ -154,6 +154,17 @@ public:
Axes.Push(info);
}
}
bool GetEnabled()
{
return Enabled;
}
void SetEnabled(bool enabled)
{
Enabled = enabled;
}
FString GetIdentifier()
{
char id[16];
@ -248,9 +259,12 @@ protected:
SDL_Joystick *Device;
float Multiplier;
bool Enabled;
TArray<AxisInfo> Axes;
int NumAxes;
int NumHats;
friend class SDLInputJoystickManager;
};
const EJoyAxis SDLInputJoystick::DefaultAxes[5] = {JOYAXIS_Side, JOYAXIS_Forward, JOYAXIS_Pitch, JOYAXIS_Yaw, JOYAXIS_Up};
@ -291,7 +305,7 @@ public:
void ProcessInput() const
{
for(unsigned int i = 0;i < Joysticks.Size();++i)
Joysticks[i]->ProcessInput();
if(Joysticks[i]->Enabled) Joysticks[i]->ProcessInput();
}
protected:
TArray<SDLInputJoystick *> Joysticks;

View file

@ -257,6 +257,7 @@ bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
struct timeval tv;
int retval;
char k;
bool stdin_eof = false;
for (;;)
{
@ -265,7 +266,10 @@ bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
tv.tv_usec = 500000;
FD_ZERO (&rfds);
FD_SET (STDIN_FILENO, &rfds);
if (!stdin_eof)
{
FD_SET (STDIN_FILENO, &rfds);
}
retval = select (1, &rfds, NULL, NULL, &tv);
@ -281,13 +285,21 @@ bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata)
return true;
}
}
else if (read (STDIN_FILENO, &k, 1) == 1)
else
{
// Check input on stdin
if (k == 'q' || k == 'Q')
ssize_t amt = read (STDIN_FILENO, &k, 1); // Check input on stdin
if (amt == 0)
{
fprintf (stderr, "\nNetwork game synchronization aborted.");
return false;
// EOF. Stop reading
stdin_eof = true;
}
else if (amt == 1)
{
if (k == 'q' || k == 'Q')
{
fprintf (stderr, "\nNetwork game synchronization aborted.");
return false;
}
}
}
}

View file

@ -180,6 +180,9 @@ public:
bool IsAxisMapDefault(int axis);
bool IsAxisScaleDefault(int axis);
bool GetEnabled();
void SetEnabled(bool enabled);
void SetDefaultConfig();
FString GetIdentifier();
@ -219,6 +222,8 @@ protected:
DIOBJECTDATAFORMAT *Objects;
DIDATAFORMAT DataFormat;
bool Enabled;
static BOOL CALLBACK EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
void OrderAxes();
bool ReorderAxisPair(const GUID &x, const GUID &y, int pos);
@ -297,6 +302,7 @@ FDInputJoystick::FDInputJoystick(const GUID *instance, FString &name)
Instance = *instance;
Name = name;
Marked = false;
Enabled = true;
}
//===========================================================================
@ -410,7 +416,7 @@ void FDInputJoystick::ProcessInput()
{
hr = Device->Acquire();
}
if (FAILED(hr))
if (FAILED(hr) || !Enabled)
{
return;
}
@ -984,6 +990,28 @@ bool FDInputJoystick::IsAxisScaleDefault(int axis)
return true;
}
//===========================================================================
//
// FDInputJoystick :: GetEnabled
//
//===========================================================================
bool FDInputJoystick::GetEnabled()
{
return Enabled;
}
//===========================================================================
//
// FDInputJoystick :: SetEnabled
//
//===========================================================================
void FDInputJoystick::SetEnabled(bool enabled)
{
Enabled = enabled;
}
//===========================================================================
//
// FDInputJoystick :: IsAxisMapDefault

View file

@ -115,7 +115,7 @@ protected:
void PostKeyEvent(int keynum, INTBOOL down, bool foreground);
};
class NOVTABLE FJoystickCollection : public FInputDevice
class FJoystickCollection : public FInputDevice
{
public:
virtual void AddAxes(float axes[NUM_JOYAXIS]) = 0;

View file

@ -114,6 +114,9 @@ public:
bool IsAxisMapDefault(int axis);
bool IsAxisScaleDefault(int axis);
bool GetEnabled();
void SetEnabled(bool enabled);
void SetDefaultConfig();
FString GetIdentifier();
@ -153,6 +156,7 @@ protected:
bool Connected;
bool Marked;
bool Active;
bool Enabled;
void Attached();
void Detached();
@ -376,6 +380,7 @@ FRawPS2Controller::FRawPS2Controller(HANDLE handle, EAdapterType type, int seque
ControllerNumber = controller;
Sequence = sequence;
DeviceID = devid;
Enabled = true;
// The EMS USB2 controller provides attachment status. The others do not.
Connected = (Descriptors[type].ControllerStatus < 0);
@ -849,6 +854,28 @@ bool FRawPS2Controller::IsAxisScaleDefault(int axis)
return true;
}
//===========================================================================
//
// FRawPS2Controller :: GetEnabled
//
//===========================================================================
bool FRawPS2Controller::GetEnabled()
{
return Enabled;
}
//===========================================================================
//
// FRawPS2Controller :: SetEnabled
//
//===========================================================================
void FRawPS2Controller::SetEnabled(bool enabled)
{
Enabled = enabled;
}
//===========================================================================
//
// FRawPS2Controller :: IsAxisMapDefault
@ -972,7 +999,7 @@ bool FRawPS2Manager::ProcessRawInput(RAWINPUT *raw, int code)
{
if (Devices[i]->Handle == raw->header.hDevice)
{
if (Devices[i]->ProcessInput(&raw->data.hid, code))
if (Devices[i]->Enabled && Devices[i]->ProcessInput(&raw->data.hid, code))
{
return true;
}

View file

@ -102,6 +102,9 @@ public:
bool IsAxisMapDefault(int axis);
bool IsAxisScaleDefault(int axis);
bool GetEnabled();
void SetEnabled(bool enabled);
void SetDefaultConfig();
FString GetIdentifier();
@ -138,6 +141,7 @@ protected:
DWORD LastPacketNumber;
int LastButtons;
bool Connected;
bool Enabled;
void Attached();
void Detached();
@ -221,6 +225,7 @@ FXInputController::FXInputController(int index)
{
Index = index;
Connected = false;
Enabled = true;
M_LoadJoystickConfig(this);
}
@ -269,7 +274,7 @@ void FXInputController::ProcessInput()
{
Attached();
}
if (state.dwPacketNumber == LastPacketNumber)
if (state.dwPacketNumber == LastPacketNumber || !Enabled)
{ // Nothing has changed since last time.
return;
}
@ -628,6 +633,28 @@ bool FXInputController::IsAxisScaleDefault(int axis)
return true;
}
//===========================================================================
//
// FXInputController :: GetEnabled
//
//===========================================================================
bool FXInputController::GetEnabled()
{
return Enabled;
}
//===========================================================================
//
// FXInputController :: SetEnabled
//
//===========================================================================
void FXInputController::SetEnabled(bool enabled)
{
Enabled = enabled;
}
//===========================================================================
//
// FXInputController :: IsAxisMapDefault

View file

@ -19,7 +19,6 @@ EXTERN_CVAR (Bool, gl_light_raytrace);
EXTERN_CVAR (Int, gl_shadowmap_quality);
EXTERN_CVAR(Int, gl_fogmode)
EXTERN_CVAR(Int, gl_lightmode)
EXTERN_CVAR(Bool,gl_mirror_envmap)
EXTERN_CVAR(Bool,gl_mirrors)

View file

@ -34,7 +34,7 @@
**
*/
#include "vectors.h" // RAD2DEG
#include "vectors.h"
#include "hw_cvars.h"
#include "hw_vrmodes.h"
#include "v_video.h"
@ -67,6 +67,16 @@ static VRMode vrmi_righteye = { 1, 1.f, 1.f, 1.f,{ { .5f, 1.f },{ 0.f, 0.f } } }
static VRMode vrmi_topbottom = { 2, 1.f, .5f, 1.f,{ { -.5f, 1.f },{ .5f, 1.f } } };
static VRMode vrmi_checker = { 2, isqrt2, isqrt2, 1.f,{ { -.5f, 1.f },{ .5f, 1.f } } };
static float DEG2RAD(float deg)
{
return deg * float(M_PI / 180.0);
}
static float RAD2DEG(float rad)
{
return rad * float(180. / M_PI);
}
const VRMode *VRMode::GetVRMode(bool toscreen)
{
int mode = !toscreen || (sysCallbacks.DisableTextureFilter && sysCallbacks.DisableTextureFilter()) ? 0 : vr_mode;

View file

@ -1,5 +1,8 @@
#pragma once
#include "zstring.h"
#include "tarray.h"
enum class PostProcessUniformType
{
Undefined,

View file

@ -113,7 +113,7 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
}
else
{
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
VkFormat format = tex->IsHDR() ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM;
int w = tex->GetWidth();
int h = tex->GetHeight();

View file

@ -277,7 +277,8 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
// null pointers can be assigned to everything, everything can be assigned to void pointers.
if (fromtype == nullptr || totype == TypeVoidPtr) return true;
// when comparing const-ness does not matter.
if (!forcompare && totype->IsConst != fromtype->IsConst) return false;
// If not comparing, then we should not allow const to be cast away.
if (!forcompare && fromtype->IsConst && !totype->IsConst) return false;
// A type is always compatible to itself.
if (fromtype == totype) return true;
// Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type.
@ -4793,7 +4794,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
}
else
{
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject)), false);
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject), true), false);
ClassCheck = false;
}
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right, false);
@ -8858,7 +8859,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
}
}
if (Self->ValueType->isRealPointer())
if (Self->ValueType->isRealPointer() && Self->ValueType->toPointer()->PointedType)
{
auto ptype = Self->ValueType->toPointer()->PointedType;
cls = ptype->toContainer();
@ -9151,7 +9152,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
// [Player701] Catch attempts to call abstract functions directly at compile time
if (NoVirtual && Function->Variants[0].Implementation->VarFlags & VARF_Abstract)
{
ScriptPosition.Message(MSG_ERROR, "Cannot call abstract function %s", Function->Variants[0].Implementation->PrintableName.GetChars());
ScriptPosition.Message(MSG_ERROR, "Cannot call abstract function %s", Function->Variants[0].Implementation->PrintableName);
delete this;
return nullptr;
}

View file

@ -348,8 +348,8 @@ public:
bool IsQuaternion() const { return ValueType == TypeQuaternion || ValueType == TypeFQuaternion || ValueType == TypeQuaternionStruct; };
bool IsBoolCompat() const { return ValueType->isScalar(); }
bool IsObject() const { return ValueType->isObjectPointer(); }
bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType->isArray()); }
bool isStaticArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType->isStaticArray()); } // can only exist in pointer form.
bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType && ValueType->toPointer()->PointedType->isArray()); }
bool isStaticArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType && ValueType->toPointer()->PointedType->isStaticArray()); } // can only exist in pointer form.
bool IsDynamicArray() const { return (ValueType->isDynArray()); }
bool IsMap() const { return ValueType->isMap(); }
bool IsMapIterator() const { return ValueType->isMapIterator(); }

View file

@ -790,7 +790,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo
it.PrintableName = name;
it.Function = new VMScriptFunction;
it.Function->Name = functype->SymbolName;
it.Function->PrintableName = name;
it.Function->QualifiedName = it.Function->PrintableName = ClassDataAllocator.Strdup(name);
it.Function->ImplicitArgs = functype->GetImplicitArgs();
it.Proto = nullptr;
it.FromDecorate = fromdecorate;

View file

@ -198,7 +198,8 @@ void InitImports()
{
assert(afunc->VMPointer != NULL);
*(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName);
(*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName);
(*(afunc->VMPointer))->QualifiedName = ClassDataAllocator.Strdup(FStringf("%s.%s", afunc->ClassName + 1, afunc->FuncName));
(*(afunc->VMPointer))->PrintableName = ClassDataAllocator.Strdup(FStringf("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName));
(*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative;
AFTable.Push(*afunc);
});

View file

@ -221,5 +221,5 @@ void FScopeBarrier::ValidateCall(PClass* selftype, VMFunction *calledfunc, int o
{
int innerside = FScopeBarrier::SideFromObjectFlags(selftype->VMType->ScopeFlags);
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData))
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->PrintableName.GetChars(), FScopeBarrier::StringFromSide(outerside));
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->PrintableName, FScopeBarrier::StringFromSide(outerside));
}

View file

@ -9,6 +9,16 @@ class PPrototype;
struct ZCC_TreeNode;
class PContainerType;
// This is needed in common code, despite being Doom specific.
enum EStateUseFlags
{
SUF_ACTOR = 1,
SUF_OVERLAY = 2,
SUF_WEAPON = 4,
SUF_ITEM = 8,
};
// Symbol information -------------------------------------------------------
class PTypeBase

View file

@ -528,7 +528,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
}
else if (code[i].op == OP_CALL_K && callfunc)
{
printf_wrapper(out, " [%s]\n", callfunc->PrintableName.GetChars());
printf_wrapper(out, " [%s]\n", callfunc->PrintableName);
}
else
{

View file

@ -2798,7 +2798,7 @@ void ZCCCompiler::InitFunctions()
{
if (v->VarFlags & VARF_Abstract)
{
Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName.GetChars());
Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName);
}
}
}

View file

@ -15,7 +15,7 @@ static void OutputJitLog(const asmjit::StringLogger &logger);
JitFuncPtr JitCompile(VMScriptFunction *sfunc)
{
#if 0
if (strcmp(sfunc->PrintableName.GetChars(), "StatusScreen.drawNum") != 0)
if (strcmp(sfunc->PrintableName, "StatusScreen.drawNum") != 0)
return nullptr;
#endif
@ -35,7 +35,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
catch (const CRecoverableError &e)
{
OutputJitLog(logger);
Printf("%s: Unexpected JIT error: %s\n",sfunc->PrintableName.GetChars(), e.what());
Printf("%s: Unexpected JIT error: %s\n",sfunc->PrintableName, e.what());
return nullptr;
}
}
@ -237,7 +237,7 @@ void JitCompiler::Setup()
cc.comment(marks, 56);
FString funcname;
funcname.Format("Function: %s", sfunc->PrintableName.GetChars());
funcname.Format("Function: %s", sfunc->PrintableName);
cc.comment(funcname.GetChars(), funcname.Len());
cc.comment(marks, 56);
@ -364,7 +364,7 @@ void JitCompiler::SetupSimpleFrame()
if (errorDetails)
{
I_FatalError("JIT: inconsistent number of %s for function %s", errorDetails, sfunc->PrintableName.GetChars());
I_FatalError("JIT: inconsistent number of %s for function %s", errorDetails, sfunc->PrintableName);
}
for (int i = regd; i < sfunc->NumRegD; i++)

View file

@ -97,7 +97,7 @@ void JitCompiler::EmitVMCall(asmjit::X86Gp vmfunc, VMFunction *target)
call->setArg(2, Imm(B));
call->setArg(3, GetCallReturns());
call->setArg(4, Imm(C));
call->setInlineComment(target ? target->PrintableName.GetChars() : "VMCall");
call->setInlineComment(target ? target->PrintableName : "VMCall");
LoadInOuts();
LoadReturns(pc + 1, C);
@ -360,7 +360,7 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
asmjit::CBNode *cursorBefore = cc.getCursor();
auto call = cc.call(imm_ptr(target->DirectNativeCall), CreateFuncSignature());
call->setInlineComment(target->PrintableName.GetChars());
call->setInlineComment(target->PrintableName);
asmjit::CBNode *cursorAfter = cc.getCursor();
cc.setCursor(cursorBefore);

View file

@ -306,7 +306,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
if (result == 0)
I_Error("RtlAddFunctionTable failed");
JitDebugInfo.Push({ compiler->GetScriptFunction()->PrintableName, compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr });
JitDebugInfo.Push({ FString(compiler->GetScriptFunction()->PrintableName), compiler->GetScriptFunction()->SourceFileName, compiler->LineInfo, startaddr, endaddr });
#endif
return p;

View file

@ -451,7 +451,8 @@ public:
FName Name;
const uint8_t *RegTypes = nullptr;
TArray<TypedVMValue> DefaultArgs;
FString PrintableName; // so that the VM can print meaningful info if something in this function goes wrong.
const char* QualifiedName = nullptr;
const char* PrintableName = nullptr; // same as QualifiedName, but can have additional annotations.
class PPrototype *Proto;
TArray<uint32_t> ArgFlags; // Should be the same length as Proto->ArgumentTypes

View file

@ -895,7 +895,7 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
catch (CVMAbortException &err)
{
err.MaybePrintMessage();
err.stacktrace.AppendFormat("Called from %s\n", call->PrintableName.GetChars());
err.stacktrace.AppendFormat("Called from %s\n", call->PrintableName);
// PrintParameters(reg.param + f->NumParam - B, B);
throw;
}
@ -2000,7 +2000,7 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
catch (CVMAbortException &err)
{
err.MaybePrintMessage();
err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars(), sfunc->PCToLine(pc));
err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName, sfunc->SourceFileName.GetChars(), sfunc->PCToLine(pc));
// PrintParameters(reg.param + f->NumParam - B, B);
throw;
}

View file

@ -80,7 +80,7 @@ void VMFunction::CreateRegUse()
if (!Proto)
{
//if (RegTypes) return;
//Printf(TEXTCOLOR_ORANGE "Function without prototype needs register info manually set: %s\n", PrintableName.GetChars());
//Printf(TEXTCOLOR_ORANGE "Function without prototype needs register info manually set: %s\n", PrintableName);
return;
}
assert(Proto->isPrototype());
@ -277,7 +277,7 @@ static bool CanJit(VMScriptFunction *func)
if (func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS < maxregs)
return true;
Printf(TEXTCOLOR_ORANGE "%s is using too many registers (%d of max %d)! Function will not use native code.\n", func->PrintableName.GetChars(), func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS, maxregs);
Printf(TEXTCOLOR_ORANGE "%s is using too many registers (%d of max %d)! Function will not use native code.\n", func->PrintableName, func->NumRegA + func->NumRegD + func->NumRegF + func->NumRegS, maxregs);
return false;
}
@ -289,7 +289,7 @@ int VMScriptFunction::FirstScriptCall(VMFunction *func, VMValue *params, int num
// rather than let GZDoom crash.
if (func->VarFlags & VARF_Abstract)
{
ThrowAbortException(X_OTHER, "attempt to call abstract function %s.", func->PrintableName.GetChars());
ThrowAbortException(X_OTHER, "attempt to call abstract function %s.", func->PrintableName);
}
#ifdef HAVE_VM_JIT
if (vm_jit && CanJit(static_cast<VMScriptFunction*>(func)))
@ -320,7 +320,7 @@ int VMNativeFunction::NativeScriptCall(VMFunction *func, VMValue *params, int nu
catch (CVMAbortException &err)
{
err.MaybePrintMessage();
err.stacktrace.AppendFormat("Called from %s\n", func->PrintableName.GetChars());
err.stacktrace.AppendFormat("Called from %s\n", func->PrintableName);
throw;
}
}
@ -702,7 +702,7 @@ void CVMAbortException::MaybePrintMessage()
CVMAbortException err(reason, moreinfo, ap);
err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars(), sfunc->PCToLine(line));
err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName, sfunc->SourceFileName.GetChars(), sfunc->PCToLine(line));
throw err;
}

View file

@ -0,0 +1,213 @@
/*
** qoitexture.cpp
** Texture class for QOI (Quite OK Image Format) images
**
**---------------------------------------------------------------------------
** Copyright 2023 Cacodemon345
** Copyright 2022 Dominic Szablewski
** All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
**---------------------------------------------------------------------------
**
**
*/
#include "files.h"
#include "filesystem.h"
#include "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
#pragma pack(1)
struct QOIHeader
{
char magic[4];
uint32_t width;
uint32_t height;
uint8_t channels;
uint8_t colorspace;
};
#pragma pack()
class FQOITexture : public FImageSource
{
public:
FQOITexture(int lumpnum, QOIHeader& header);
PalettedPixels CreatePalettedPixels(int conversion) override;
int CopyPixels(FBitmap *bmp, int conversion) override;
};
FImageSource *QOIImage_TryCreate(FileReader &file, int lumpnum)
{
QOIHeader header;
if (file.GetLength() < (sizeof(header) + 8))
{
return nullptr;
}
file.Seek(0, FileReader::SeekSet);
file.Read((void *)&header, sizeof(header));
if (header.magic[0] != 'q' || header.magic[1] != 'o' || header.magic[2] != 'i' || header.magic[3] != 'f')
{
return nullptr;
}
if (header.width == 0 || header.height == 0 || header.channels < 3 || header.channels > 4 || header.colorspace > 1)
{
return nullptr;
}
return new FQOITexture(lumpnum, header);
}
FQOITexture::FQOITexture(int lumpnum, QOIHeader& header)
: FImageSource(lumpnum)
{
LeftOffset = TopOffset = 0;
Width = header.width;
Height = header.height;
if (header.channels == 3) bMasked = bTranslucent = false;
}
PalettedPixels FQOITexture::CreatePalettedPixels(int conversion)
{
FBitmap bitmap;
bitmap.Create(Width, Height);
CopyPixels(&bitmap, conversion);
const uint8_t *data = bitmap.GetPixels();
uint8_t *dest_p;
int dest_adv = Height;
int dest_rew = Width * Height - 1;
PalettedPixels Pixels(Width * Height);
dest_p = Pixels.Data();
bool doalpha = conversion == luminance;
// Convert the source image from row-major to column-major format and remap it
for (int y = Height; y != 0; --y)
{
for (int x = Width; x != 0; --x)
{
int b = *data++;
int g = *data++;
int r = *data++;
int a = *data++;
if (a < 128)
*dest_p = 0;
else
*dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b);
dest_p += dest_adv;
}
dest_p -= dest_rew;
}
return Pixels;
}
int FQOITexture::CopyPixels(FBitmap *bmp, int conversion)
{
enum
{
QOI_OP_INDEX = 0x00, /* 00xxxxxx */
QOI_OP_DIFF = 0x40, /* 01xxxxxx */
QOI_OP_LUMA = 0x80, /* 10xxxxxx */
QOI_OP_RUN = 0xc0, /* 11xxxxxx */
QOI_OP_RGB = 0xfe, /* 11111110 */
QOI_OP_RGBA = 0xff, /* 11111111 */
QOI_MASK_2 = 0xc0, /* 11000000 */
};
constexpr auto QOI_COLOR_HASH = [](PalEntry C) { return (C.r * 3 + C.g * 5 + C.b * 7 + C.a * 11); };
auto lump = fileSystem.OpenFileReader(SourceLump);
auto bytes = lump.Read();
if (bytes.Size() < 22) return 0; // error
PalEntry index[64] = {};
PalEntry pe = 0xff000000;
size_t p = 14, run = 0;
size_t chunks_len = bytes.Size() - 8;
for (int h = 0; h < Height; h++)
{
auto pixels = bmp->GetPixels() + h * bmp->GetPitch();
for (int w = 0; w < Width; w++)
{
if (run > 0)
{
run--;
}
else if (p < chunks_len)
{
int b1 = bytes[p++];
if (b1 == QOI_OP_RGB)
{
pe.r = bytes[p++];
pe.g = bytes[p++];
pe.b = bytes[p++];
}
else if (b1 == QOI_OP_RGBA)
{
pe.r = bytes[p++];
pe.g = bytes[p++];
pe.b = bytes[p++];
pe.a = bytes[p++];
}
else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX)
{
pe = index[b1];
}
else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF)
{
pe.r += ((b1 >> 4) & 0x03) - 2;
pe.g += ((b1 >> 2) & 0x03) - 2;
pe.b += (b1 & 0x03) - 2;
}
else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA)
{
int b2 = bytes[p++];
int vg = (b1 & 0x3f) - 32;
pe.r += vg - 8 + ((b2 >> 4) & 0x0f);
pe.g += vg;
pe.b += vg - 8 + (b2 & 0x0f);
}
else if ((b1 & QOI_MASK_2) == QOI_OP_RUN)
{
run = (b1 & 0x3f);
}
index[QOI_COLOR_HASH(pe) % 64] = pe;
}
}
pixels[0] = pe.b;
pixels[1] = pe.g;
pixels[2] = pe.r;
pixels[3] = pe.a;
pixels += 4;
}
return bMasked? -1 : 0;
}

View file

@ -322,6 +322,7 @@ FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum);
FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum);
FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum);
FImageSource *StbImage_TryCreate(FileReader &, int lumpnum);
FImageSource *QOIImage_TryCreate(FileReader &, int lumpnum);
FImageSource *AnmImage_TryCreate(FileReader &, int lumpnum);
FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum);
FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum);
@ -342,6 +343,7 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat)
{ DDSImage_TryCreate, false },
{ PCXImage_TryCreate, false },
{ StbImage_TryCreate, false },
{ QOIImage_TryCreate, false },
{ TGAImage_TryCreate, false },
{ AnmImage_TryCreate, false },
{ StartupPageImage_TryCreate, false },

View file

@ -217,6 +217,7 @@ protected:
bool Masked = false; // Texture (might) have holes
bool bHasCanvas = false;
bool bHdr = false; // only canvas textures for now.
int8_t bTranslucent = -1;
int8_t areacount = 0; // this is capped at 4 sections.
@ -253,6 +254,8 @@ public:
bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later.
bool isCanvas() const { return bHasCanvas; }
bool IsHDR() const { return bHdr; }
int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method.
void SetSourceLump(int sl) { SourceLump = sl; }
bool FindHoles(const unsigned char * buffer, int w, int h);
@ -345,6 +348,12 @@ public:
float aspectRatio;
friend struct FCanvasTextureInfo;
friend class FTextureAnimator;
private:
void SetHDR(bool hdr) {
bHdr = hdr;
}
};

View file

@ -36,6 +36,7 @@
*/
#include <time.h>
#include <string.h>
#include "common/engine/printf.h"
#include "discord_rpc.h"

21
src/common/thirdparty/stb/stb_sprintf.c vendored Normal file
View file

@ -0,0 +1,21 @@
#define STB_SPRINTF_IMPLEMENTATION
#define STB_SPRINTF_UTF8_CHARS
#include "stb_sprintf.h"
// We still need our own wrappers because they use a size_t for count, not an int.
int mysnprintf(char* buf, size_t count, char const* fmt, ...)
{
int result;
va_list va;
va_start(va, fmt);
result = stbsp_vsnprintf(buf, (int)count, fmt, va);
va_end(va);
return result;
}
int myvsnprintf(char* buf, size_t count, const char* fmt, va_list va)
{
return stbsp_vsnprintf(buf, (int)count, fmt, va);
}

1947
src/common/thirdparty/stb/stb_sprintf.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,6 @@
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include "xs_Float.h"
#define MAXWIDTH 12000
#define MAXHEIGHT 5000
@ -22,7 +21,6 @@ typedef int32_t fixed_t;
// the last remnants of tables.h
#define ANGLE_90 (0x40000000)
#define ANGLE_180 (0x80000000)
#define ANGLE_270 (0xc0000000)
#define ANGLE_MAX (0xffffffff)
typedef uint32_t angle_t;
@ -39,14 +37,6 @@ typedef uint32_t angle_t;
#define FORCE_PACKED
#endif
// Todo: get rid of this. Static file name buffers suck.
#ifndef PATH_MAX
#define BMAX_PATH 256
#else
#define BMAX_PATH PATH_MAX
#endif
#ifdef __GNUC__
#define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi)))
#define GCCFORMAT(stri) __attribute__((format(printf,stri,0)))
@ -69,12 +59,6 @@ using INTBOOL = int;
using BITFIELD = uint32_t;
#if defined(_MSC_VER)
#define NOVTABLE __declspec(novtable)
#else
#define NOVTABLE
#endif
// always use our own definition for consistency.
#ifdef M_PI
#undef M_PI
@ -82,46 +66,6 @@ using BITFIELD = uint32_t;
const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h
inline float DEG2RAD(float deg)
{
return deg * float(M_PI / 180.0);
}
inline double DEG2RAD(double deg)
{
return deg * (M_PI / 180.0);
}
inline float RAD2DEG(float rad)
{
return rad * float(180. / M_PI);
}
inline double RAD2DEG(double rad)
{
return rad * (180. / M_PI);
}
inline angle_t RAD2BAM(float rad)
{
return angle_t(xs_RoundToUInt(rad * float(0x80000000u / M_PI)));
}
inline angle_t RAD2BAM(double rad)
{
return angle_t(xs_RoundToUInt(rad * (0x80000000u / M_PI)));
}
// This is needed in common code, despite being Doom specific.
enum EStateUseFlags
{
SUF_ACTOR = 1,
SUF_OVERLAY = 2,
SUF_WEAPON = 4,
SUF_ITEM = 8,
};
using std::min;
using std::max;
using std::clamp;

View file

@ -122,25 +122,6 @@ char *copystring (const char *s)
return b;
}
//==========================================================================
//
// ReplaceString
//
// Do not use in new code.
//
//==========================================================================
void ReplaceString (char **ptr, const char *str)
{
if (*ptr)
{
if (*ptr == str)
return;
delete[] *ptr;
}
*ptr = copystring (str);
}
/*
=============================================================================

View file

@ -54,7 +54,6 @@ struct FScriptPosition;
bool IsNum (const char *str); // [RH] added
char *copystring(const char *s);
void ReplaceString (char **ptr, const char *str);
bool CheckWildcards (const char *pattern, const char *text);

View file

@ -34,8 +34,8 @@
*/
#include "files.h"
// just for 'clamp'
#include "zstring.h"
#include "utf8.h"
#include "stb_sprintf.h"
FILE *myfopen(const char *filename, const char *flags)
@ -472,13 +472,18 @@ long FileWriter::Seek(long offset, int mode)
size_t FileWriter::Printf(const char *fmt, ...)
{
va_list ap;
FString out;
char workbuf[STB_SPRINTF_MIN];
va_list arglist;
va_start(arglist, fmt);
auto r = stbsp_vsprintfcb([](const char* cstr, void* data, int len) -> char*
{
auto fr = (FileWriter*)data;
auto writ = fr->Write(cstr, len);
return writ == (size_t)len? (char*)cstr : nullptr; // abort if writing caused an error.
}, this, workbuf, fmt, arglist);
va_start(ap, fmt);
out.VFormat(fmt, ap);
va_end(ap);
return Write(out.GetChars(), out.Len());
va_end(arglist);
return r;
}
size_t BufferWriter::Write(const void *buffer, size_t len)

View file

@ -43,7 +43,6 @@
#include "files.h"
#include "zstring.h"
#include "cmdlib.h"
//==========================================================================

View file

@ -132,6 +132,13 @@ void* FMemArena::Calloc(size_t size)
return mem;
}
const char* FMemArena::Strdup(const char* str)
{
char* p = (char*)Alloc(strlen(str) + 1);
strcpy(p, str);
return p;
}
//==========================================================================
//
// FMemArena :: FreeAll

View file

@ -45,6 +45,7 @@ public:
void *Alloc(size_t size);
void* Calloc(size_t size);
const char* Strdup(const char*);
void FreeAll();
void FreeAllBlocks();
FString DumpInfo();

View file

@ -1157,3 +1157,17 @@ bool myisupper(int code)
return false;
}
std::wstring WideString(const char* cin)
{
std::wstring buildbuffer;
if (cin)
{
// This is a bit tricky because we need to support both UTF-8 and legacy content in ISO-8859-1 / Windows 1252
// and thanks to user-side string manipulation it can be that a text mixes both.
// To convert the string this uses the same function as all text printing in the engine.
const uint8_t* in = (const uint8_t*)cin;
while (*in) buildbuffer.push_back((wchar_t)GetCharFromString(in));
}
return buildbuffer;
}

View file

@ -18,3 +18,8 @@ int getAlternative(int code);
extern uint16_t win1252map[];
extern uint16_t lowerforupper[65536];
extern uint16_t upperforlower[65536];
// make this only visible on Windows, on other platforms this should not be called.
#ifdef _WIN32
std::wstring WideString(const char*);
#endif

View file

@ -55,7 +55,7 @@ namespace pi
inline constexpr float pif() { return 3.14159265358979323846f; }
}
// optionally use reliable math routines if reproducability across hardware is important., but let this still compile without them.
// optionally use reliable math routines if reproducability across hardware is important, but let this still compile without them.
#if __has_include("math/cmath.h")
#include "math/cmath.h"
#else
@ -1043,44 +1043,9 @@ struct TMatrix3x3
// Construct a rotation matrix about an arbitrary axis.
// (The axis vector must be normalized.)
TMatrix3x3(const Vector3 &axis, double radians)
TMatrix3x3(const Vector3 &axis, double degrees)
: TMatrix3x3(axis, g_sindeg(degrees), g_cosdeg(degrees))
{
double c = g_cos(radians), s = g_sin(radians), t = 1 - c;
/* In comments: A more readable version of the matrix setup.
This was found in Diana Gruber's article "The Mathematics of the
3D Rotation Matrix" at <http://www.makegames.com/3drotation/> and is
attributed to Graphics Gems (Glassner, Academic Press, 1990).
Cells[0][0] = t*axis.X*axis.X + c;
Cells[0][1] = t*axis.X*axis.Y - s*axis.Z;
Cells[0][2] = t*axis.X*axis.Z + s*axis.Y;
Cells[1][0] = t*axis.Y*axis.X + s*axis.Z;
Cells[1][1] = t*axis.Y*axis.Y + c;
Cells[1][2] = t*axis.Y*axis.Z - s*axis.X;
Cells[2][0] = t*axis.Z*axis.X - s*axis.Y;
Cells[2][1] = t*axis.Z*axis.Y + s*axis.X;
Cells[2][2] = t*axis.Z*axis.Z + c;
Outside comments: A faster version with only 10 (not 24) multiplies.
*/
double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z;
double tx, ty, txx, tyy, u, v;
tx = t*axis.X;
Cells[0][0] = vec_t( (txx=tx*axis.X) + c );
Cells[0][1] = vec_t( (u=tx*axis.Y) - sz);
Cells[0][2] = vec_t( (v=tx*axis.Z) + sy);
ty = t*axis.Y;
Cells[1][0] = vec_t( u + sz);
Cells[1][1] = vec_t( (tyy=ty*axis.Y) + c );
Cells[1][2] = vec_t( (u=ty*axis.Z) - sx);
Cells[2][0] = vec_t( v - sy);
Cells[2][1] = vec_t( u + sx);
Cells[2][2] = vec_t( (t-txx-tyy) + c );
}
TMatrix3x3(const Vector3 &axis, double c/*cosine*/, double s/*sine*/)
@ -1106,10 +1071,10 @@ Outside comments: A faster version with only 10 (not 24) multiplies.
TMatrix3x3(const Vector3 &axis, TAngle<vec_t> degrees);
static TMatrix3x3 Rotate2D(double radians)
static TMatrix3x3 Rotate2D(double degrees)
{
double c = g_cos(radians);
double s = g_sin(radians);
double c = g_cosdeg(degrees);
double s = g_sindeg(degrees);
TMatrix3x3 ret;
ret.Cells[0][0] = c; ret.Cells[0][1] = -s; ret.Cells[0][2] = 0;
ret.Cells[1][0] = s; ret.Cells[1][1] = c; ret.Cells[1][2] = 0;
@ -1521,12 +1486,6 @@ inline TAngle<T> absangle(const TAngle<T> &a1, const TAngle<T> &a2)
return fabs(deltaangle(a2, a1));
}
template<class T>
inline TAngle<T> clamp(const TAngle<T> &angle, const TAngle<T> &min, const TAngle<T> &max)
{
return TAngle<T>::fromDeg(clamp(angle.Degrees(), min.Degrees(), max.Degrees()));
}
inline TAngle<double> VecToAngle(double x, double y)
{
return TAngle<double>::fromRad(g_atan2(y, x));

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@
#include "zstring.h"
#include "utf8.h"
#include "stb_sprintf.h"
extern uint16_t lowerforupper[65536];
extern uint16_t upperforlower[65536];
@ -274,25 +275,28 @@ void FString::Format (const char *fmt, ...)
void FString::AppendFormat (const char *fmt, ...)
{
char workbuf[STB_SPRINTF_MIN];
va_list arglist;
va_start (arglist, fmt);
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
stbsp_vsprintfcb(FormatHelper, this, workbuf, fmt, arglist);
va_end (arglist);
}
void FString::VFormat (const char *fmt, va_list arglist)
{
char workbuf[STB_SPRINTF_MIN];
Data()->Release();
Chars = (char *)(FStringData::Alloc(128) + 1);
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
stbsp_vsprintfcb(FormatHelper, this, workbuf, fmt, arglist);
}
void FString::VAppendFormat (const char *fmt, va_list arglist)
{
StringFormat::VWorker (FormatHelper, this, fmt, arglist);
char workbuf[STB_SPRINTF_MIN];
stbsp_vsprintfcb(FormatHelper, this, workbuf, fmt, arglist);
}
int FString::FormatHelper (void *data, const char *cstr, int len)
char* FString::FormatHelper (const char *cstr, void* data, int len)
{
FString *str = (FString *)data;
size_t len1 = str->Len();
@ -302,7 +306,7 @@ int FString::FormatHelper (void *data, const char *cstr, int len)
}
StrCopy (str->Chars + len1, cstr, len);
str->Data()->Len = (unsigned int)(len1 + len);
return len;
return (char*)cstr;
}
FString FString::operator + (const FString &tail) const
@ -1322,19 +1326,6 @@ FString &FString::operator=(const wchar_t *copyStr)
return *this;
}
std::wstring WideString(const char *cin)
{
if (!cin) return L"";
const uint8_t *in = (const uint8_t*)cin;
// This is a bit tricky because we need to support both UTF-8 and legacy content in ISO-8859-1
// and thanks to user-side string manipulation it can be that a text mixes both.
// To convert the string this uses the same function as all text printing in the engine.
TArray<wchar_t> buildbuffer;
while (*in) buildbuffer.Push((wchar_t)GetCharFromString(in));
buildbuffer.Push(0);
return std::wstring(buildbuffer.Data());
}
static HANDLE StringHeap;
const SIZE_T STRING_HEAP_SIZE = 64*1024;
#endif

View file

@ -39,6 +39,7 @@
#include <stddef.h>
#include <string>
#include "tarray.h"
#include "utf8.h"
#ifdef __GNUC__
#define PRINTFISH(x) __attribute__((format(printf, 2, x)))
@ -57,10 +58,6 @@
#define IGNORE_FORMAT_POST
#endif
#ifdef _WIN32
std::wstring WideString(const char *);
#endif
struct FStringData
{
unsigned int Len; // Length of string, excluding terminating null
@ -364,7 +361,7 @@ protected:
void AllocBuffer (size_t len);
void ReallocBuffer (size_t newlen);
static int FormatHelper (void *data, const char *str, int len);
static char* FormatHelper (const char *str, void* data, int len);
static void StrCopy (char *to, const char *from, size_t len);
static void StrCopy (char *to, const FString &from);
@ -431,6 +428,7 @@ public:
};
/*
namespace StringFormat
{
enum
@ -461,6 +459,7 @@ namespace StringFormat
int VWorker (OutputFunc output, void *outputData, const char *fmt, va_list arglist);
int Worker (OutputFunc output, void *outputData, const char *fmt, ...);
};
*/
#undef PRINTFISH

View file

@ -374,14 +374,13 @@ static void ShoveChatStr (const char *str, uint8_t who)
Net_WriteByte (DEM_SAY);
Net_WriteByte (who);
if (!chat_substitution || !DoSubstitution (substBuff, str))
if (chat_substitution && DoSubstitution (substBuff, str))
{
Net_WriteString(MakeUTF8(str));
}
else
{
Net_WriteString(MakeUTF8(substBuff));
str = substBuff.GetChars();
}
Net_WriteString(CleanseString(const_cast<char*>(MakeUTF8(str))));
}
//===========================================================================

View file

@ -308,8 +308,7 @@ FIWadManager::FIWadManager(const char *firstfn, const char *optfn)
fns.Push(firstfn);
if (optfn) fns.Push(optfn);
check.InitMultipleFiles(fns, true);
if (check.GetNumEntries() > 0)
if (check.InitMultipleFiles(fns, nullptr, nullptr))
{
int num = check.CheckNumForName("IWADINFO");
if (num >= 0)
@ -331,7 +330,7 @@ FIWadManager::FIWadManager(const char *firstfn, const char *optfn)
int FIWadManager::ScanIWAD (const char *iwad)
{
FileSystem check;
check.InitSingleFile(iwad, true);
check.InitSingleFile(iwad, nullptr);
mLumpsFound.Resize(mIWadInfos.Size());
@ -390,8 +389,7 @@ int FIWadManager::CheckIWADInfo(const char* fn)
TArray<FString> filenames;
filenames.Push(fn);
check.InitMultipleFiles(filenames, true, &lfi);
if (check.GetNumEntries() > 0)
if (check.InitMultipleFiles(filenames, &lfi, nullptr))
{
int num = check.CheckNumForName("IWADINFO");
if (num >= 0)

View file

@ -1937,8 +1937,7 @@ static FString CheckGameInfo(TArray<FString> & pwads)
GetReserved(lfi);
// Open the entire list as a temporary file system and look for a GAMEINFO lump. The last one will automatically win.
check.InitMultipleFiles(pwads, true, &lfi);
if (check.GetNumEntries() > 0)
if (check.InitMultipleFiles(pwads, &lfi, nullptr))
{
int num = check.CheckNumForName("GAMEINFO");
if (num >= 0)
@ -3044,6 +3043,35 @@ static FILE* D_GetHashFile()
return hashfile;
}
static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...)
{
va_list arg;
va_start(arg, fmt);
FString text;
text.VFormat(fmt, arg);
switch (level)
{
case FSMessageLevel::Error:
return Printf(TEXTCOLOR_RED "%s", text.GetChars());
break;
case FSMessageLevel::Warning:
Printf(TEXTCOLOR_YELLOW "%s", text.GetChars());
break;
case FSMessageLevel::Attention:
Printf(TEXTCOLOR_BLUE "%s", text.GetChars());
break;
case FSMessageLevel::Message:
Printf("%s", text.GetChars());
break;
case FSMessageLevel::DebugWarn:
DPrintf(DMSG_WARNING, "%s", text.GetChars());
break;
case FSMessageLevel::DebugNotify:
DPrintf(DMSG_NOTIFY, "%s", text.GetChars());
break;
}
return text.Len();
}
//==========================================================================
//
// D_InitGame
@ -3132,7 +3160,10 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
bool allowduplicates = Args->CheckParm("-allowduplicates");
auto hashfile = D_GetHashFile();
fileSystem.InitMultipleFiles (allwads, false, &lfi, allowduplicates, hashfile);
if (!fileSystem.InitMultipleFiles(allwads, &lfi, FileSystemPrintf, allowduplicates, hashfile))
{
I_FatalError("FileSystem: no files found");
}
allwads.Clear();
allwads.ShrinkToFit();
SetMapxxFlag();
@ -3928,6 +3959,22 @@ void I_UpdateWindowTitle()
I_SetWindowTitle(copy.Data());
}
CCMD(fs_dir)
{
int numfiles = fileSystem.GetNumEntries();
for (int i = 0; i < numfiles; i++)
{
auto container = fileSystem.GetResourceFileFullName(fileSystem.GetFileContainer(i));
auto fn1 = fileSystem.GetFileFullName(i);
auto fns = fileSystem.GetFileShortName(i);
auto fnid = fileSystem.GetResourceId(i);
auto length = fileSystem.FileLength(i);
bool hidden = fileSystem.FindFile(fn1) != i;
Printf(PRINT_HIGH | PRINT_NONOTIFY, "%s%-64s %-15s (%5d) %10d %s %s\n", hidden ? TEXTCOLOR_RED : TEXTCOLOR_UNTRANSLATED, fn1, fns, fnid, length, container, hidden ? "(h)" : "");
}
}
#ifdef _WIN32
// 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,

View file

@ -1406,7 +1406,6 @@ struct ArbitrateData
bool DoArbitrate (void *userdata)
{
ArbitrateData *data = (ArbitrateData *)userdata;
char *s;
uint8_t *stream;
int version;
int node;
@ -1468,9 +1467,7 @@ bool DoArbitrate (void *userdata)
NetMode = netbuffer[2];
stream = &netbuffer[3];
s = ReadString (&stream);
startmap = s;
delete[] s;
startmap = ReadStringConst(&stream);
rngseed = ReadLong (&stream);
C_ReadCVars (&stream);
}
@ -2166,7 +2163,7 @@ static int RemoveClass(FLevelLocals *Level, const PClass *cls)
void Net_DoCommand (int type, uint8_t **stream, int player)
{
uint8_t pos = 0;
char *s = NULL;
const char* s = nullptr;
int i;
switch (type)
@ -2176,8 +2173,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
const char *name = players[player].userinfo.GetName();
uint8_t who = ReadByte (stream);
s = ReadString (stream);
CleanseString (s);
s = ReadStringConst(stream);
if (((who & 1) == 0) || players[player].userinfo.GetTeam() == TEAM_NONE)
{ // Said to everyone
if (who & 2)
@ -2206,18 +2202,15 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
break;
case DEM_MUSICCHANGE:
s = ReadString (stream);
S_ChangeMusic (s);
S_ChangeMusic(ReadStringConst(stream));
break;
case DEM_PRINT:
s = ReadString (stream);
Printf ("%s", s);
Printf("%s", ReadStringConst(stream));
break;
case DEM_CENTERPRINT:
s = ReadString (stream);
C_MidPrint (nullptr, s);
C_MidPrint(nullptr, ReadStringConst(stream));
break;
case DEM_UINFCHANGED:
@ -2233,7 +2226,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
break;
case DEM_GIVECHEAT:
s = ReadString (stream);
s = ReadStringConst(stream);
cht_Give (&players[player], s, ReadLong (stream));
if (player != consoleplayer)
{
@ -2245,12 +2238,12 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
break;
case DEM_TAKECHEAT:
s = ReadString (stream);
s = ReadStringConst(stream);
cht_Take (&players[player], s, ReadLong (stream));
break;
case DEM_SETINV:
s = ReadString(stream);
s = ReadStringConst(stream);
i = ReadLong(stream);
cht_SetInv(&players[player], s, i, !!ReadByte(stream));
break;
@ -2274,7 +2267,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
/* intentional fall-through */
case DEM_CHANGEMAP:
// Change to another map without disconnecting other players
s = ReadString (stream);
s = ReadStringConst(stream);
// Using LEVEL_NOINTERMISSION tends to throw the game out of sync.
// That was a long time ago. Maybe it works now?
primaryLevel->flags |= LEVEL_CHANGEMAPCHEAT;
@ -2361,7 +2354,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
uint8_t special = 0;
int args[5];
s = ReadString (stream);
s = ReadStringConst(stream);
if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2)
{
angle = ReadWord(stream);
@ -2425,12 +2418,12 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
break;
case DEM_SPRAY:
s = ReadString(stream);
s = ReadStringConst(stream);
SprayDecal(players[player].mo, s);
break;
case DEM_MDK:
s = ReadString(stream);
s = ReadStringConst(stream);
cht_DoMDK(&players[player], s);
break;
@ -2453,11 +2446,8 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
case DEM_SAVEGAME:
if (gamestate == GS_LEVEL)
{
s = ReadString (stream);
savegamefile = s;
delete[] s;
s = ReadString (stream);
savedescription = s;
savegamefile = ReadStringConst(stream);
savedescription = ReadStringConst(stream);
if (player != consoleplayer)
{
// Paths sent over the network will be valid for the system that sent
@ -2525,7 +2515,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
case DEM_RUNNAMEDSCRIPT:
{
s = ReadString(stream);
s = ReadStringConst(stream);
int argn = ReadByte(stream);
RunScript(stream, players[player].mo, -FName(s).GetIndex(), argn & 127, (argn & 128) ? ACS_ALWAYS : 0);
@ -2564,8 +2554,8 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
case DEM_MORPHEX:
{
s = ReadString (stream);
FString msg = cht_Morph (players + player, PClass::FindActor (s), false);
s = ReadStringConst(stream);
FString msg = cht_Morph (players + player, PClass::FindActor(s), false);
if (player == consoleplayer)
{
Printf ("%s\n", msg[0] != '\0' ? msg.GetChars() : "Morph failed.");
@ -2595,7 +2585,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
case DEM_KILLCLASSCHEAT:
{
s = ReadString (stream);
s = ReadStringConst(stream);
int killcount = 0;
PClassActor *cls = PClass::FindActor(s);
@ -2618,7 +2608,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
break;
case DEM_REMOVE:
{
s = ReadString(stream);
s = ReadStringConst(stream);
int removecount = 0;
PClassActor *cls = PClass::FindActor(s);
if (cls != NULL && cls->IsDescendantOf(RUNTIME_CLASS(AActor)))
@ -2702,7 +2692,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
case DEM_NETEVENT:
{
s = ReadString(stream);
s = ReadStringConst(stream);
int argn = ReadByte(stream);
int arg[3] = { 0, 0, 0 };
for (int i = 0; i < 3; i++)
@ -2720,9 +2710,6 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
I_Error ("Unknown net command: %d", type);
break;
}
if (s)
delete[] s;
}
// Used by DEM_RUNSCRIPT, DEM_RUNSCRIPT2, and DEM_RUNNAMEDSCRIPT

View file

@ -317,7 +317,8 @@ CCMD (slot)
}
// [Nash] Option to display the name of the weapon being switched to.
if ((paused || pauseext) || players[consoleplayer].playerstate != PST_LIVE) return;
if ((paused || pauseext) || players[consoleplayer].playerstate != PST_LIVE)
return;
if (SendItemUse != players[consoleplayer].ReadyWeapon && (displaynametags & 2) && StatusBar && SmallFont && SendItemUse)
{
StatusBar->AttachMessage(Create<DHUDMessageFadeOut>(nullptr, SendItemUse->GetTag(),
@ -328,6 +329,8 @@ CCMD (slot)
CCMD (centerview)
{
if ((players[consoleplayer].cheats & CF_TOTALLYFROZEN))
return;
Net_WriteByte (DEM_CENTERVIEW);
}
@ -1972,7 +1975,7 @@ void G_DoLoadGame ()
hidecon = gameaction == ga_loadgamehidecon;
gameaction = ga_nothing;
std::unique_ptr<FResourceFile> resfile(FResourceFile::OpenResourceFile(savename.GetChars(), true, true));
std::unique_ptr<FResourceFile> resfile(FResourceFile::OpenResourceFile(savename.GetChars(), true));
if (resfile == nullptr)
{
LoadGameError("TXT_COULDNOTREAD");

View file

@ -30,6 +30,8 @@
struct event_t;
#include <functional>
#include "dobjgc.h"
#include "name.h"
#include "gamestate.h"

View file

@ -146,17 +146,30 @@ CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL)
}
}
CUSTOM_CVAR(Int, gl_lightmode, 8, CVAR_ARCHIVE | CVAR_NOINITCALL)
CUSTOM_CVAR(Int, gl_maplightmode, -1, CVAR_NOINITCALL) // this is just for testing. -1 means 'inactive'
{
int newself = self;
if (newself > 8) newself = 16; // use 8 and 16 for software lighting to avoid conflicts with the bit mask ( in hindsight a bad idea.)
else if (newself > 5) newself = 8;
else if (newself < 0) newself = 0;
if (self != newself) self = newself;
else for (auto Level : AllLevels())
if (self > 5 || self < -1) self = -1;
}
CUSTOM_CVAR(Int, gl_lightmode, 1, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (self < 0 || self > 2) self = 2;
}
ELightMode getRealLightmode(FLevelLocals* Level, bool for3d)
{
auto lightmode = Level->info->lightmode;
if (lightmode == ELightMode::NotSet)
{
if ((Level->info == nullptr || Level->info->lightmode == ELightMode::NotSet)) Level->lightMode = (ELightMode)*self;
if (gl_maplightmode != -1) lightmode = (ELightMode)*gl_maplightmode;
else lightmode = ELightMode::Doom;
}
if (lightmode == ELightMode::Doom && for3d)
{
if (gl_lightmode == 1) lightmode = ELightMode::ZDoomSoftware;
else if (gl_lightmode == 2) lightmode = ELightMode::DoomSoftware;
}
return lightmode;
}
CVAR(Int, sv_alwaystally, 0, CVAR_SERVERINFO)
@ -1870,7 +1883,6 @@ void FLevelLocals::Init()
DefaultEnvironment = info->DefaultEnvironment;
lightMode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode;
brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog;
lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;

View file

@ -680,7 +680,6 @@ public:
float MusicVolume;
// Hardware render stuff that can either be set via CVAR or MAPINFO
ELightMode lightMode;
bool brightfog;
bool lightadditivesurfaces;
bool notexturefill;
@ -880,3 +879,5 @@ inline TArrayView<FLevelLocals *> AllLevels()
{
return TArrayView<FLevelLocals *>(&primaryLevel, 1);
}
ELightMode getRealLightmode(FLevelLocals* Level, bool for3d);

View file

@ -208,28 +208,13 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
TextColor = textColor;
State = 0;
SourceText = copystring (text);
SourceText = text;
VisibilityFlags = 0;
Style = STYLE_Translucent;
Alpha = 1.;
ResetText (SourceText);
}
//============================================================================
//
// DHUDMessage Destructor
//
//============================================================================
void DHUDMessage::OnDestroy()
{
if (SourceText != NULL)
{
delete[] SourceText;
SourceText = nullptr;
}
}
//============================================================================
//
// DHUDMessage :: Serialize
@ -263,7 +248,7 @@ void DHUDMessage::Serialize(FSerializer &arc)
if (arc.isReading())
{
ResetText(SourceText);
ResetText(SourceText.GetChars());
}
}
@ -277,7 +262,7 @@ void DHUDMessage::ScreenSizeChanged ()
{
if (HUDWidth == 0)
{
ResetText (SourceText);
ResetText (SourceText.GetChars());
}
}

View file

@ -99,7 +99,6 @@ class DHUDMessage : public DHUDMessageBase
public:
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
EColorRange textColor, float holdTime);
virtual void OnDestroy () override;
virtual void Serialize(FSerializer &arc);
@ -125,7 +124,7 @@ public:
void SetNoWrap(bool nowrap)
{
NoWrap = nowrap;
ResetText(SourceText);
ResetText(SourceText.GetChars());
}
void SetClipRect(int x, int y, int width, int height, bool aspect)
{
@ -138,7 +137,7 @@ public:
void SetWrapWidth(int wrap)
{
WrapWidth = wrap;
ResetText(SourceText);
ResetText(SourceText.GetChars());
}
protected:
@ -160,10 +159,10 @@ protected:
double Alpha;
void CalcClipCoords(int hudheight);
DHUDMessage () : SourceText(NULL) {}
DHUDMessage() = default;
private:
char *SourceText;
FString SourceText;
};

View file

@ -598,6 +598,15 @@ void FGameConfigFile::DoGlobalSetup ()
var->SetGenericRep(v, CVAR_Float);
}
}
if (last < 225)
{
if (const auto var = FindCVar("gl_lightmode", NULL))
{
UCVarValue v = var->GetGenericRep(CVAR_Int);
v.Int /= 8; // all legacy modes map to 0, ZDoom software to 1 and Vanilla software to 2.
var->SetGenericRep(v, CVAR_Int);
}
}
}
}
}

View file

@ -1016,7 +1016,7 @@ static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &di
sfunc->NumArgs = numargs;
sfunc->ImplicitArgs = numargs;
state->SetAction(sfunc);
sfunc->PrintableName.Format("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2);
sfunc->PrintableName = ClassDataAllocator.Strdup(FStringf("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2));
disasmdump.Write(sfunc, sfunc->PrintableName);

View file

@ -1522,7 +1522,8 @@ DEFINE_MAP_OPTION(lightmode, false)
parse.ParseAssign();
parse.sc.MustGetNumber();
if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8 || parse.sc.Number == 16)
if (parse.sc.Number == 8 || parse.sc.Number == 16) info->lightmode = ELightMode::NotSet;
else if (parse.sc.Number >= 0 && parse.sc.Number <= 5)
{
info->lightmode = ELightMode(parse.sc.Number);
}

View file

@ -132,16 +132,16 @@ void FState::CheckCallerType(AActor *self, AActor *stateowner)
// This should really never happen. Any valid action function must have actor pointers here.
if (!requiredType->isObjectPointer())
{
ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName.GetChars());
ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName);
}
auto cls = static_cast<PObjectPointer*>(requiredType)->PointedClass();
if (check == nullptr)
{
ThrowAbortException(X_OTHER, "%s called without valid caller. %s expected", ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars());
ThrowAbortException(X_OTHER, "%s called without valid caller. %s expected", ActionFunc->PrintableName, cls->TypeName.GetChars());
}
if (!(StateFlags & STF_DEHACKED) && !check->IsKindOf(cls))
{
ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars());
ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName, cls->TypeName.GetChars());
}
};

View file

@ -742,6 +742,17 @@ void FTextureAnimator::ParseCameraTexture(FScanner &sc)
TexMan.AddGameTexture (viewer);
}
if (sc.GetString())
{
if (sc.Compare ("hdr"))
{
canvas->SetHDR(true);
}
else
{
sc.UnGet();
}
}
if (sc.GetString())
{
if (sc.Compare ("fit"))
{

View file

@ -883,7 +883,7 @@ bool MapLoader::LoadGLNodes(MapData * map)
strcpy(ext, ".gwa");
// Todo: Compare file dates
f_gwa = FResourceFile::OpenResourceFile(path, true);
f_gwa = FResourceFile::OpenResourceFile(path);
if (f_gwa==nullptr) return false;
strncpy(map->MapLumps[0].Name, fileSystem.GetFileFullName(map->lumpnum), 8);

View file

@ -77,7 +77,7 @@ void FSavegameManager::ReadSaveStrings()
// I_FindName only returns the file's name and not its full path
FString filepath = G_BuildSaveName(I_FindName(&c_file));
std::unique_ptr<FResourceFile> savegame(FResourceFile::OpenResourceFile(filepath, true, true));
std::unique_ptr<FResourceFile> savegame(FResourceFile::OpenResourceFile(filepath, true));
if (savegame != nullptr)
{
bool oldVer = false;

View file

@ -125,7 +125,7 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck)
delete map;
return NULL;
}
map->resource = FResourceFile::OpenResourceFile(mapname, true);
map->resource = FResourceFile::OpenResourceFile(mapname);
wadReader = map->resource->GetReader();
}
else

View file

@ -969,6 +969,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
arc("flags", flags)
("flags2", flags2)
("flags3", flags3)
("vkdflags", vkdflags)
("fadeto", fadeto)
("found_secrets", found_secrets)

View file

@ -285,7 +285,7 @@ void FLevelLocals::ClearLevelData(bool fullgc)
auto it = GetThinkerIterator<AActor>(NAME_None, STAT_TRAVELLING);
for (AActor *actor = it.Next(); actor != nullptr; actor = it.Next())
{
actor->BlockingLine = nullptr;
actor->BlockingLine = actor->MovementBlockingLine = nullptr;
actor->BlockingFloor = actor->BlockingCeiling = actor->Blocking3DFloor = nullptr;
}
}

View file

@ -116,6 +116,7 @@ enum
QF_GROUNDONLY = 1 << 7,
QF_AFFECTACTORS = 1 << 8,
QF_SHAKEONLY = 1 << 9,
QF_DAMAGEFALLOFF = 1 << 10,
};
struct FQuakeJiggers
@ -134,8 +135,8 @@ class DEarthquake : public DThinker
public:
static const int DEFAULT_STAT = STAT_EARTHQUAKE;
void Construct(AActor *center, double intensityX, double intensityY, double intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave);
int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave, double damageMultiplier, double thrustMultiplier, int damage);
void Serialize(FSerializer &arc);
void Tick ();
@ -150,11 +151,13 @@ public:
double m_Falloff;
int m_Highpoint, m_MiniCount;
double m_RollIntensity, m_RollWave;
double m_DamageMultiplier, m_ThrustMultiplier;
int m_Damage;
double GetModIntensity(double intensity, bool fake = false) const;
double GetModWave(double ticFrac, double waveMultiplier) const;
double GetFalloff(double dist) const;
void DoQuakeDamage(DEarthquake *quake, AActor *victim) const;
double GetFalloff(double dist, double radius) const;
void DoQuakeDamage(DEarthquake *quake, AActor *victim, bool falloff) const;
static int StaticGetQuakeIntensities(double ticFrac, AActor *viewer, FQuakeJiggers &jiggers);
};

View file

@ -206,8 +206,7 @@ enum ActorFlag2
// but still considered solid
MF2_INVULNERABLE = 0x08000000, // mobj is invulnerable
MF2_DORMANT = 0x10000000, // thing is dormant
MF2_ARGSDEFINED = 0x20000000, // Internal flag used by DECORATE to signal that the
// args should not be taken from the mapthing definition
MF2_ARGSDEFINED = 0x20000000, // Internal flag used by DECORATE to signal that the args should not be taken from the mapthing definition
MF2_SEEKERMISSILE = 0x40000000, // is a seeker (for reflection)
MF2_REFLECTIVE = 0x80000000, // reflects missiles
};
@ -394,11 +393,13 @@ enum ActorFlag7
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
MF7_SMASHABLE = 0x04000000, // dies if hitting the floor.
MF7_NOSHIELDREFLECT = 0x08000000, // will not be reflected by shields.
MF7_FORCEZERORADIUSDMG = 0x10000000, // passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
MF7_FORCEZERORADIUSDMG = 0x10000000,// passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
MF7_NOINFIGHTSPECIES = 0x20000000, // don't start infights with one's own species.
MF7_FORCEINFIGHTING = 0x40000000, // overrides a map setting of 'no infighting'.
MF7_INCHASE = 0x80000000, // [RH] used by A_Chase and A_Look to avoid recursion
};
// --- mobj.flags8 ---
enum ActorFlag8
{
MF8_FRIGHTENING = 0x00000001, // for those moments when halloween just won't do
@ -428,12 +429,21 @@ enum ActorFlag8
MF8_STAYONLIFT = 0x02000000, // MBF AI enhancement.
MF8_DONTFOLLOWPLAYERS = 0x04000000, // [inkoalawetrust] Friendly monster will not follow players.
MF8_SEEFRIENDLYMONSTERS = 0X08000000, // [inkoalawetrust] Hostile monster can see friendly monsters.
MF8_CROSSLINECHECK = 0x10000000, // [MC]Enables CanCrossLine virtual
MF8_CROSSLINECHECK = 0x10000000, // [MC] Enables CanCrossLine virtual
MF8_MASTERNOSEE = 0x20000000, // Don't show object in first person if their master is the current camera.
MF8_ADDLIGHTLEVEL = 0x40000000, // [MC] Actor light level is additive with sector.
MF8_ONLYSLAMSOLID = 0x80000000, // [B] Things with skullfly will ignore non-solid Actors.
};
// --- mobj.flags9 ---
enum ActorFlag9
{
MF9_SHADOWAIM = 0x00000001, // [inkoalawetrust] Monster still gets aim penalty from aiming at shadow actors even with MF6_SEEINVISIBLE on.
MF9_DOSHADOWBLOCK = 0x00000002, // [inkoalawetrust] Should the monster look for SHADOWBLOCK actors ?
MF9_SHADOWBLOCK = 0x00000004, // [inkoalawetrust] Actors in the line of fire with this flag trigger the MF_SHADOW aiming penalty.
MF9_SHADOWAIMVERT = 0x00000008, // [inkoalawetrust] Monster aim is also offset vertically when aiming at shadow actors.
};
// --- mobj.renderflags ---
enum ActorRenderFlag
{
@ -588,6 +598,7 @@ typedef TFlags<ActorFlag5> ActorFlags5;
typedef TFlags<ActorFlag6> ActorFlags6;
typedef TFlags<ActorFlag7> ActorFlags7;
typedef TFlags<ActorFlag8> ActorFlags8;
typedef TFlags<ActorFlag9> ActorFlags9;
typedef TFlags<ActorRenderFlag> ActorRenderFlags;
typedef TFlags<ActorRenderFlag2> ActorRenderFlags2;
typedef TFlags<ActorBounceFlag> ActorBounceFlags;
@ -600,6 +611,7 @@ DEFINE_TFLAGS_OPERATORS (ActorFlags5)
DEFINE_TFLAGS_OPERATORS (ActorFlags6)
DEFINE_TFLAGS_OPERATORS (ActorFlags7)
DEFINE_TFLAGS_OPERATORS (ActorFlags8)
DEFINE_TFLAGS_OPERATORS (ActorFlags9)
DEFINE_TFLAGS_OPERATORS (ActorRenderFlags)
DEFINE_TFLAGS_OPERATORS (ActorRenderFlags2)
DEFINE_TFLAGS_OPERATORS (ActorBounceFlags)
@ -838,6 +850,11 @@ public:
// (virtual on the script side only)
int SpecialMissileHit (AActor *victim);
// Called when bouncing to allow for custom behavior.
// Returns -1 for normal behavior, 0 to stop, and 1 to keep going.
// (virtual on the script side only)
int SpecialBounceHit(AActor* bounceMobj, line_t* bounceLine, secplane_t* bouncePlane);
// Returns true if it's okay to switch target to "other" after being attacked by it.
bool CallOkayToSwitchTarget(AActor *other);
bool OkayToSwitchTarget (AActor *other);
@ -1080,6 +1097,7 @@ public:
ActorFlags6 flags6; // Shit! Where did all the flags go?
ActorFlags7 flags7; // WHO WANTS TO BET ON 8!?
ActorFlags8 flags8; // I see your 8, and raise you a bet for 9.
ActorFlags9 flags9; // Happy ninth actor flag field GZDoom !
double Floorclip; // value to use for floor clipping
double radius, Height; // for movement checking
@ -1196,6 +1214,8 @@ public:
double Gravity; // [GRB] Gravity factor
double Friction;
double pushfactor;
double ShadowAimFactor; // [inkoalawetrust] How much the actors' aim is affected when attacking shadow actors.
double ShadowPenaltyFactor;// [inkoalawetrust] How much the shadow actor affects its' shooters' aim.
int bouncecount; // Strife's grenades only bounce twice before exploding
int FastChaseStrafeCount;
int lastpush;
@ -1208,6 +1228,7 @@ public:
AActor *BlockingMobj; // Actor that blocked the last move
line_t *BlockingLine; // Line that blocked the last move
line_t *MovementBlockingLine; // Line that stopped the Actor's movement in P_XYMovement
sector_t *Blocking3DFloor; // 3D floor that blocked the last move (if any)
sector_t *BlockingCeiling; // Sector that blocked the last move (ceiling plane slope)
sector_t *BlockingFloor; // Sector that blocked the last move (floor plane slope)

View file

@ -33,6 +33,7 @@
#include "d_player.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include <p_maputl.h>
static FRandom pr_quake ("Quake");
@ -51,7 +52,7 @@ IMPLEMENT_POINTERS_END
void DEarthquake::Construct(AActor *center, double intensityX, double intensityY, double intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesound, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint,
double rollIntensity, double rollWave)
double rollIntensity, double rollWave, double damageMultiplier, double thrustMultiplier, int damage)
{
m_QuakeSFX = quakesound;
m_Spot = center;
@ -68,6 +69,9 @@ void DEarthquake::Construct(AActor *center, double intensityX, double intensityY
m_MiniCount = highpoint;
m_RollIntensity = rollIntensity;
m_RollWave = rollWave;
m_DamageMultiplier = damageMultiplier;
m_ThrustMultiplier = thrustMultiplier;
m_Damage = damage;
}
//==========================================================================
@ -93,13 +97,16 @@ void DEarthquake::Serialize(FSerializer &arc)
("minicount", m_MiniCount)
("rollintensity", m_RollIntensity)
("rollwave", m_RollWave);
("damagemultiplier", m_DamageMultiplier);
("thrustmultiplier", m_ThrustMultiplier);
("damage", m_Damage);
}
//==========================================================================
//
// DEarthquake :: Tick
//
// Deals damage to any players near the earthquake and makes sure it's
// Deals damage to any actors near the earthquake and makes sure it's
// making noise.
//
//==========================================================================
@ -123,16 +130,17 @@ void DEarthquake::Tick ()
{
if (m_Flags & QF_AFFECTACTORS)
{
auto iterator = m_Spot->Level->GetThinkerIterator<AActor>();
AActor* mo = nullptr;
FPortalGroupArray check(FPortalGroupArray::PGA_Full3d);
FMultiBlockThingsIterator it(check,m_Spot,m_DamageRadius,false);
FMultiBlockThingsIterator::CheckResult cres;
while ((mo = iterator.Next()) != NULL)
while (it.Next(&cres))
{
if (mo == m_Spot) //Ignore the earthquake origin.
AActor *mo = cres.thing;
if (mo == nullptr || mo == m_Spot) //Ignore null references and the earthquake origin.
continue;
DoQuakeDamage(this, mo);
DoQuakeDamage(this, mo, !!(m_Flags & QF_DAMAGEFALLOFF));
}
}
else
@ -142,7 +150,7 @@ void DEarthquake::Tick ()
if (Level->PlayerInGame(i) && !(Level->Players[i]->cheats & CF_NOCLIP))
{
AActor* victim = Level->Players[i]->mo;
DoQuakeDamage(this, victim);
DoQuakeDamage(this, victim, !!(m_Flags & QF_DAMAGEFALLOFF));
}
}
}
@ -168,26 +176,37 @@ void DEarthquake::Tick ()
//
//==========================================================================
void DEarthquake::DoQuakeDamage(DEarthquake *quake, AActor *victim) const
void DEarthquake::DoQuakeDamage(DEarthquake *quake, AActor *victim, bool falloff) const
{
double dist;
double thrustfalloff;
int damage;
if (!quake || !victim) return;
dist = quake->m_Spot->Distance2D(victim, true);
thrustfalloff = falloff ? GetFalloff(dist, m_DamageRadius) : 1.0;
// Check if in damage radius
if (dist < m_DamageRadius && victim->Z() <= victim->floorz)
{
if (!(quake->m_Flags & QF_SHAKEONLY) && pr_quake() < 50)
{
P_DamageMobj(victim, NULL, NULL, pr_quake.HitDice(1), NAME_Quake);
if (m_Damage < 1)
damage = falloff ? (int)(pr_quake.HitDice(1) * GetFalloff(dist, m_DamageRadius) * m_DamageMultiplier) : (int)(pr_quake.HitDice(1) * m_DamageMultiplier);
//[inkoalawetrust] Do the exact specified damage.
else
damage = falloff ? (int)(m_Damage * GetFalloff(dist, m_DamageRadius) * m_DamageMultiplier) : (int)(m_Damage * m_DamageMultiplier);
damage = damage < 1 ? 1 : damage; //Do at least a tiny bit of damage when in radius.
P_DamageMobj(victim, NULL, NULL, damage, NAME_Quake);
}
// Thrust player or thrustable actor around
if (victim->player || !(victim->flags7 & MF7_DONTTHRUST))
// Thrust pushable actor around
if (!(victim->flags7 & MF7_DONTTHRUST) && m_ThrustMultiplier > 0)
{
DAngle an = victim->Angles.Yaw + DAngle::fromDeg(pr_quake());
victim->Vel.X += m_Intensity.X * an.Cos() * 0.5;
victim->Vel.Y += m_Intensity.Y * an.Sin() * 0.5;
victim->Vel.X += m_Intensity.X * an.Cos() * m_ThrustMultiplier * thrustfalloff;
victim->Vel.Y += m_Intensity.Y * an.Sin() * m_ThrustMultiplier * thrustfalloff;
}
}
return;
@ -285,19 +304,19 @@ double DEarthquake::GetModIntensity(double intensity, bool fake) const
//
// DEarthquake :: GetFalloff
//
// Given the distance of the player from the quake, find the multiplier.
// Given the distance of the actor from the quake, find the multiplier.
//
//==========================================================================
double DEarthquake::GetFalloff(double dist) const
double DEarthquake::GetFalloff(double dist, double radius) const
{
if ((dist < m_Falloff) || (m_Falloff >= m_TremorRadius) || (m_Falloff <= 0) || (m_TremorRadius - m_Falloff <= 0))
{ //Player inside the minimum falloff range, or safety check kicked in.
if ((dist < m_Falloff) || (m_Falloff >= radius) || (m_Falloff <= 0) || (radius - m_Falloff <= 0))
{ //Actor inside the minimum falloff range, or safety check kicked in.
return 1.;
}
else if ((dist > m_Falloff) && (dist < m_TremorRadius))
{ //Player inside the radius, and outside the min distance for falloff.
double tremorsize = m_TremorRadius - m_Falloff;
else if ((dist > m_Falloff) && (dist < radius))
{ //Actor inside the radius, and outside the min distance for falloff.
double tremorsize = radius - m_Falloff;
assert(tremorsize > 0);
return (1. - ((dist - m_Falloff) / tremorsize));
}
@ -341,7 +360,7 @@ int DEarthquake::StaticGetQuakeIntensities(double ticFrac, AActor *victim, FQuak
if (dist < quake->m_TremorRadius)
{
++count;
const double falloff = quake->GetFalloff(dist);
const double falloff = quake->GetFalloff(dist, quake->m_TremorRadius);
const double r = quake->GetModIntensity(quake->m_RollIntensity);
const double strength = quake->GetModIntensity(1.0, true);
DVector3 intensity;
@ -411,7 +430,7 @@ int DEarthquake::StaticGetQuakeIntensities(double ticFrac, AActor *victim, FQuak
bool P_StartQuakeXYZ(FLevelLocals *Level, AActor *activator, int tid, double intensityX, double intensityY, double intensityZ, int duration,
int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint,
double rollIntensity, double rollWave)
double rollIntensity, double rollWave, double damageMultiplier, double thrustMultiplier, int damage)
{
AActor *center;
bool res = false;
@ -425,7 +444,7 @@ bool P_StartQuakeXYZ(FLevelLocals *Level, AActor *activator, int tid, double int
if (activator != NULL)
{
Level->CreateThinker<DEarthquake>(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave);
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave, damageMultiplier, thrustMultiplier, damage);
return true;
}
}
@ -436,14 +455,14 @@ bool P_StartQuakeXYZ(FLevelLocals *Level, AActor *activator, int tid, double int
{
res = true;
Level->CreateThinker<DEarthquake>(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad,
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave);
quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ, falloff, highpoint, rollIntensity, rollWave, damageMultiplier, thrustMultiplier, damage);
}
}
return res;
}
bool P_StartQuake(FLevelLocals *Level, AActor *activator, int tid, double intensity, int duration, int damrad, int tremrad, FSoundID quakesfx)
bool P_StartQuake(FLevelLocals * Level, AActor * activator, int tid, double intensity, int duration, int damrad, int tremrad, FSoundID quakesfx)
{ //Maintains original behavior by passing 0 to intensityZ, flags, and everything else after QSFX.
return P_StartQuakeXYZ(Level, activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0, 0, 0, 0, 0, 0, 0, 0);
return P_StartQuakeXYZ(Level, activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, 0.5, 0);
}

View file

@ -6243,7 +6243,10 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
argCount > 12 ? args[12] : 0,
argCount > 13 ? args[13] : 0,
argCount > 14 ? ACSToDouble(args[14]) : 0,
argCount > 15 ? ACSToDouble(args[15]) : 0);
argCount > 15 ? ACSToDouble(args[15]) : 0,
argCount > 16 ? ACSToDouble(args[16]) : 1.0,
argCount > 17 ? ACSToDouble(args[17]) : 0.5,
argCount > 18 ? args[18] : 0);
}
case ACSF_SetLineActivation:

View file

@ -70,20 +70,21 @@
#include "actorinlines.h"
#include "types.h"
#include "model.h"
#include "shadowinlines.h"
static FRandom pr_camissile ("CustomActorfire");
static FRandom pr_cabullet ("CustomBullet");
static FRandom pr_cwjump ("CustomWpJump");
static FRandom pr_cwpunch ("CustomWpPunch");
static FRandom pr_grenade ("ThrowGrenade");
static FRandom pr_crailgun ("CustomRailgun");
FRandom pr_crailgun ("CustomRailgun");
static FRandom pr_spawndebris ("SpawnDebris");
static FRandom pr_spawnitemex ("SpawnItemEx");
static FRandom pr_burst ("Burst");
static FRandom pr_monsterrefire ("MonsterRefire");
static FRandom pr_teleport("A_Teleport");
static FRandom pr_bfgselfdamage("BFGSelfDamage");
FRandom pr_cajump("CustomJump");
FRandom pr_cajump("CustomJump");
//==========================================================================
//
@ -129,7 +130,7 @@ static int CallStateChain (AActor *self, AActor *actor, FState *state)
// If an unsafe function (i.e. one that accesses user variables) is being detected, print a warning once and remove the bogus function. We may not call it because that would inevitably crash.
auto owner = FState::StaticFindStateOwner(state);
Printf(TEXTCOLOR_RED "Unsafe state call in state %s to %s which accesses user variables. The action function has been removed from this state\n",
FState::StaticGetStateName(state).GetChars(), state->ActionFunc->PrintableName.GetChars());
FState::StaticGetStateName(state).GetChars(), state->ActionFunc->PrintableName);
state->ActionFunc = nullptr;
}
@ -1226,11 +1227,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun)
self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * veleffect, -self->target->Vel.Y * veleffect);
}
if (self->target->flags & MF_SHADOW)
{
DAngle rnd = DAngle::fromDeg(pr_crailgun.Random2() * (45. / 256.));
self->Angles.Yaw += rnd;
}
A_CustomRailgun_ShadowHandling(self, spawnofs_xy, spawnofs_z, spread_xy, flags);
}
if (!(flags & CRF_EXPLICITANGLE))
@ -1399,7 +1396,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LogFloat)
if (local && !self->CheckLocalView()) return 0;
IGNORE_FORMAT_PRE
Printf("%H\n", num);
Printf("%g\n", num);
IGNORE_FORMAT_POST
return 0;
}
@ -2092,6 +2089,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
self->flags6 = defs->flags6;
self->flags7 = defs->flags7;
self->flags8 = defs->flags8;
self->flags9 = defs->flags9;
self->SetState (self->SpawnState);
self->renderflags &= ~RF_INVISIBLE;
@ -3369,8 +3367,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_QuakeEx)
PARAM_INT(highpoint);
PARAM_FLOAT(rollIntensity);
PARAM_FLOAT(rollWave);
PARAM_FLOAT(damageMultiplier);
PARAM_FLOAT(thrustMultiplier);
PARAM_INT(damage);
P_StartQuakeXYZ(self->Level, self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ, falloff, highpoint,
rollIntensity, rollWave);
rollIntensity, rollWave, damageMultiplier, thrustMultiplier, damage);
return 0;
}
@ -3526,7 +3527,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WolfAttack)
hitchance -= idist * (dodge ? 16 : 8);
// While we're here, we may as well do something for this:
if (self->target->flags & MF_SHADOW)
if (A_WolfAttack_ShadowHandling(self))
{
hitchance >>= 2;
}

View file

@ -50,6 +50,7 @@
#include "vm.h"
#include "actorinlines.h"
#include "a_ceiling.h"
#include "shadowinlines.h"
#include "gi.h"
@ -61,8 +62,8 @@ static FRandom pr_lookformonsters ("LookForMonsters");
static FRandom pr_lookforplayers ("LookForPlayers");
static FRandom pr_scaredycat ("Anubis");
FRandom pr_chase ("Chase");
static FRandom pr_facetarget ("FaceTarget");
static FRandom pr_railface ("RailFace");
FRandom pr_facetarget ("FaceTarget");
FRandom pr_railface ("RailFace");
static FRandom pr_look2 ("LookyLooky");
static FRandom pr_look3 ("IGotHooky");
static FRandom pr_slook ("SlooK");
@ -2206,6 +2207,7 @@ enum ChaseFlags
CHF_NOPOSTATTACKTURN = 128,
CHF_STOPIFBLOCKED = 256,
CHF_DONTIDLE = 512,
CHF_DONTLOOKALLAROUND = 1024,
};
void A_Wander(AActor *self, int flags)
@ -2440,7 +2442,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
// hurt our old one temporarily.
actor->threshold = 0;
}
if (P_LookForPlayers (actor, true, NULL) && actor->target != actor->goal)
if (P_LookForPlayers (actor, !(flags & CHF_DONTLOOKALLAROUND), NULL) && actor->target != actor->goal)
{ // got a new target
actor->flags7 &= ~MF7_INCHASE;
return;
@ -2615,7 +2617,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
lookForBetter = true;
}
AActor * oldtarget = actor->target;
gotNew = P_LookForPlayers (actor, true, NULL);
gotNew = P_LookForPlayers (actor, !(flags & CHF_DONTLOOKALLAROUND), NULL);
if (lookForBetter)
{
actor->flags3 |= MF3_NOSIGHTCHECK;
@ -3018,15 +3020,11 @@ void A_Face(AActor *self, AActor *other, DAngle max_turn, DAngle max_pitch, DAng
self->Angles.Pitch = other_pitch;
}
self->Angles.Pitch += pitch_offset;
A_Face_ShadowHandling(self, other, max_pitch, other_pitch, true);
}
// This will never work well if the turn angle is limited.
if (max_turn == nullAngle && (self->Angles.Yaw == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) )
{
self->Angles.Yaw += DAngle::fromDeg(pr_facetarget.Random2() * (45 / 256.));
}
A_Face_ShadowHandling(self,other,max_turn,other_angle,false);
}
void A_FaceTarget(AActor *self)
@ -3073,10 +3071,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail)
// Let the aim trail behind the player
self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3);
if (self->target->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE))
{
self->Angles.Yaw += DAngle::fromDeg(pr_railface.Random2() * 45./256);
}
A_MonsterRail_ShadowHandling(self);
FRailParams p;

View file

@ -268,6 +268,7 @@ void P_PlayerStartStomp (AActor *actor, bool mononly=false); // [RH] Stomp on t
void P_SlideMove (AActor* mo, const DVector2 &pos, int numsteps);
bool P_BounceWall (AActor *mo);
bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop);
bool P_ReflectOffActor(AActor* mo, AActor* blocking);
int P_CheckSight (AActor *t1, AActor *t2, int flags=0);
enum ESightFlags
@ -406,9 +407,12 @@ enum
RADF_SOURCEISSPOT = 4,
RADF_NODAMAGE = 8,
RADF_THRUSTZ = 16,
RADF_OLDRADIUSDAMAGE = 32
RADF_OLDRADIUSDAMAGE = 32,
RADF_THRUSTLESS = 64,
RADF_NOALLIES = 128,
RADF_CIRCULAR = 256
};
int P_GetRadiusDamage(AActor *self, AActor *thing, int damage, int distance, int fulldmgdistance, bool oldradiusdmg);
int P_GetRadiusDamage(AActor *self, AActor *thing, int damage, int distance, int fulldmgdistance, bool oldradiusdmg, bool circular);
int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
FName damageType, int flags, int fulldamagedistance=0, FName species = NAME_None);

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