From ea0e4ed34482cf1089708b1e6a9de69f53f022f4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 13 Sep 2013 10:07:43 +0200 Subject: [PATCH 001/311] - fixed: The Hexen bridge must make its balls disappear when it gets destroyed. Hexen did this with a call to A_BridgeRemove in Thing_Destroy which merely set a flag in the bridge object, which cannot be done safely in ZDoom because it's not guaranteed that the ball object calls A_BridgeOrbit and the garbage collector may delete the bridge actor before it can be checked so now the Bridge's Destroy method deletes all balls attached to the bridge object itself. --- src/g_shared/a_bridge.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index 7e743a0af..d669cc3bd 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -38,6 +38,7 @@ class ACustomBridge : public AActor DECLARE_CLASS (ACustomBridge, AActor) public: void BeginPlay (); + void Destroy(); }; IMPLEMENT_CLASS(ACustomBridge) @@ -58,6 +59,24 @@ void ACustomBridge::BeginPlay () } } +void ACustomBridge::Destroy() +{ + // Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit. + // But this is not safe with custom bridge balls that do not necessarily call that function. + // So the best course of action is to look for all bridge balls here and destroy them ourselves. + + TThinkerIterator it; + AActor *thing; + + while ((thing = it.Next())) + { + if (thing->target == this) + { + thing->Destroy(); + } + } +} + // Action functions for the non-Doom bridge -------------------------------- #define ORBIT_RADIUS 15 @@ -89,10 +108,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) // Set rotation radius if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / (100 * FRACUNIT)); - if (self->target->special1) - { - self->SetState (NULL); - } self->angle += rotationspeed; self->x = self->target->x + rotationradius * finecosine[self->angle >> ANGLETOFINESHIFT]; self->y = self->target->y + rotationradius * finesine[self->angle >> ANGLETOFINESHIFT]; @@ -115,7 +130,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) cy = self->y; cz = self->z; startangle = pr_orbit() << 24; - self->special1 = 0; // Spawn triad into world -- may be more than a triad now. int ballcount = self->args[2]==0 ? 3 : self->args[2]; @@ -129,14 +143,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) } } -/* never used -void A_BridgeRemove (AActor *self) -{ - self->special1 = true; // Removing the bridge - self->flags &= ~MF_SOLID; - self->SetState (&ABridge::States[S_FREE_BRIDGE]); -} -*/ // Invisible bridge -------------------------------------------------------- From da02a44126c67e0e7e084c1517dee8fd888f2961 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 14 Sep 2013 21:02:47 -0500 Subject: [PATCH 002/311] Consolidate special path functions into m_specialpaths.cpp - Also remove CDROM_DIR while I'm at it. --- src/CMakeLists.txt | 1 + src/b_game.cpp | 24 +- src/d_main.cpp | 11 - src/g_game.cpp | 26 +-- src/gameconfigfile.cpp | 94 +------- src/m_misc.cpp | 112 +-------- src/m_misc.h | 15 +- src/m_specialpaths.cpp | 500 +++++++++++++++++++++++++++++++++++++++++ src/p_glnodes.cpp | 51 +---- src/version.h | 2 - zdoom.vcproj | 4 + 11 files changed, 541 insertions(+), 299 deletions(-) create mode 100644 src/m_specialpaths.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 82f347fd8..4223598f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -701,6 +701,7 @@ add_executable( zdoom WIN32 m_misc.cpp m_png.cpp m_random.cpp + m_specialpaths.cpp memarena.cpp md5.cpp name.cpp diff --git a/src/b_game.cpp b/src/b_game.cpp index ed3a5c848..f3878b8bb 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -505,31 +505,13 @@ bool FCajunMaster::LoadBots () bool gotteam = false; bglobal.ForgetBots (); -#ifndef __unix__ - tmp = progdir; - tmp += "zcajun/" BOTFILENAME; - if (!FileExists (tmp)) + tmp = M_GetCajunPath(BOTFILENAME); + if (tmp.IsEmpty()) { DPrintf ("No " BOTFILENAME ", so no bots\n"); return false; } -#else - tmp = GetUserFile (BOTFILENAME); - if (!FileExists (tmp)) - { - if (!FileExists (SHARE_DIR BOTFILENAME)) - { - DPrintf ("No " BOTFILENAME ", so no bots\n"); - return false; - } - else - sc.OpenFile (SHARE_DIR BOTFILENAME); - } -#endif - else - { - sc.OpenFile (tmp); - } + sc.OpenFile(tmp); while (sc.GetString ()) { diff --git a/src/d_main.cpp b/src/d_main.cpp index b70e5d779..f72dc368b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2137,17 +2137,6 @@ static void CheckCmdLine() Printf ("%s", GStrings("D_DEVSTR")); } -#if !defined(__unix__) && !defined(__APPLE__) - // We do not need to support -cdrom under Unix, because all the files - // that would go to c:\\zdoomdat are already stored in .zdoom inside - // the user's home directory. - if (Args->CheckParm("-cdrom")) - { - Printf ("%s", GStrings("D_CDROM")); - mkdir (CDROM_DIR, 0); - } -#endif - // turbo option // [RH] (now a cvar) v = Args->CheckValue("-turbo"); if (v != NULL) diff --git a/src/g_game.cpp b/src/g_game.cpp index 79cd4b233..698b52e79 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1919,32 +1919,10 @@ FString G_BuildSaveName (const char *prefix, int slot) leader = Args->CheckValue ("-savedir"); if (leader.IsEmpty()) { -#if !defined(__unix__) && !defined(__APPLE__) - if (Args->CheckParm ("-cdrom")) - { - leader = CDROM_DIR "/"; - } - else -#endif - { - leader = save_dir; - } + leader = save_dir; if (leader.IsEmpty()) { -#ifdef __unix__ - leader = "~/" GAME_DIR; -#elif defined(__APPLE__) - char cpath[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - leader << cpath << "/" GAME_DIR "/Savegames/"; - } -#else - leader = progdir; -#endif + leader = M_GetSavegamesPath(); } } size_t len = leader.Len(); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 211ef96c6..f679bec3d 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -42,8 +42,6 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include -#include -#include extern HWND Window; #define USE_WINDOWS_DWORD #endif @@ -588,106 +586,20 @@ void FGameConfigFile::ArchiveGlobalData () FString FGameConfigFile::GetConfigPath (bool tryProg) { const char *pathval; - FString path; pathval = Args->CheckValue ("-config"); if (pathval != NULL) { return FString(pathval); } -#ifdef _WIN32 - path = NULL; - HRESULT hr; - - TCHAR uname[UNLEN+1]; - DWORD unamelen = countof(uname); - - // Because people complained, try for a user-specific .ini in the program directory first. - // If that is not writeable, use the one in the home directory instead. - hr = GetUserName (uname, &unamelen); - if (SUCCEEDED(hr) && uname[0] != 0) - { - // Is it valid for a user name to have slashes? - // Check for them and substitute just in case. - char *probe = uname; - while (*probe != 0) - { - if (*probe == '\\' || *probe == '/') - *probe = '_'; - ++probe; - } - - path = progdir; - path += "zdoom-"; - path += uname; - path += ".ini"; - if (tryProg) - { - if (!FileExists (path.GetChars())) - { - path = ""; - } - } - else - { // check if writeable - FILE *checker = fopen (path.GetChars(), "a"); - if (checker == NULL) - { - path = ""; - } - else - { - fclose (checker); - } - } - } - - if (path.IsEmpty()) - { - if (Args->CheckParm ("-cdrom")) - return CDROM_DIR "\\zdoom.ini"; - - path = progdir; - path += "zdoom.ini"; - } - return path; -#elif defined(__APPLE__) - char cpath[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kUserDomain, kPreferencesFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - path = cpath; - path += "/zdoom.ini"; - return path; - } - // Ungh. - return "zdoom.ini"; -#else - return GetUserFile ("zdoom.ini"); -#endif + return M_GetConfigPath(tryProg); } void FGameConfigFile::CreateStandardAutoExec(const char *section, bool start) { if (!SetSection(section)) { - FString path; -#ifdef __APPLE__ - char cpath[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - path << cpath << "/" GAME_DIR "/autoexec.cfg"; - } -#elif !defined(__unix__) - path = "$PROGDIR/autoexec.cfg"; -#else - path = GetUserFile ("autoexec.cfg"); -#endif + FString path = M_GetAutoexecPath(); SetSection (section, true); SetValueForKey ("Path", path.GetChars()); } @@ -794,6 +706,6 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen) CCMD (whereisini) { - FString path = GameConfig->GetConfigPath (false); + FString path = M_GetConfigPath(false); Printf ("%s\n", path.GetChars()); } diff --git a/src/m_misc.cpp b/src/m_misc.cpp index e218cadc4..14b9d9b1b 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -31,9 +31,6 @@ #include #include #include -#ifdef __APPLE__ -#include -#endif #include "doomtype.h" #include "version.h" @@ -333,65 +330,6 @@ static long ParseCommandLine (const char *args, int *argc, char **argv) } -#if defined(__unix__) -FString GetUserFile (const char *file) -{ - FString path; - struct stat info; - - path = NicePath("~/" GAME_DIR "/"); - - if (stat (path, &info) == -1) - { - struct stat extrainfo; - - // Sanity check for ~/.config - FString configPath = NicePath("~/.config/"); - if (stat (configPath, &extrainfo) == -1) - { - if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) - { - I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno)); - } - } - else if (!S_ISDIR(extrainfo.st_mode)) - { - I_FatalError ("~/.config must be a directory"); - } - - // This can be removed after a release or two - // Transfer the old zdoom directory to the new location - bool moved = false; - FString oldpath = NicePath("~/.zdoom/"); - if (stat (oldpath, &extrainfo) != -1) - { - if (rename(oldpath, path) == -1) - { - I_Error ("Failed to move old zdoom directory (%s) to new location (%s).", - oldpath.GetChars(), path.GetChars()); - } - else - moved = true; - } - - if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) - { - I_FatalError ("Failed to create %s directory:\n%s", - path.GetChars(), strerror (errno)); - } - } - else - { - if (!S_ISDIR(info.st_mode)) - { - I_FatalError ("%s must be a directory", path.GetChars()); - } - } - path += file; - return path; -} -#endif - // // M_SaveDefaults // @@ -698,48 +636,22 @@ void M_ScreenShot (const char *filename) // find a file name to save it to if (filename == NULL || filename[0] == '\0') { -#if !defined(__unix__) && !defined(__APPLE__) - if (Args->CheckParm ("-cdrom")) + size_t dirlen; + autoname = Args->CheckValue("-shotdir"); + if (autoname.IsEmpty()) { - autoname = CDROM_DIR "\\"; + autoname = screenshot_dir; } - else -#endif + dirlen = autoname.Len(); + if (dirlen == 0) { - size_t dirlen; - autoname = Args->CheckValue("-shotdir"); - if (autoname.IsEmpty()) + autoname = M_GetScreenshotsPath(); + } + else if (dirlen > 0) + { + if (autoname[dirlen-1] != '/' && autoname[dirlen-1] != '\\') { - autoname = screenshot_dir; - } - dirlen = autoname.Len(); - if (dirlen == 0) - { -#ifdef __unix__ - autoname = "~/" GAME_DIR "/screenshots/"; -#elif defined(__APPLE__) - char cpath[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) - { - autoname << cpath << "/" GAME_DIR "/Screenshots/"; - } - else - { - autoname = "~"; - } -#else - autoname = progdir; -#endif - } - else if (dirlen > 0) - { - if (autoname[dirlen-1] != '/' && autoname[dirlen-1] != '\\') - { - autoname += '/'; - } + autoname += '/'; } } autoname = NicePath(autoname); diff --git a/src/m_misc.h b/src/m_misc.h index 27006cf87..327df3de4 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -24,6 +24,7 @@ #define __M_MISC__ #include "basictypes.h" +#include "zstring.h" class FConfigFile; class FGameConfigFile; @@ -44,9 +45,19 @@ bool M_SaveDefaults (const char *filename); void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen); -// Prepends ~/.zdoom to path -FString GetUserFile (const char *path); FString M_ZLibError(int zerrnum); +// Get special directory paths (defined in m_specialpaths.cpp) + +#ifdef __unix__ +FString GetUserFile (const char *path); // Prepends ~/.zdoom to path +#endif +FString M_GetCachePath(); +FString M_GetAutoexecPath(); +FString M_GetCajunPath(const char *filename); +FString M_GetConfigPath(bool for_reading); +FString M_GetScreenshotsPath(); +FString M_GetSavegamesPath(); + #endif diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp new file mode 100644 index 000000000..6f77551ae --- /dev/null +++ b/src/m_specialpaths.cpp @@ -0,0 +1,500 @@ +#ifdef __APPLE__ +#include +#endif + +#ifdef _WIN32 +#include +#include +#include +#define USE_WINDOWS_DWORD +#endif + +#include "cmdlib.h" +#include "m_misc.h" + +#if defined(_WIN32) + +//=========================================================================== +// +// M_GetCachePath Windows +// +// Returns the path for cache GL nodes. +// +//=========================================================================== + +FString M_GetCachePath() +{ + FString path; + + char pathstr[MAX_PATH]; + if (0 != SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pathstr)) + { // Failed (e.g. On Win9x): use program directory + path = progdir; + } + else + { + path = pathstr; + } + // Don't use GAME_DIR and such so that ZDoom and its child ports can + // share the node cache. + path += "/zdoom/cache"; + return path; +} + +//=========================================================================== +// +// M_GetAutoexecPath Windows +// +// Returns the expected location of autoexec.cfg. +// +//=========================================================================== + +FString M_GetAutoexecPath() +{ + return "$PROGDIR/autoexec.cfg"; +} + +//=========================================================================== +// +// M_GetCajunPath Windows +// +// Returns the location of the Cajun Bot definitions. +// +//=========================================================================== + +FString M_GetCajunPath(const char *botfilename) +{ + FString path; + + path << progdir << "zcajun/" << botfilename; + if (!FileExists(path)) + { + path = ""; + } + return path; +} + +//=========================================================================== +// +// M_GetConfigPath Windows +// +// Returns the path to the config file. On Windows, this can vary for reading +// vs writing. i.e. If $PROGDIR/zdoom-.ini does not exist, it will try +// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini. +// +//=========================================================================== + +FString M_GetConfigPath(bool for_reading) +{ + FString path; + HRESULT hr; + + TCHAR uname[UNLEN+1]; + DWORD unamelen = countof(uname); + + // Because people complained, try for a user-specific .ini in the program directory first. + // If that is not writeable, use the one in the home directory instead. + hr = GetUserName(uname, &unamelen); + if (SUCCEEDED(hr) && uname[0] != 0) + { + // Is it valid for a user name to have slashes? + // Check for them and substitute just in case. + char *probe = uname; + while (*probe != 0) + { + if (*probe == '\\' || *probe == '/') + *probe = '_'; + ++probe; + } + + path = progdir; + path += "zdoom-"; + path += uname; + path += ".ini"; + if (for_reading) + { + if (!FileExists(path.GetChars())) + { + path = ""; + } + } + else + { // check if writeable + FILE *checker = fopen (path.GetChars(), "a"); + if (checker == NULL) + { + path = ""; + } + else + { + fclose (checker); + } + } + } + return path; +} + +//=========================================================================== +// +// M_GetScreenshotsPath Windows +// +// Returns the path to the default screenshots directory. +// +//=========================================================================== + +FString M_GetScreenshotsPath() +{ + FString path; + path = progdir; + return path; +} + +//=========================================================================== +// +// M_GetSavegamesPath Windows +// +// Returns the path to the default save games directory. +// +//=========================================================================== + +FString M_GetSavegamesPath() +{ + FString path; + path = progdir; + return path; +} + +#elif defined(__APPLE__) + +//=========================================================================== +// +// M_GetCachePath Mac OS X +// +// Returns the path for cache GL nodes. +// +//=========================================================================== + +FString M_GetCachePath() +{ + FString path; + + char pathstr[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX)) + { + path = pathstr; + } + else + { + path = progdir; + } + path += "/zdoom/cache"; + return path; +} + +//=========================================================================== +// +// M_GetAutoexecPath Mac OS X +// +// Returns the expected location of autoexec.cfg. +// +//=========================================================================== + +FString M_GetAutoexecPath() +{ + FString path; + + char cpath[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + path << cpath << "/" GAME_DIR "/autoexec.cfg"; + } + return path; +} + +//=========================================================================== +// +// M_GetCajunPath Mac OS X +// +// Returns the location of the Cajun Bot definitions. +// +//=========================================================================== + +FString M_GetCajunPath(const char *botfilename) +{ + FString path; + + // Just copies the Windows code. Should this be more Mac-specific? + path << progdir << "zcajun/" << botfilename; + if (!FileExists(path)) + { + path = ""; + } + return path; +} + +//=========================================================================== +// +// M_GetConfigPath Mac OS X +// +// Returns the path to the config file. On Windows, this can vary for reading +// vs writing. i.e. If $PROGDIR/zdoom-.ini does not exist, it will try +// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini. +// +//=========================================================================== + +FString M_GetConfigPath(bool for_reading) +{ + char cpath[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kUserDomain, kPreferencesFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + FString path; + path << cpath << "/zdoom.ini"; + return path; + } + // Ungh. + return "zdoom.ini"; +} + +//=========================================================================== +// +// M_GetScreenshotsPath Mac OS X +// +// Returns the path to the default screenshots directory. +// +//=========================================================================== + +FString M_GetScreenshotsPath() +{ + FString path; + char cpath[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + path << cpath << "/" GAME_DIR "/Screenshots/"; + } + else + { + path = "~/"; + } + return path; +} + +//=========================================================================== +// +// M_GetSavegamesPath Mac OS X +// +// Returns the path to the default save games directory. +// +//=========================================================================== + +FString M_GetSavegamesPath() +{ + FString path; + char cpath[PATH_MAX]; + FSRef folder; + + if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) && + noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) + { + path << cpath << "/" GAME_DIR "/Savegames/"; + } + return path; +} + +#else // Linux, et al. + +FString GetUserFile(const char *file) +{ + FString path; + struct stat info; + + path = NicePath("~/" GAME_DIR "/"); + + if (stat(path, &info) == -1) + { + struct stat extrainfo; + + // Sanity check for ~/.config + FString configPath = NicePath("~/.config/"); + if (stat(configPath, &extrainfo) == -1) + { + if (mkdir(configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + { + I_FatalError("Failed to create ~/.config directory:\n%s", strerror(errno)); + } + } + else if (!S_ISDIR(extrainfo.st_mode)) + { + I_FatalError("~/.config must be a directory"); + } + + // This can be removed after a release or two + // Transfer the old zdoom directory to the new location + bool moved = false; + FString oldpath = NicePath("~/.zdoom/"); + if (stat #if defined(__unix__) +FString GetUserFile (const char *file) +{ + FString path; + struct stat info; + + path = NicePath("~/" GAME_DIR "/"); + + if (stat (path, &info) == -1) + { + struct stat extrainfo; + + // Sanity check for ~/.config + FString configPath = NicePath("~/.config/"); + if (stat (configPath, &extrainfo) == -1) + { + if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + { + I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno)); + } + } + else if (!S_ISDIR(extrainfo.st_mode)) + { + I_FatalError ("~/.config must be a directory"); + } + + // This can be removed after a release or two + // Transfer the old zdoom directory to the new location + bool moved = false; + FString oldpath = NicePath("~/.zdoom/"); + if (stat (oldpath, &extrainfo) != -1) + { + if (rename(oldpath, path) == -1) + { + I_Error ("Failed to move old zdoom directory (%s) to new location (%s).", + oldpath.GetChars(), path.GetChars()); + } + else + moved = true; + } + + if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + { + I_FatalError ("Failed to create %s directory:\n%s", + path.GetChars(), strerror (errno)); + } + } + else + { + if (!S_ISDIR(info.st_mode)) + { + I_FatalError ("%s must be a directory", path.GetChars()); + } + } + path += file; + return path; +} + +//=========================================================================== +// +// M_GetCachePath Unix +// +// Returns the path for cache GL nodes. +// +//=========================================================================== + +FString M_GetCachePath() +{ + // Don't use GAME_DIR and such so that ZDoom and its child ports can + // share the node cache. + return NicePath("~/.config/zdoom/cache"); +} + +//=========================================================================== +// +// M_GetAutoexecPath Unix +// +// Returns the expected location of autoexec.cfg. +// +//=========================================================================== + +FString M_GetAutoexecPath() +{ + return GetUserFile("autoexec.cfg"); +} + +//=========================================================================== +// +// M_GetCajunPath Unix +// +// Returns the location of the Cajun Bot definitions. +// +//=========================================================================== + +FString M_GetCajunPath(const char *botfilename) +{ + FString path; + + // Check first in ~/.config/zdoom./botfilename. + path = GetUserFile(BOTFILENAME); + if (!FileExists(tmp)) + { + // Then check in SHARE_DIR/botfilename. (Some allowance for Macs + // should probably be made here.) + path = SHARE_DIR BOTFILENAME; + if (!FileExists(path)) + { + path =""; + } + } + return path; +} + +//=========================================================================== +// +// M_GetConfigPath Unix +// +// Returns the path to the config file. On Windows, this can vary for reading +// vs writing. i.e. If $PROGDIR/zdoom-.ini does not exist, it will try +// to read from $PROGDIR/zdoom.ini, but it will never write to zdoom.ini. +// +//=========================================================================== + +FString M_GetConfigPath(bool for_reading) +{ + return GetUserFile("zdoom.ini"); +} + +//=========================================================================== +// +// M_GetScreenshotsPath Unix +// +// Returns the path to the default screenshots directory. +// +//=========================================================================== + +FString M_GetScreenshotsPath() +{ + return "~/" GAME_DIR "/screenshots/"; +} + +//=========================================================================== +// +// M_GetSavegamesPath Unix +// +// Returns the path to the default save games directory. +// +//=========================================================================== + +FString M_GetSavegamesPath() +{ + return = "~/" GAME_DIR; +} + +#endif diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 2665f69ba..7dde9c80f 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -43,17 +43,6 @@ #define rmdir _rmdir -// TODO, maybe: stop using DWORD so I don't need to worry about conflicting -// with Windows' typedef. Then I could just include the header file instead -// of declaring everything here. -#define MAX_PATH 260 -#define CSIDL_LOCAL_APPDATA 0x001c -extern "C" __declspec(dllimport) long __stdcall SHGetFolderPathA(void *hwnd, int csidl, void *hToken, unsigned long dwFlags, char *pszPath); - -#endif - -#ifdef __APPLE__ -#include #endif #include "templates.h" @@ -75,6 +64,7 @@ extern "C" __declspec(dllimport) long __stdcall SHGetFolderPathA(void *hwnd, int #include "x86.h" #include "version.h" #include "md5.h" +#include "m_misc.h" void P_GetPolySpots (MapData * lump, TArray &spots, TArray &anchors); @@ -1048,45 +1038,10 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) typedef TArray MemFile; -static FString GetCachePath() -{ - FString path; - -#ifdef _WIN32 - char pathstr[MAX_PATH]; - if (0 != SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pathstr)) - { // Failed (e.g. On Win9x): use program directory - path = progdir; - } - else - { - path = pathstr; - } - path += "/zdoom/cache"; -#elif defined(__APPLE__) - char pathstr[PATH_MAX]; - FSRef folder; - - if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX)) - { - path = pathstr; - } - else - { - path = progdir; - } - path += "/zdoom/cache"; -#else - // Don't use GAME_DIR and such so that ZDoom and its child ports can share the node cache. - path = NicePath("~/.config/zdoom/cache"); -#endif - return path; -} static FString CreateCacheName(MapData *map, bool create) { - FString path = GetCachePath(); + FString path = M_GetCachePath(); FString lumpname = Wads.GetLumpFullPath(map->lumpnum); int separator = lumpname.IndexOf(':'); path << '/' << lumpname.Left(separator); @@ -1299,7 +1254,7 @@ errorout: CCMD(clearnodecache) { TArray list; - FString path = GetCachePath(); + FString path = M_GetCachePath(); path += "/"; try diff --git a/src/version.h b/src/version.h index d7acf1e6a..5fee0bd83 100644 --- a/src/version.h +++ b/src/version.h @@ -95,8 +95,6 @@ const char *GetVersionString(); #define GAME_DIR ".config/zdoom" #elif defined(__APPLE__) #define GAME_DIR GAMENAME -#else -#define CDROM_DIR "C:\\ZDOOMDAT" #endif diff --git a/zdoom.vcproj b/zdoom.vcproj index 89cf4c7b0..b6ebdeb90 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -710,6 +710,10 @@ RelativePath=".\src\m_random.cpp" > + + From 0645053431884fafdcc7ede11694058b16d2b3af Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 14 Sep 2013 23:07:59 -0500 Subject: [PATCH 003/311] Add support for standard file paths on Windows. - If the current user does not have write permissions for the directory zdoom.exe is located in, use standard folder paths located in their home directory instead. This is a common scenario when people put ZDoom into Program Files. (Ironically, zdoom.ini used to be in AppData, buth then people complained when it wasn't in the same directory as zdoom.exe, so it got turned into zdoom-.ini so at least it could retain some multi-user support. I'm not sure when the AppData support was removed, though, since it should have still been kept around for migrating configs to the new name.) --- src/m_misc.cpp | 3 +- src/m_misc.h | 2 +- src/m_specialpaths.cpp | 242 +++++++++++++++++++++++++++++++++-------- src/p_glnodes.cpp | 4 +- 4 files changed, 202 insertions(+), 49 deletions(-) diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 14b9d9b1b..c550c4593 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -646,8 +646,9 @@ void M_ScreenShot (const char *filename) if (dirlen == 0) { autoname = M_GetScreenshotsPath(); + dirlen = autoname.Len(); } - else if (dirlen > 0) + if (dirlen > 0) { if (autoname[dirlen-1] != '/' && autoname[dirlen-1] != '\\') { diff --git a/src/m_misc.h b/src/m_misc.h index 327df3de4..90844221f 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -53,7 +53,7 @@ FString M_ZLibError(int zerrnum); #ifdef __unix__ FString GetUserFile (const char *path); // Prepends ~/.zdoom to path #endif -FString M_GetCachePath(); +FString M_GetCachePath(bool create); FString M_GetAutoexecPath(); FString M_GetCajunPath(const char *filename); FString M_GetConfigPath(bool for_reading); diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 6f77551ae..cd116e538 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -14,6 +14,114 @@ #if defined(_WIN32) +#include "version.h" // for GAMENAME +typedef HRESULT (*GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); + +//=========================================================================== +// +// IsProgramDirectoryWritable +// +// If the program directory is writable, then dump everything in there for +// historical reasons. Otherwise, known folders get used instead. +// +//=========================================================================== + +bool UseKnownFolders() +{ + // Cache this value so the semantics don't change during a single run + // of the program. (e.g. Somebody could add write access while the + // program is running.) + static INTBOOL iswritable = -1; + FString testpath; + HANDLE file; + + if (iswritable >= 0) + { + return !iswritable; + } + testpath << progdir << "writest"; + file = CreateFile(testpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); + if (file != INVALID_HANDLE_VALUE) + { + CloseHandle(file); + Printf("Using program directory for storage\n"); + iswritable = true; + return false; + } + Printf("Using known folders for storage\n"); + iswritable = false; + return true; +} + +//=========================================================================== +// +// GetKnownFolder +// +// Returns the known_folder if SHGetKnownFolderPath is available, otherwise +// returns the shell_folder using SHGetFolderPath. +// +//=========================================================================== + +bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create, FString &path) +{ + static GKFP SHGetKnownFolderPath = NULL; + static bool tested = false; + + if (!tested) + { + tested = true; + HMODULE shell32 = GetModuleHandle("shell32.dll"); + if (shell32 != NULL) + { + SHGetKnownFolderPath = (GKFP)GetProcAddress(shell32, "SHGetKnownFolderPath"); + } + } + + char pathstr[MAX_PATH]; + + // SHGetKnownFolderPath knows about more folders than SHGetFolderPath, but is + // new to Vista, hence the reason we support both. + if (SHGetKnownFolderPath == NULL) + { + if (shell_folder < 0) + { // Not supported by SHGetFolderPath + return false; + } + if (create) + { + shell_folder |= CSIDL_FLAG_CREATE; + } + if (FAILED(SHGetFolderPathA(NULL, shell_folder, NULL, 0, pathstr))) + { + return false; + } + path = pathstr; + return true; + } + else + { + PWSTR wpath; + if (FAILED(SHGetKnownFolderPath(known_folder, create ? KF_FLAG_CREATE : 0, NULL, &wpath))) + { + return false; + } + // FIXME: Support Unicode, at least for filenames. This function + // has no MBCS equivalent, so we have to convert it since we don't + // support Unicode. :( + bool converted = false; + if (WideCharToMultiByte(GetACP(), WC_NO_BEST_FIT_CHARS, wpath, -1, + pathstr, countof(pathstr), NULL, NULL) > 0) + { + path = pathstr; + converted = true; + } + CoTaskMemFree(wpath); + return converted; + } +} + //=========================================================================== // // M_GetCachePath Windows @@ -22,19 +130,14 @@ // //=========================================================================== -FString M_GetCachePath() +FString M_GetCachePath(bool create) { FString path; - char pathstr[MAX_PATH]; - if (0 != SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pathstr)) + if (!GetKnownFolder(CSIDL_LOCAL_APPDATA, FOLDERID_LocalAppData, create, path)) { // Failed (e.g. On Win9x): use program directory path = progdir; } - else - { - path = pathstr; - } // Don't use GAME_DIR and such so that ZDoom and its child ports can // share the node cache. path += "/zdoom/cache"; @@ -89,48 +192,50 @@ FString M_GetConfigPath(bool for_reading) FString path; HRESULT hr; - TCHAR uname[UNLEN+1]; - DWORD unamelen = countof(uname); - - // Because people complained, try for a user-specific .ini in the program directory first. - // If that is not writeable, use the one in the home directory instead. - hr = GetUserName(uname, &unamelen); - if (SUCCEEDED(hr) && uname[0] != 0) + // Construct a user-specific config name + if (UseKnownFolders() && GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true, path)) { - // Is it valid for a user name to have slashes? - // Check for them and substitute just in case. - char *probe = uname; - while (*probe != 0) - { - if (*probe == '\\' || *probe == '/') - *probe = '_'; - ++probe; - } + path += "/zdoom"; + CreatePath(path); + path += "/zdoom.ini"; + } + else + { // construct "$PROGDIR/zdoom-$USER.ini" + TCHAR uname[UNLEN+1]; + DWORD unamelen = countof(uname); path = progdir; - path += "zdoom-"; - path += uname; - path += ".ini"; - if (for_reading) + hr = GetUserName(uname, &unamelen); + if (SUCCEEDED(hr) && uname[0] != 0) { - if (!FileExists(path.GetChars())) + // Is it valid for a user name to have slashes? + // Check for them and substitute just in case. + char *probe = uname; + while (*probe != 0) { - path = ""; + if (*probe == '\\' || *probe == '/') + *probe = '_'; + ++probe; } + path << "zdoom-" << uname << ".ini"; } else - { // check if writeable - FILE *checker = fopen (path.GetChars(), "a"); - if (checker == NULL) - { - path = ""; - } - else - { - fclose (checker); - } + { // Couldn't get user name, so just use zdoom.ini + path += "zdoom.ini"; } } + + // If we are reading the config file, check if it exists. If not, fallback + // to $PROGDIR/zdoom.ini + if (for_reading) + { + if (!FileExists(path)) + { + path = progdir; + path << "zdoom.ini"; + } + } + return path; } @@ -142,10 +247,31 @@ FString M_GetConfigPath(bool for_reading) // //=========================================================================== +// I'm not sure when FOLDERID_Screenshots was added, but it was probably +// for Windows 8, since it's not in the v7.0 Windows SDK. +static const GUID MyFOLDERID_Screenshots = { 0xb7bede81, 0xdf94, 0x4682, 0xa7, 0xd8, 0x57, 0xa5, 0x26, 0x20, 0xb8, 0x6f }; + FString M_GetScreenshotsPath() { FString path; - path = progdir; + + if (!UseKnownFolders()) + { + return progdir; + } + else if (GetKnownFolder(-1, MyFOLDERID_Screenshots, true, path)) + { + path << "/" GAMENAME; + } + else if (GetKnownFolder(CSIDL_MYPICTURES, FOLDERID_Pictures, true, path)) + { + path << "/Screenshots/" GAMENAME; + } + else + { + return progdir; + } + CreatePath(path); return path; } @@ -160,7 +286,28 @@ FString M_GetScreenshotsPath() FString M_GetSavegamesPath() { FString path; - path = progdir; + + if (!UseKnownFolders()) + { + return progdir; + } + // Try standard Saved Games folder + else if (GetKnownFolder(-1, FOLDERID_SavedGames, true, path)) + { + path << "/" GAMENAME; + } + // Try defacto My Documents/My Games folder + else if (GetKnownFolder(CSIDL_PERSONAL, FOLDERID_Documents, true, path)) + { + // I assume since this isn't a standard folder, it doesn't have + // a localized name either. + path << "/My Games/" GAMENAME; + CreatePath(path); + } + else + { + path = progdir; + } return path; } @@ -174,14 +321,14 @@ FString M_GetSavegamesPath() // //=========================================================================== -FString M_GetCachePath() +FString M_GetCachePath(bool create) { FString path; char pathstr[PATH_MAX]; FSRef folder; - if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && + if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) && noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX)) { path = pathstr; @@ -409,11 +556,16 @@ FString GetUserFile (const char *file) // //=========================================================================== -FString M_GetCachePath() +FString M_GetCachePath(bool create) { // Don't use GAME_DIR and such so that ZDoom and its child ports can // share the node cache. - return NicePath("~/.config/zdoom/cache"); + FString path = NicePath("~/.config/zdoom/cache"); + if (create) + { + CreatePath(create); + } + return path; } //=========================================================================== diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 7dde9c80f..b07d50aed 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1041,7 +1041,7 @@ typedef TArray MemFile; static FString CreateCacheName(MapData *map, bool create) { - FString path = M_GetCachePath(); + FString path = M_GetCachePath(create); FString lumpname = Wads.GetLumpFullPath(map->lumpnum); int separator = lumpname.IndexOf(':'); path << '/' << lumpname.Left(separator); @@ -1254,7 +1254,7 @@ errorout: CCMD(clearnodecache) { TArray list; - FString path = M_GetCachePath(); + FString path = M_GetCachePath(false); path += "/"; try From d36afb975ca7017920998998248e2f4f35b0229e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Sep 2013 08:57:22 +0200 Subject: [PATCH 004/311] - fixed the Linux portion of m_specialpaths.cpp which had a section of GetUserFile duplicated. --- src/m_specialpaths.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index cd116e538..469a2fa6b 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -461,36 +461,7 @@ FString M_GetSavegamesPath() #else // Linux, et al. -FString GetUserFile(const char *file) -{ - FString path; - struct stat info; - path = NicePath("~/" GAME_DIR "/"); - - if (stat(path, &info) == -1) - { - struct stat extrainfo; - - // Sanity check for ~/.config - FString configPath = NicePath("~/.config/"); - if (stat(configPath, &extrainfo) == -1) - { - if (mkdir(configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) - { - I_FatalError("Failed to create ~/.config directory:\n%s", strerror(errno)); - } - } - else if (!S_ISDIR(extrainfo.st_mode)) - { - I_FatalError("~/.config must be a directory"); - } - - // This can be removed after a release or two - // Transfer the old zdoom directory to the new location - bool moved = false; - FString oldpath = NicePath("~/.zdoom/"); - if (stat #if defined(__unix__) FString GetUserFile (const char *file) { FString path; From 8847d5649adf011ac5e8cb327e94554f04d2896f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Sep 2013 23:11:55 +0200 Subject: [PATCH 005/311] - fixed: Bridge needs to call Super::Destroy. --- src/g_shared/a_bridge.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index d669cc3bd..4caa56287 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -75,6 +75,7 @@ void ACustomBridge::Destroy() thing->Destroy(); } } + Super::Destroy(); } // Action functions for the non-Doom bridge -------------------------------- From 88b05fe2a10f20299a44ce7f23de7892489a552b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 17 Sep 2013 17:31:29 -0500 Subject: [PATCH 006/311] Fixed: SHGetKnownFolderPath needs to be declared as WINAPI. --- src/m_specialpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index cd116e538..469f7587e 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -15,7 +15,7 @@ #if defined(_WIN32) #include "version.h" // for GAMENAME -typedef HRESULT (*GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); +typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); //=========================================================================== // From e021fba5e1813636245baad445d260240da73a63 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 17 Sep 2013 20:44:13 -0500 Subject: [PATCH 007/311] Improve NoDelay reliability. - Instead of tying NoDelay behavior to OF_JustSpawned, use a new actor flag, MF7_HANDLENODELAY. This only gets cleared once it has actually been checked by Tick(). This is necessary because freeze mode delays the initial run of Tick() past the initial spawn, so OF_JustSpawned will no longer be set when it does the initial tick. - Delay NoDelay processing if an actor is spawned dormant. Actors spawned dormant have Deactivate() called before they tick, so MF7_HANDLENODELAY will remain set as long as an actor is dormant. This allows the NoDelay handling to occur as expected once it is activated. --- src/actor.h | 3 ++- src/dobject.h | 2 +- src/dthinker.cpp | 2 +- src/p_mobj.cpp | 27 ++++++++++++++++----------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/actor.h b/src/actor.h index c60b6a516..3a97ef49a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -334,11 +334,12 @@ enum MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup. MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts. -// --- mobj.flags6 --- +// --- mobj.flags7 --- MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered. MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO) MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings. + MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag // --- mobj.renderflags --- diff --git a/src/dobject.h b/src/dobject.h index 2ae5493c6..40b47ee5c 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -473,7 +473,7 @@ public: // use this method. virtual size_t PointerSubstitution (DObject *old, DObject *notOld); static size_t StaticPointerSubstitution (DObject *old, DObject *notOld); - + PClass *GetClass() const { if (Class == NULL) diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 15206dabd..327b29731 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -457,7 +457,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest) node->PostBeginPlay(); } else if (dest != NULL) - { // Move thinker from this list to the destination list + { I_Error("There is a thinker in the fresh list that has already ticked.\n"); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 13f9de0af..492dd3389 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3525,19 +3525,23 @@ void AActor::Tick () Destroy(); return; } - if (ObjectFlags & OF_JustSpawned && state->GetNoDelay()) + if ((flags7 & MF7_HANDLENODELAY) && !(flags2 & MF2_DORMANT)) { - // For immediately spawned objects with the NoDelay flag set for their - // Spawn state, explicitly set the current state so that it calls its - // action and chains 0-tic states. - int starttics = tics; - if (!SetState(state)) - return; // freed itself - // If the initial state had a duration of 0 tics, let the next state run - // normally. Otherwise, increment tics by 1 so that we don't double up ticks. - if (starttics > 0 && tics >= 0) + flags7 &= ~MF7_HANDLENODELAY; + if (state->GetNoDelay()) { - tics++; + // For immediately spawned objects with the NoDelay flag set for their + // Spawn state, explicitly set the current state so that it calls its + // action and chains 0-tic states. + int starttics = tics; + if (!SetState(state)) + return; // freed itself + // If the initial state had a duration of 0 tics, let the next state run + // normally. Otherwise, increment tics by 1 so that we don't double up ticks. + else if (starttics > 0 && tics >= 0) + { + tics++; + } } } // cycle through states, calling action functions at transitions @@ -4024,6 +4028,7 @@ void AActor::PostBeginPlay () Renderer->StateChanged(this); } PrevAngle = angle; + flags7 |= MF7_HANDLENODELAY; } void AActor::MarkPrecacheSounds() const From f591c5df5e3a1a18c8d737777d1f7f5f62835c20 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 18 Sep 2013 09:40:40 +0200 Subject: [PATCH 008/311] - fixed: saving the config to the user's known folders should use the GAME_DIR #define, not 'zdoom' so that child ports can have their own. --- src/m_specialpaths.cpp | 2 +- src/version.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 469a2fa6b..d9b776d58 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -195,7 +195,7 @@ FString M_GetConfigPath(bool for_reading) // Construct a user-specific config name if (UseKnownFolders() && GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true, path)) { - path += "/zdoom"; + path << '/' << GAME_DIR; CreatePath(path); path += "/zdoom.ini"; } diff --git a/src/version.h b/src/version.h index 5fee0bd83..b0717fbf8 100644 --- a/src/version.h +++ b/src/version.h @@ -95,6 +95,8 @@ const char *GetVersionString(); #define GAME_DIR ".config/zdoom" #elif defined(__APPLE__) #define GAME_DIR GAMENAME +#else +#define GAME_DIR "zdoom" #endif From e748c49dd0c672829d23ab31358e6671ebf5b215 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 17:29:42 -0500 Subject: [PATCH 009/311] - Fixed: m_specialpaths.cpp did not compile under Linux. --- src/m_specialpaths.cpp | 31 +++++++++++++++++++------------ src/version.h | 6 ++---- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 1f17f90c2..b4fcba3c3 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -12,9 +12,16 @@ #include "cmdlib.h" #include "m_misc.h" -#if defined(_WIN32) +#if !defined(__APPLE__) && !defined(_WIN32) +#include +#include +#include "i_system.h" +#endif #include "version.h" // for GAMENAME + +#if defined(_WIN32) + typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); //=========================================================================== @@ -195,7 +202,7 @@ FString M_GetConfigPath(bool for_reading) // Construct a user-specific config name if (UseKnownFolders() && GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true, path)) { - path << '/' << GAME_DIR; + path += "/" GAME_DIR; CreatePath(path); path += "/zdoom.ini"; } @@ -534,7 +541,7 @@ FString M_GetCachePath(bool create) FString path = NicePath("~/.config/zdoom/cache"); if (create) { - CreatePath(create); + CreatePath(path); } return path; } @@ -564,16 +571,16 @@ FString M_GetCajunPath(const char *botfilename) { FString path; - // Check first in ~/.config/zdoom./botfilename. - path = GetUserFile(BOTFILENAME); - if (!FileExists(tmp)) + // Check first in ~/.config/zdoom/botfilename. + path = GetUserFile(botfilename); + if (!FileExists(path)) { - // Then check in SHARE_DIR/botfilename. (Some allowance for Macs - // should probably be made here.) - path = SHARE_DIR BOTFILENAME; + // Then check in SHARE_DIR/botfilename. + path = SHARE_DIR; + path << botfilename; if (!FileExists(path)) { - path =""; + path = ""; } } return path; @@ -604,7 +611,7 @@ FString M_GetConfigPath(bool for_reading) FString M_GetScreenshotsPath() { - return "~/" GAME_DIR "/screenshots/"; + return NicePath("~/" GAME_DIR "/screenshots/"); } //=========================================================================== @@ -617,7 +624,7 @@ FString M_GetScreenshotsPath() FString M_GetSavegamesPath() { - return = "~/" GAME_DIR; + return NicePath("~/" GAME_DIR); } #endif diff --git a/src/version.h b/src/version.h index b0717fbf8..66e2f8938 100644 --- a/src/version.h +++ b/src/version.h @@ -91,12 +91,10 @@ const char *GetVersionString(); #define FORUM_URL "http://forum.zdoom.org" #define BUGS_FORUM_URL "http://forum.zdoom.org/index.php?c=3" -#ifdef __unix__ -#define GAME_DIR ".config/zdoom" -#elif defined(__APPLE__) +#if defined(__APPLE__) || defined(_WIN32) #define GAME_DIR GAMENAME #else -#define GAME_DIR "zdoom" +#define GAME_DIR ".config/zdoom" #endif From 285be8db926d3fc7ebc7af992f00171d3dbd7336 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 20:45:39 -0500 Subject: [PATCH 010/311] Fixed: wi_noautostartmap was not sync safe - Make wi_noautostartmap a userinfo cvar. This allows it to be communicated across the network and saved in demos. If any player has it set, then the intermission screen will not automatically advance to the next level. --- src/d_player.h | 4 ++++ src/namedef.h | 1 + src/wi_stuff.cpp | 25 +++++++++++++++++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 75ed533d9..69487070e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -325,6 +325,10 @@ struct userinfo_t : TMap { return *static_cast(*CheckKey(NAME_Gender)); } + bool GetNoAutostartMap() const + { + return *static_cast(*CheckKey(NAME_Wi_NoAutostartMap)); + } void Reset(); int TeamChanged(int team); diff --git a/src/namedef.h b/src/namedef.h index f7607400e..644d0deb4 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -568,3 +568,4 @@ xx(NeverSwitchOnPickup) xx(MoveBob) xx(StillBob) xx(PlayerClass) +xx(Wi_NoAutostartMap) \ No newline at end of file diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 6ae9148af..7aef939b1 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -62,7 +62,7 @@ typedef enum CVAR (Bool, wi_percents, true, CVAR_ARCHIVE) CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE) -CVAR (Bool, wi_noautostartmap, false, CVAR_ARCHIVE) +CVAR (Bool, wi_noautostartmap, false, CVAR_USERINFO|CVAR_ARCHIVE) void WI_loadData (); @@ -1098,11 +1098,28 @@ void WI_updateNoState () { WI_updateAnimatedBack(); + if (acceleratestage) + { + cnt = 0; + } + else + { + bool noauto = noautostartmap; - if (!wi_noautostartmap && !noautostartmap) cnt--; - if (acceleratestage) cnt=0; + for (int i = 0; !noauto && i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + { + noauto |= players[i].userinfo.GetNoAutostartMap(); + } + } + if (!noauto) + { + cnt--; + } + } - if (cnt==0) + if (cnt == 0) { WI_End(); G_WorldDone(); From 0cf68af7d26978b3c3623855ece6633d0ce56946 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:14:44 -0500 Subject: [PATCH 011/311] Overload operator = for player_t - This fixes crashes when quitting multiplayer games because the default byte-for-byte copy caused PredictionPlayerBackup and the console player to point to the exact same userinfo data and to both try and free it when they are deleted. --- src/d_netinfo.cpp | 1 + src/d_player.h | 1 + src/p_user.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 6832a047e..12fb187ae 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -1058,4 +1058,5 @@ userinfo_t::~userinfo_t() { delete pair->Value; } + this->Clear(); } diff --git a/src/d_player.h b/src/d_player.h index 69487070e..f6f7674d7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -352,6 +352,7 @@ class player_t { public: player_t(); + player_t &operator= (const player_t &p); void Serialize (FArchive &arc); size_t FixPointers (const DObject *obj, DObject *replacement); diff --git a/src/p_user.cpp b/src/p_user.cpp index e2c8b80c9..901f6cfaa 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -314,6 +314,115 @@ player_t::player_t() memset (&skill, 0, sizeof(skill)); } +player_t &player_t::operator=(const player_t &p) +{ + mo = p.mo; + playerstate = p.playerstate; + cmd = p.cmd; + original_cmd = p.original_cmd; + original_oldbuttons = p.original_oldbuttons; + // Intentionally not copying userinfo! + cls = p.cls; + DesiredFOV = p.DesiredFOV; + FOV = p.FOV; + viewz = p.viewz; + viewheight = p.viewheight; + deltaviewheight = p.deltaviewheight; + bob = p.bob; + velx = p.velx; + vely = p.vely; + centering = p.centering; + turnticks = p.turnticks; + attackdown = p.attackdown; + usedown = p.usedown; + oldbuttons = p.oldbuttons; + health = p.health; + inventorytics = p.inventorytics; + CurrentPlayerClass = p.CurrentPlayerClass; + backpack = p.backpack; + memcpy(frags, &p.frags, sizeof(frags)); + fragcount = p.fragcount; + lastkilltime = p.lastkilltime; + multicount = p.multicount; + spreecount = p.spreecount; + WeaponState = p.WeaponState; + ReadyWeapon = p.ReadyWeapon; + PendingWeapon = p.PendingWeapon; + cheats = p.cheats; + timefreezer = p.timefreezer; + refire = p.refire; + inconsistant = p.inconsistant; + waiting = p.waiting; + killcount = p.killcount; + itemcount = p.itemcount; + secretcount = p.secretcount; + damagecount = p.damagecount; + bonuscount = p.bonuscount; + hazardcount = p.hazardcount; + poisoncount = p.poisoncount; + poisontype = p.poisontype; + poisonpaintype = p.poisonpaintype; + poisoner = p.poisoner; + attacker = p.attacker; + extralight = p.extralight; + fixedcolormap = p.fixedcolormap; + fixedlightlevel = p.fixedlightlevel; + memcpy(psprites, &p.psprites, sizeof(psprites)); + morphTics = p.morphTics; + MorphedPlayerClass = p.MorphedPlayerClass; + MorphStyle = p.MorphStyle; + MorphExitFlash = p.MorphExitFlash; + PremorphWeapon = p.PremorphWeapon; + chickenPeck = p.chickenPeck; + jumpTics = p.jumpTics; + respawn_time = p.respawn_time; + camera = p.camera; + air_finished = p.air_finished; + LastDamageType = p.LastDamageType; + savedyaw = p.savedyaw; + savedpitch = p.savedpitch; + angle = p.angle; + dest = p.dest; + prev = p.prev; + enemy = p.enemy; + missile = p.missile; + mate = p.mate; + last_mate = p.last_mate; + settings_controller = p.settings_controller; + skill = p.skill; + t_active = p.t_active; + t_respawn = p.t_respawn; + t_strafe = p.t_strafe; + t_react = p.t_react; + t_fight = p.t_fight; + t_roam = p.t_roam; + t_rocket = p.t_rocket; + isbot = p.isbot; + first_shot = p.first_shot; + sleft = p.sleft; + allround = p.allround; + oldx = p.oldx; + oldy = p.oldy; + BlendR = p.BlendR; + BlendG = p.BlendG; + BlendB = p.BlendB; + BlendA = p.BlendA; + LogText = p.LogText; + MinPitch = p.MinPitch; + MaxPitch = p.MaxPitch; + crouching = p.crouching; + crouchdir = p.crouchdir; + crouchfactor = p.crouchfactor; + crouchoffset = p.crouchoffset; + crouchviewdelta = p.crouchviewdelta; + weapons = p.weapons; + ConversationNPC = p.ConversationNPC; + ConversationPC = p.ConversationPC; + ConversationNPCAngle = p.ConversationNPCAngle; + ConversationFaceTalker = p.ConversationFaceTalker; + return *this; +} + // This function supplements the pointer cleanup in dobject.cpp, because // player_t is not derived from DObject. (I tried it, and DestroyScan was // unable to properly determine the player object's type--possibly From d05cdb79ef9b25ad8aac0d66012209c20b9d89bc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:22:21 -0500 Subject: [PATCH 012/311] Switch true to LAF_ISMELEEATTACK inside A_Punch's call to P_LineAttack() --- src/g_doom/a_doomweaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 9dd055711..368d7ce8b 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) angle += pr_punch.Random2() << 18; pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); - P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget); + P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &linetarget); // turn to face target if (linetarget) From a7a7d5d6b3dc5075ea5c82b7b50ac2c12dbadfa4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:25:00 -0500 Subject: [PATCH 013/311] Add missing prantheses for A_CustomPunch's puffFlags calculation - Fixed: Need parentheses for precedence when setting puffFlags in A_CustomPunch. Otherwise, it's completely broken. --- src/thingdef/thingdef_codeptr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f5ef45f45..c97aee39c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1404,7 +1404,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) } if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff); - int puffFlags = LAF_ISMELEEATTACK | (flags & CPF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; + int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0); P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage); @@ -1426,7 +1426,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED; if (flags & CPF_DAGGER) P_DaggerAlert (self, linetarget); - } } From e3741c809752f67d07a9004df823849ae5b55d0e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:29:19 -0500 Subject: [PATCH 014/311] GetSelectedSize() needs to check for a valid selection. - With mouse navigation, there's no guarantee that there even is a selected item. --- src/menu/videomenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 8a6e6720d..f26b90704 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -348,7 +348,7 @@ void M_InitVideoModesMenu () static bool GetSelectedSize (int *width, int *height) { FOptionMenuDescriptor *opt = GetVideoModeMenu(); - if (opt != NULL) + if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size()) { int line = opt->mSelectedItem; int hsel; From 75535fba727d0aa9c733c4ee4cf9d32d1d75ab93 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:32:46 -0500 Subject: [PATCH 015/311] Do not enter testing mode if a valid mode is not selected. - It doesn't make much sense to "test" the current mode if a non-video mode is selected in the menu, so don't. --- src/menu/videomenu.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index f26b90704..1d1d02383 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -166,15 +166,18 @@ public: NewWidth = SCREENWIDTH; NewHeight = SCREENHEIGHT; } - OldWidth = SCREENWIDTH; - OldHeight = SCREENHEIGHT; - OldBits = DisplayBits; - NewBits = BitTranslate[DummyDepthCvar]; - setmodeneeded = true; - testingmode = I_GetTime(false) + 5 * TICRATE; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - SetModesMenu (NewWidth, NewHeight, NewBits); - return true; + else + { + OldWidth = SCREENWIDTH; + OldHeight = SCREENHEIGHT; + OldBits = DisplayBits; + NewBits = BitTranslate[DummyDepthCvar]; + setmodeneeded = true; + testingmode = I_GetTime(false) + 5 * TICRATE; + S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + SetModesMenu (NewWidth, NewHeight, NewBits); + return true; + } } return Super::Responder(ev); } From ad7aefff20b4047b5bac744a13743dcba24cc775 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:37:51 -0500 Subject: [PATCH 016/311] - Fixed: Do not apply AVOIDMELEE logic when moving toward a goal --- src/p_enemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 81a58ac15..359b49f9c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -915,7 +915,7 @@ void P_NewChaseDir(AActor * actor) // MBF's monster_backing option. Made an actor flag instead. Also cleaned the code up to make it readable. // Todo: implement the movement logic AActor *target = actor->target; - if (target->health > 0 && !actor->IsFriend(target)) + if (target->health > 0 && !actor->IsFriend(target) && target != actor->goal) { // Live enemy target if (actor->flags3 & MF3_AVOIDMELEE) From 5850279090bc29f3f76811baaf719eb319bdf1bc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 22:03:59 -0500 Subject: [PATCH 017/311] - Fixed: Thing_SetGoal could put an actor's target and goal out of sync. If an actor is already targeting a goal, and Thing_SetGoal is used on it, it would still be left targeting the old goal instead of the new one. This messed up checks in A_Chase for walking towards a goal vs a real target. --- src/p_lnspec.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 869fd5169..12c877116 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1562,9 +1562,21 @@ FUNC(LS_Thing_SetGoal) ok = true; if (self->flags & MF_SHOOTABLE) { + if (self->target == self->goal) + { // Targeting a goal already? -> don't target it anymore. + // A_Look will set it to the goal, presuming no real targets + // come into view by then. + self->target = NULL; + } self->goal = goal; - if (arg3 == 0) self->flags5 &=~ MF5_CHASEGOAL; - else self->flags5 |= MF5_CHASEGOAL; + if (arg3 == 0) + { + self->flags5 &= ~MF5_CHASEGOAL; + } + else + { + self->flags5 |= MF5_CHASEGOAL; + } if (self->target == NULL) { self->reactiontime = arg2 * TICRATE; From a144221174b99341051f26af21b39c4da8e450de Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 20 Sep 2013 10:43:10 +0200 Subject: [PATCH 018/311] - changed the invisible waiting frame of the ExplosiveBarrel to use TNTA10 instead of the real barrel frame. This is so that sprite checks do not erroneously determine that there's still something to see. GZDoom's dynamic light code has problems with this. --- wadsrc/static/actors/doom/doommisc.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/actors/doom/doommisc.txt b/wadsrc/static/actors/doom/doommisc.txt index 131bb273d..fadab2b05 100644 --- a/wadsrc/static/actors/doom/doommisc.txt +++ b/wadsrc/static/actors/doom/doommisc.txt @@ -27,8 +27,8 @@ ACTOR ExplosiveBarrel 2035 BEXP C 5 BRIGHT BEXP D 5 BRIGHT A_Explode BEXP E 10 BRIGHT - BEXP E 1050 BRIGHT A_BarrelDestroy - BEXP E 5 A_Respawn + TNT1 A 1050 BRIGHT A_BarrelDestroy + TNT1 A 5 A_Respawn Wait } } From f73275ad8892fc6ce46d78b1318e6966ee5e8d44 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 21 Sep 2013 12:46:19 -0400 Subject: [PATCH 019/311] - Applied Tesseract's patch for drawimage extensions. (Extended icon support and maximum width/height.) --- src/g_shared/sbar.h | 16 ++- src/g_shared/sbarinfo.cpp | 8 +- src/g_shared/sbarinfo_commands.cpp | 165 +++++++++++++++++++++++------ src/g_shared/shared_hud.cpp | 48 ++++++--- 4 files changed, 188 insertions(+), 49 deletions(-) diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 3d8c62001..b8dde5850 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -444,6 +444,20 @@ void ST_LoadCrosshair(bool alwaysload=false); void ST_Clear(); extern FTexture *CrosshairImage; -FTextureID GetWeaponIcon(AWeapon *weapon); +FTextureID GetInventoryIcon(AInventory *item, DWORD flags, bool *applyscale); + +enum DI_Flags +{ + DI_SKIPICON = 0x1, + DI_SKIPALTICON = 0x2, + DI_SKIPSPAWN = 0x4, + DI_SKIPREADY = 0x8, + DI_ALTICONFIRST = 0x10, + + DI_DRAWINBOX = 0x20, // Set when either width or height is not zero + + DI_FORCESCALE = 0x40, + DI_ALTERNATEONFAIL = 0x80 +}; #endif /* __SBAR_H__ */ diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 09be47363..3e1c364e2 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -1187,8 +1187,12 @@ public: if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER) { - dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); - dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); + if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); + else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble()/texture->GetScaledWidthDouble())); + //Unoptimalized formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble()); + + if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); + else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble()/texture->GetScaledHeightDouble())); } dx += xOffset; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index febf32b80..d5ee06d11 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -41,28 +41,65 @@ // classes. //////////////////////////////////////////////////////////////////////////////// - -class CommandDrawImage : public SBarInfoCommand +class CommandDrawImage : public SBarInfoCommandFlowControl { public: - CommandDrawImage(SBarInfo *script) : SBarInfoCommand(script), - translatable(false), type(NORMAL_IMAGE), image(-1), offset(static_cast (TOP|LEFT)), + CommandDrawImage(SBarInfo *script) : SBarInfoCommandFlowControl(script), + translatable(false), type(NORMAL_IMAGE), image(-1), maxwidth(-1), + maxheight(-1), spawnScaleX(1.0f), spawnScaleY(1.0f), flags(0), + applyscale(false), offset(static_cast (TOP|LEFT)), texture(NULL), alpha(FRACUNIT) { } void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) { + if(flags & DI_ALTERNATEONFAIL) + SBarInfoCommandFlowControl::Draw(block, statusBar); + if(texture == NULL) return; + int w = maxwidth, h = maxheight; + // We must calculate this per frame in order to prevent glitches with cl_capfps true. fixed_t frameAlpha = block->Alpha(); if(alpha != FRACUNIT) frameAlpha = fixed_t(((double) block->Alpha() / (double) FRACUNIT) * ((double) alpha / (double) OPAQUE) * FRACUNIT); - + + if(flags & DI_DRAWINBOX) + { + double scale1, scale2; + scale1 = scale2 = 1.0f; + double texwidth = (int) (texture->GetScaledWidthDouble()*spawnScaleX); + double texheight = (int) (texture->GetScaledHeightDouble()*spawnScaleY); + + if (w != -1 && (wGetScaledWidthDouble()*spawnScaleX); + h=(int) (texture->GetScaledHeightDouble()*spawnScaleY); + } statusBar->DrawGraphic(texture, imgx, imgy, block->XOffset(), block->YOffset(), frameAlpha, block->FullScreenOffsets(), - translatable, false, offset); + translatable, false, offset, false, w, h); } void Parse(FScanner &sc, bool fullScreenOffsets) { @@ -98,7 +135,7 @@ class CommandDrawImage : public SBarInfoCommand type = HEXENARMOR_AMULET; else { - sc.ScriptMessage("Unkown armor type: '%s'", sc.String); + sc.ScriptMessage("Unknown armor type: '%s'", sc.String); type = HEXENARMOR_ARMOR; } sc.MustGetToken(','); @@ -141,48 +178,90 @@ class CommandDrawImage : public SBarInfoCommand offset = CENTER; else if(sc.Compare("centerbottom")) offset = static_cast (HMIDDLE|BOTTOM); - else + else if(!sc.Compare("lefttop")) //That's already set sc.ScriptError("'%s' is not a valid alignment.", sc.String); } - sc.MustGetToken(';'); + if(sc.CheckToken(',')) + { + sc.MustGetToken(TK_IntConst); + if((maxwidth = sc.Number) > 0) + flags |= DI_DRAWINBOX; + else + maxwidth = -1; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + if ((maxheight = sc.Number) > 0) + flags |= DI_DRAWINBOX; + else + maxheight = -1; + } + if(sc.CheckToken(',')) + { + while(sc.CheckToken(TK_Identifier)) + { + if(sc.Compare("skipicon")) + flags |= DI_SKIPICON; + else if(sc.Compare("skipalticon")) + flags |= DI_SKIPALTICON; + else if(sc.Compare("skipspawn")) + flags |= DI_SKIPSPAWN; + else if(sc.Compare("skipready")) + flags |= DI_SKIPREADY; + else if(sc.Compare("alticonfirst")) + flags |= DI_ALTICONFIRST; + else if(sc.Compare("forcescale")) + { + if(flags & DI_DRAWINBOX) + flags |= DI_FORCESCALE; + } + else if(sc.Compare("alternateonfail")) + flags |= DI_ALTERNATEONFAIL; + else + sc.ScriptError("Unknown flag '%s'.", sc.String); + if(!sc.CheckToken('|') && !sc.CheckToken(',')) break; + } + } + if(flags & DI_ALTERNATEONFAIL) + SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets); + else + sc.MustGetToken(';'); } void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) { + SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); + texture = NULL; alpha = FRACUNIT; + if (applyscale) + { + spawnScaleX = spawnScaleY = 1.0f; + applyscale = false; + } if(type == PLAYERICON) texture = TexMan[statusBar->CPlayer->mo->ScoreIcon]; else if(type == AMMO1) { - if(statusBar->ammo1 != NULL) - texture = TexMan[statusBar->ammo1->Icon]; + AAmmo *ammo = statusBar->ammo1; + if(ammo != NULL) + GetIcon(ammo); } else if(type == AMMO2) { - if(statusBar->ammo2 != NULL) - texture = TexMan[statusBar->ammo2->Icon]; + AAmmo *ammo = statusBar->ammo2; + if(ammo != NULL) + GetIcon(ammo); } else if(type == ARMOR) { - if(statusBar->armor != NULL && statusBar->armor->Amount != 0) - texture = TexMan(statusBar->armor->Icon); + ABasicArmor *armor = statusBar->armor; + if(armor != NULL && armor->Amount != 0) + GetIcon(armor); } else if(type == WEAPONICON) { AWeapon *weapon = statusBar->CPlayer->ReadyWeapon; if(weapon != NULL) - { - FTextureID icon; - if (weapon->Icon.isValid()) - { - icon = weapon->Icon; - } - else - { - icon = GetWeaponIcon(weapon); - } - texture = TexMan[icon]; - } + GetIcon(weapon); } else if(type == SIGIL) { @@ -213,8 +292,26 @@ class CommandDrawImage : public SBarInfoCommand texture = TexMan(statusBar->CPlayer->mo->InvSel->Icon); else if(image >= 0) texture = statusBar->Images[image]; + + if (flags & DI_ALTERNATEONFAIL) + { + SetTruth(texture == NULL || !(texture->GetID().isValid()), block, statusBar); + } } protected: + void GetIcon(AInventory *item) + { + FTextureID icon = GetInventoryIcon(item, flags, &applyscale); + + if (applyscale) + { + spawnScaleX = FIXED2FLOAT(item->scaleX); + spawnScaleY = FIXED2FLOAT(item->scaleY); + } + + texture = TexMan[icon]; + } + enum ImageType { PLAYERICON, @@ -238,6 +335,12 @@ class CommandDrawImage : public SBarInfoCommand ImageType type; int image; FTextureID sprite; + int maxwidth; + int maxheight; + double spawnScaleX; + double spawnScaleY; + DWORD flags; + bool applyscale; //Set remotely from from GetInventoryIcon when selected sprite comes from Spawn state // I'm using imgx/imgy here so that I can inherit drawimage with drawnumber for some commands. SBarInfoCoordinate imgx; SBarInfoCoordinate imgy; @@ -1479,11 +1582,11 @@ class CommandDrawMugShot : public SBarInfoCommand //////////////////////////////////////////////////////////////////////////////// -class CommandDrawSelectedInventory : public SBarInfoCommandFlowControl, private CommandDrawImage, private CommandDrawNumber +class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDrawNumber { public: - CommandDrawSelectedInventory(SBarInfo *script) : SBarInfoCommandFlowControl(script), - CommandDrawImage(script), CommandDrawNumber(script), alternateOnEmpty(false), + CommandDrawSelectedInventory(SBarInfo *script) : CommandDrawImage(script), + CommandDrawNumber(script), alternateOnEmpty(false), artiflash(false), alwaysShowCounter(false) { length = INT_MAX; // Counter size @@ -3011,7 +3114,7 @@ class CommandDrawGem : public SBarInfoCommand else sc.ScriptError("Unknown drawgem flag '%s'.", sc.String); if(!sc.CheckToken('|')) - sc.MustGetToken(','); + sc.MustGetToken(','); } sc.MustGetToken(TK_StringConst); //chain chain = script->newImage(sc.String); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 3416bb82d..964a28e2b 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -135,12 +135,12 @@ static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, int trans if (tex) { - int texwidth=tex->GetWidth(); - int texheight=tex->GetHeight(); + double texwidth=tex->GetScaledWidthDouble(); + double texheight=tex->GetScaledHeightDouble(); - if (wGetClass()); + FTextureID picnum, AltIcon = GetHUDIcon(item->GetClass()); FState * state=NULL, *ReadyState; - FTextureID picnum = !AltIcon.isNull()? AltIcon : weapon->Icon; - - if (picnum.isNull()) + picnum.SetNull(); + if (flags & DI_ALTICONFIRST) { - if (weapon->SpawnState && weapon->SpawnState->sprite!=0) + if (!(flags & DI_SKIPALTICON) && AltIcon.isValid()) + picnum = AltIcon; + else if (!(flags & DI_SKIPICON)) + picnum = item->Icon; + } + else + { + if (!(flags & DI_SKIPICON) && item->Icon.isValid()) + picnum = item->Icon; + else if (!(flags & DI_SKIPALTICON)) + picnum = AltIcon; + } + + if (!picnum.isValid()) //isNull() is bad for checking, because picnum could be also invalid (-1) + { + if (!(flags & DI_SKIPSPAWN) && item->SpawnState && item->SpawnState->sprite!=0) { - state = weapon->SpawnState; + state = item->SpawnState; + + if (applyscale != NULL && !(flags & DI_FORCESCALE)) + { + *applyscale = true; + } } - // no spawn state - now try the ready state - else if ((ReadyState = weapon->FindState(NAME_Ready)) && ReadyState->sprite!=0) + // no spawn state - now try the ready state if it's weapon + else if (!(flags & DI_SKIPREADY) && item->GetClass()->IsDescendantOf(RUNTIME_CLASS(AWeapon)) && (ReadyState = item->FindState(NAME_Ready)) && ReadyState->sprite!=0) { state = ReadyState; } @@ -651,7 +669,7 @@ static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) if (weapon==CPlayer->ReadyWeapon || weapon==CPlayer->ReadyWeapon->SisterWeapon) trans=0xd999; } - FTextureID picnum = GetWeaponIcon(weapon); + FTextureID picnum = GetInventoryIcon(weapon, DI_ALTICONFIRST); if (picnum.isValid()) { From e8bcbd14fbbac6e407f1b85553024b9302da6ee3 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 21 Sep 2013 13:20:36 -0400 Subject: [PATCH 020/311] - Added vid_asyncblit for Linux and OS X. It defaults to true and sets SDL_AYNCBLIT on the frame buffer. This allows for ZDoom to obtain ~100% CPU usage with an uncapped frame rate on Linux like it should. (Not sure if it does anything for OS X yet.) It also makes uncapped play smoothly for me (as long as the frame rate is >= 2*refresh rate), but I'm not sure if capped feels more jittery or not. I could use some feedback here. Do note that vid_asyncblit requires a restart after the value is changed. --- src/sdl/i_video.h | 64 ----------------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 src/sdl/i_video.h diff --git a/src/sdl/i_video.h b/src/sdl/i_video.h deleted file mode 100644 index 2865df02f..000000000 --- a/src/sdl/i_video.h +++ /dev/null @@ -1,64 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// DESCRIPTION: -// System specific interface stuff. -// -//----------------------------------------------------------------------------- - - -#ifndef __I_VIDEO_H__ -#define __I_VIDEO_H__ - -#include "basictypes.h" - -class DCanvas; - -// [RH] Set the display mode -void I_SetMode (int &width, int &height, int &bits); - -// Takes full 8 bit values. -void I_SetPalette (DWORD *palette); - -void I_BeginUpdate (void); // [RH] Locks screen[0] -void I_FinishUpdate (void); -void I_FinishUpdateNoBlit (void); - -// Wait for vertical retrace or pause a bit. -void I_WaitVBL(int count); - -void I_ReadScreen (BYTE *scr); - -bool I_CheckResolution (int width, int height, int bits); -void I_ClosestResolution (int *width, int *height, int bits); -bool I_SetResolution (int width, int height, int bits); - -bool I_AllocateScreen (DCanvas *canvas, int width, int height, int bits); -void I_FreeScreen (DCanvas *canvas); - -void I_LockScreen (DCanvas *canvas); -void I_UnlockScreen (DCanvas *canvas); -void I_Blit (DCanvas *from, int srcx, int srcy, int srcwidth, int srcheight, - DCanvas *to, int destx, int desty, int destwidth, int destheight); - -enum EDisplayType -{ - DISPLAY_WindowOnly, - DISPLAY_FullscreenOnly, - DISPLAY_Both -}; - -#endif // __I_VIDEO_H__ From 658b4f7e0ff4bf723105fbafe993cfcd8fbc5964 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 21 Sep 2013 15:30:32 -0400 Subject: [PATCH 021/311] - For some reason git decided not to include the actual changes for the last commit. --- src/sdl/sdlvideo.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index 2f11b8bbd..92741d325 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -87,6 +87,10 @@ EXTERN_CVAR (Bool, cl_capfps) CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +// vid_asyncblit needs a restart to work. SDL doesn't seem to change if the +// frame buffer is changed at run time. +CVAR (Bool, vid_asyncblit, 1, CVAR_NOINITCALL|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (screen != NULL) @@ -301,9 +305,8 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) UpdatePending = false; NotPaletted = false; FlashAmount = 0; - Screen = SDL_SetVideoMode (width, height, vid_displaybits, - SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_ANYFORMAT| + (vid_asyncblit ? SDL_ASYNCBLIT : 0)|SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_ANYFORMAT| (fullscreen ? SDL_FULLSCREEN : 0)); if (Screen == NULL) From ffae34c5fd0977938bf46b673397b17c58bc99e7 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 30 Sep 2013 20:02:05 -0400 Subject: [PATCH 022/311] - Changed the new default alignment keyword for drawimage from topleft to none in order to allow a potential topleft without image offsets. --- src/g_shared/sbarinfo_commands.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index d5ee06d11..449079ab5 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -173,13 +173,18 @@ class CommandDrawImage : public SBarInfoCommandFlowControl GetCoordinates(sc, fullScreenOffsets, imgx, imgy); if(sc.CheckToken(',')) { - sc.MustGetToken(TK_Identifier); - if(sc.Compare("center")) - offset = CENTER; - else if(sc.Compare("centerbottom")) - offset = static_cast (HMIDDLE|BOTTOM); - else if(!sc.Compare("lefttop")) //That's already set - sc.ScriptError("'%s' is not a valid alignment.", sc.String); + // Use none instead of topleft in case we decide we want to use + // alignments to remove the offset from images. + if(!sc.CheckToken(TK_None)) + { + sc.MustGetToken(TK_Identifier); + if(sc.Compare("center")) + offset = CENTER; + else if(sc.Compare("centerbottom")) + offset = static_cast (HMIDDLE|BOTTOM); + else + sc.ScriptError("'%s' is not a valid alignment.", sc.String); + } } if(sc.CheckToken(',')) { From f386d6b1e3c2311e664dc6385c018ad39eb67edd Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 6 Oct 2013 14:37:51 -0400 Subject: [PATCH 023/311] - Embed the proper manifest file and group soure files when building Visual Studio projects with CMake. (The groups probably also apply to other project types as well.) --- src/CMakeLists.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4223598f5..4a05c8278 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -999,4 +999,35 @@ endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" S if( MSVC ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") + add_custom_command(TARGET zdoom POST_BUILD + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#2 + COMMENT "Adding manifest..." + ) endif( MSVC ) + +source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+") +source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/oplsynth/.+") +source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.h oplsynth/dosbox/opl.cpp) +source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$") +source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$") +source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+") +source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+") +source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+") +source_group("Games\\Heretic Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_heretic/.+") +source_group("Games\\Hexen Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_hexen/.+") +source_group("Games\\Raven Shared" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_raven/.+") +source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_strife/.+") +source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") +source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") +source_group("Render Core\\Render Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.h$") +source_group("Render Core\\Render Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.cpp$") +source_group("Render Data\\Resource Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.h$") +source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.cpp$") +source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") +source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) +source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") +source_group("SFML" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+") +source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+") +source_group("Versioning" FILES version.h win32/zdoom.rc) +source_group("Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+") +source_group("Xlat" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/xlat/.+") From c4d2a021b0cbf421158414555a48a8f8240e9609 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 7 Oct 2013 11:53:58 +0200 Subject: [PATCH 024/311] - fixed: AInventory::BecomePickup must not restore the MF_COUNTITEM flag when transforming the inventory item into a pickup again. --- src/g_shared/a_pickups.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index bba5cfdc7..3ebcedb40 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -785,7 +785,7 @@ void AInventory::BecomePickup () LinkToWorld (); P_FindFloorCeiling (this); } - flags = GetDefault()->flags | MF_DROPPED; + flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM; renderflags &= ~RF_INVISIBLE; SetState (SpawnState); } From 4ced90756acc631ee0285bc510c953ab662ccde6 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 8 Oct 2013 15:35:50 -0400 Subject: [PATCH 025/311] - Let CMake know about noncompiled cpp files so they can appear in project files. - Fixed: Somehow when I added a way to disable generator expressions I inverted the meaning of NO_GENERATOR_EXPRESSIONS. --- CMakeLists.txt | 6 +- src/CMakeLists.txt | 182 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 150 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0858ecab5..087535b69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,16 +19,16 @@ function( add_pk3 PK3_NAME PK3_DIR ) set( PK3_TARGET "pk3" ) endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) - if( NO_GENERATOR_EXPRESSIONS ) + if( NOT NO_GENERATOR_EXPRESSIONS ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $ DEPENDS zipdir ${PK3_DIR} ) - else( NO_GENERATOR_EXPRESSIONS ) + else( NOT NO_GENERATOR_EXPRESSIONS ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} DEPENDS zipdir ${PK3_DIR} ) - endif( NO_GENERATOR_EXPRESSIONS ) + endif( NOT NO_GENERATOR_EXPRESSIONS ) add_custom_target( ${PK3_TARGET} ALL DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a05c8278..708e562c4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -511,29 +511,46 @@ if( FLUIDSYNTH_FOUND ) endif( FLUIDSYNTH_FOUND ) # Start defining source files for ZDoom - +set( PLAT_WIN32_SOURCES + win32/eaxedit.cpp + win32/fb_d3d9.cpp + win32/fb_d3d9_wipe.cpp + win32/fb_ddraw.cpp + win32/hardware.cpp + win32/helperthread.cpp + win32/i_cd.cpp + win32/i_crash.cpp + win32/i_input.cpp + win32/i_keyboard.cpp + win32/i_mouse.cpp + win32/i_dijoy.cpp + win32/i_rawps2.cpp + win32/i_xinput.cpp + win32/i_main.cpp + win32/i_movie.cpp + win32/i_system.cpp + win32/st_start.cpp + win32/win32video.cpp ) +set( PLAT_SDL_SOURCES + sdl/crashcatcher.c + sdl/hardware.cpp + sdl/i_cd.cpp + sdl/i_input.cpp + sdl/i_joystick.cpp + sdl/i_main.cpp + sdl/i_movie.cpp + sdl/i_system.cpp + sdl/sdlvideo.cpp + sdl/st_start.cpp ) +set( PLAT_MAC_SOURCES + sdl/SDLMain.m + sdl/iwadpicker_cocoa.mm + sdl/i_system_cocoa.mm ) if( WIN32 ) set( SYSTEM_SOURCES_DIR win32 ) - set( SYSTEM_SOURCES - win32/eaxedit.cpp - win32/fb_d3d9.cpp - win32/fb_d3d9_wipe.cpp - win32/fb_ddraw.cpp - win32/hardware.cpp - win32/helperthread.cpp - win32/i_cd.cpp - win32/i_crash.cpp - win32/i_input.cpp - win32/i_keyboard.cpp - win32/i_mouse.cpp - win32/i_dijoy.cpp - win32/i_rawps2.cpp - win32/i_xinput.cpp - win32/i_main.cpp - win32/i_movie.cpp - win32/i_system.cpp - win32/st_start.cpp - win32/win32video.cpp ) + set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ) + if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) # CMake is not set up to compile and link rc files with GCC. :( add_custom_command( OUTPUT zdoom-rc.o @@ -545,19 +562,12 @@ if( WIN32 ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) else( WIN32 ) set( SYSTEM_SOURCES_DIR sdl ) - set( SYSTEM_SOURCES - sdl/crashcatcher.c - sdl/hardware.cpp - sdl/i_cd.cpp - sdl/i_input.cpp - sdl/i_joystick.cpp - sdl/i_main.cpp - sdl/i_movie.cpp - sdl/i_system.cpp - sdl/sdlvideo.cpp - sdl/st_start.cpp ) + set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) if( APPLE ) - set( SYSTEM_SOURCES ${SYSTEM_SOURCES} sdl/SDLMain.m sdl/iwadpicker_cocoa.mm sdl/i_system_cocoa.mm ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_MAC_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) + else( APPLE ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} ) endif( APPLE ) endif( WIN32 ) @@ -627,8 +637,10 @@ file( GLOB HEADER_FILES intermission/*.h menu/*.h oplsynth/*.h + oplsynth/dosbox/*.h r_data/*.h resourcefiles/*.h + sdl/*.h sfmt/*.h sound/*.h textures/*.h @@ -637,8 +649,103 @@ file( GLOB HEADER_FILES *.h ) +# These files will be flagged as "headers" so that they appear in project files +# without being compiled. +set( NOT_COMPILED_SOURCE_FILES + ${OTHER_SYSTEM_SOURCES} + sc_man_scanner.h + sc_man_scanner.re + g_doom/a_arachnotron.cpp + g_doom/a_archvile.cpp + g_doom/a_bossbrain.cpp + g_doom/a_bruiser.cpp + g_doom/a_cacodemon.cpp + g_doom/a_cyberdemon.cpp + g_doom/a_demon.cpp + g_doom/a_doomimp.cpp + g_doom/a_doomweaps.cpp + g_doom/a_fatso.cpp + g_doom/a_keen.cpp + g_doom/a_lostsoul.cpp + g_doom/a_painelemental.cpp + g_doom/a_possessed.cpp + g_doom/a_revenant.cpp + g_doom/a_scriptedmarine.cpp + g_doom/a_spidermaster.cpp + g_heretic/a_chicken.cpp + g_heretic/a_dsparil.cpp + g_heretic/a_hereticartifacts.cpp + g_heretic/a_hereticimp.cpp + g_heretic/a_hereticweaps.cpp + g_heretic/a_ironlich.cpp + g_heretic/a_knight.cpp + g_heretic/a_wizard.cpp + g_hexen/a_bats.cpp + g_hexen/a_bishop.cpp + g_hexen/a_blastradius.cpp + g_hexen/a_boostarmor.cpp + g_hexen/a_centaur.cpp + g_hexen/a_clericflame.cpp + g_hexen/a_clericholy.cpp + g_hexen/a_clericmace.cpp + g_hexen/a_clericstaff.cpp + g_hexen/a_dragon.cpp + g_hexen/a_fighteraxe.cpp + g_hexen/a_fighterhammer.cpp + g_hexen/a_fighterplayer.cpp + g_hexen/a_fighterquietus.cpp + g_hexen/a_firedemon.cpp + g_hexen/a_flechette.cpp + g_hexen/a_fog.cpp + g_hexen/a_healingradius.cpp + g_hexen/a_heresiarch.cpp + g_hexen/a_hexenspecialdecs.cpp + g_hexen/a_iceguy.cpp + g_hexen/a_korax.cpp + g_hexen/a_magecone.cpp + g_hexen/a_magelightning.cpp + g_hexen/a_magestaff.cpp + g_hexen/a_pig.cpp + g_hexen/a_serpent.cpp + g_hexen/a_spike.cpp + g_hexen/a_summon.cpp + g_hexen/a_teleportother.cpp + g_hexen/a_wraith.cpp + g_strife/a_acolyte.cpp + g_strife/a_alienspectres.cpp + g_strife/a_coin.cpp + g_strife/a_crusader.cpp + g_strife/a_entityboss.cpp + g_strife/a_inquisitor.cpp + g_strife/a_oracle.cpp + g_strife/a_programmer.cpp + g_strife/a_reaver.cpp + g_strife/a_rebels.cpp + g_strife/a_sentinel.cpp + g_strife/a_stalker.cpp + g_strife/a_strifeitems.cpp + g_strife/a_strifeweapons.cpp + g_strife/a_templar.cpp + g_strife/a_thingstoblowup.cpp + g_shared/sbarinfo_commands.cpp + xlat/xlat_parser.y + xlat_parser.c + xlat_parser.h + + # We could have the ASM macro add these files, but it wouldn't add all + # platforms. + asm_ia32/a.asm + asm_ia32/misc.asm + asm_ia32/tmap.asm + asm_ia32/tmap2.asm + asm_ia32/tmap3.asm + asm_x86_64/tmap3.asm + asm_x86_64/tmap3.s +) + add_executable( zdoom WIN32 ${HEADER_FILES} + ${NOT_COMPILED_SOURCE_FILES} autostart.cpp ${ASM_SOURCES} ${SYSTEM_SOURCES} @@ -948,6 +1055,7 @@ add_executable( zdoom WIN32 set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( 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 ) if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") # [BL] Solaris requires these to be explicitly linked. @@ -1005,9 +1113,11 @@ if( MSVC ) ) endif( MSVC ) +source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+") +source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+") source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+") source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/oplsynth/.+") -source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.h oplsynth/dosbox/opl.cpp) +source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h) source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$") source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$") source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+") @@ -1026,8 +1136,10 @@ source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURREN source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") +source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sdl/.+") source_group("SFML" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+") source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+") source_group("Versioning" FILES version.h win32/zdoom.rc) source_group("Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+") -source_group("Xlat" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/xlat/.+") +source_group("Xlat" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/xlat/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h) +source_group("Source Files" FILES ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h sc_man_scanner.re) From d558cf51a9819723969b18d715a9162982c8a7ca Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 8 Oct 2013 19:59:46 -0500 Subject: [PATCH 026/311] - Fixed: ABackpackItem::CreateTossable did not check for failure from the supermethod. --- src/g_shared/a_pickups.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 3ebcedb40..cc559ea94 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1792,7 +1792,10 @@ bool ABackpackItem::HandlePickup (AInventory *item) AInventory *ABackpackItem::CreateTossable () { ABackpackItem *pack = static_cast(Super::CreateTossable()); - pack->bDepleted = true; + if (pack != NULL) + { + pack->bDepleted = true; + } return pack; } From 3c376aa342994971e0e3f578476e8085d346cdf1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 8 Oct 2013 20:18:35 -0500 Subject: [PATCH 027/311] Move C_ExecCmdLineParams() call slightly later in the startup process. - Fixed: You could not set any CVARINFO-defined cvars from the command line because command line console commands were executed before wads were even loaded. Off the top of my head, I can't think of anything that would\ break by having them get executed after wads are loaded. --- src/d_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index ae1c5144d..507938519 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2281,8 +2281,6 @@ void D_DoomMain (void) execFiles = Args->GatherFiles ("-exec"); D_MultiExec (execFiles, true); - C_ExecCmdLineParams (); // [RH] do all +set commands on the command line - CopyFiles(allwads, pwads); // Since this function will never leave we must delete this array here manually. @@ -2298,6 +2296,8 @@ void D_DoomMain (void) // Now that wads are loaded, define mod-specific cvars. ParseCVarInfo(); + C_ExecCmdLineParams (); // [RH] do all +set commands on the command line + // [RH] Initialize localizable strings. GStrings.LoadStrings (false); From 0c9c624e8cfeeff5fbd78fb1641749d34e08bff9 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 8 Oct 2013 21:32:26 -0500 Subject: [PATCH 028/311] Do not follow NextThinker links in DestroyThinkersInList - Fixed: DThinker::Destroy(Most)ThinkersInList() were unreliable when destroyed thinkers destroyed more thinkers in the same list. Specifically, if the thinker it destroyed caused the very next thinker in the list to also be destroyed, it would get lost in the thinker list and end up with a NULL node. So just keep iterating through the first thinker in the list until there are none left. Since destroying a thinker causes it to remove itself from its list, the first thinker will always be changing as long as there's something to destroy. --- src/dthinker.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 15206dabd..5405051e7 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -357,12 +357,10 @@ void DThinker::DestroyThinkersInList (FThinkerList &list) { if (list.Sentinel != NULL) { - DThinker *node = list.Sentinel->NextThinker; - while (node != list.Sentinel) + for (DThinker *node = list.Sentinel->NextThinker; node != list.Sentinel; node = list.Sentinel->NextThinker) { - DThinker *next = node->NextThinker; + assert(node != NULL); node->Destroy(); - node = next; } list.Sentinel->Destroy(); list.Sentinel = NULL; @@ -380,9 +378,8 @@ void DThinker::DestroyMostThinkersInList (FThinkerList &list, int stat) // it from the list. G_FinishTravel() will find it later from // a players[].mo link and destroy it then, after copying various // information to a new player. - for (DThinker *probe = list.Sentinel->NextThinker, *next; probe != list.Sentinel; probe = next) + for (DThinker *probe = list.Sentinel->NextThinker; probe != list.Sentinel; probe = list.Sentinel->NextThinker) { - next = probe->NextThinker; if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen static_cast(probe)->player == NULL || static_cast(probe)->player->mo != probe) From 8170cfbf984030009cfc3aeda9d1995450edfcd2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 9 Oct 2013 12:52:07 +0200 Subject: [PATCH 029/311] - added my own FMOD path to CMakeLists.txt so that I can use it to create VC++ 2010 files with it. --- src/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 82f347fd8..54a72aeae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,8 +76,11 @@ if( WIN32 ) set( FMOD_SEARCH_PATHS "C:/Program Files/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" - # This next one is for me. - "E:/Software/Dev/FMOD/${WIN_TYPE}/api" ) + # This next one is for Randy. + "E:/Software/Dev/FMOD/${WIN_TYPE}/api" + # .. and this one for Graf Zahl + "D:/portable/FMOD SoundSystem 4.26/FMOD Programmers API WIN32/api" + ) set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES inc ) set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib ) set( NASM_NAMES nasmw nasm ) From c2bac9d2df3484c293b8631b81d7f615a48d9218 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 9 Oct 2013 21:29:28 -0500 Subject: [PATCH 030/311] Add WorldPanning flag for camera texture definitions. - To make camera textures pan in world units instead of texture units, you can now add "WorldPanning" at the end of the cameratexture definition in ANIMDEFS, after the "fit" specification. e.g. cameratexture CAMTEX 128 128 fit 64 64 worldpanning --- src/textures/animations.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index aaf6d03d6..5a6f0729a 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -659,6 +659,17 @@ void FTextureManager::ParseCameraTexture(FScanner &sc) sc.UnGet (); } } + if (sc.GetString()) + { + if (sc.Compare("WorldPanning")) + { + viewer->bWorldPanning = true; + } + else + { + sc.UnGet(); + } + } viewer->SetScaledSize(fitwidth, fitheight); } From 1f723c10ae6e2c56d0a5569134228006bfe363b6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 9 Oct 2013 21:50:24 -0500 Subject: [PATCH 031/311] Add CF_INTERPVIEW for players. - Added CF_INTERPVIEW flag for players. A_SetPitch/A_SetAngle and the similar ACS APROPs set this when changing an angle. This forces the renderer to interpolate the view angles instead of updating with the latest mouse positions. The effect lasts one tick. --- src/actor.h | 4 ++++ src/d_player.h | 1 + src/p_acs.cpp | 12 ++++++++---- src/p_mobj.cpp | 24 ++++++++++++++++++++++++ src/p_user.cpp | 3 +++ src/r_utility.cpp | 1 + src/thingdef/thingdef_codeptr.cpp | 5 ++--- 7 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/actor.h b/src/actor.h index 3a97ef49a..f8b583101 100644 --- a/src/actor.h +++ b/src/actor.h @@ -764,6 +764,10 @@ public: return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor); } + // These also set CF_INTERPVIEW for players. + void SetPitch(int p); + void SetAngle(angle_t ang); + const PClass *GetBloodType(int type = 0) const { const PClass *bloodcls; diff --git a/src/d_player.h b/src/d_player.h index f6f7674d7..22f01f490 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -198,6 +198,7 @@ typedef enum CF_INSTANTWEAPSWITCH= 1 << 11, // [RH] Switch weapons instantly CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted + CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame CF_DRAIN = 1 << 16, // Player owns a drain powerup CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;) CF_REFLECTION = 1 << 19, diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 21e0d5c0b..d70cc2c0b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8250,7 +8250,9 @@ scriptwait: if (STACK(2) == 0) { if (activator != NULL) - activator->angle = STACK(1) << 16; + { + activator->SetAngle(STACK(1) << 16); + } } else { @@ -8259,7 +8261,7 @@ scriptwait: while ( (actor = iterator.Next ()) ) { - actor->angle = STACK(1) << 16; + actor->SetAngle(STACK(1) << 16); } } sp -= 2; @@ -8269,7 +8271,9 @@ scriptwait: if (STACK(2) == 0) { if (activator != NULL) - activator->pitch = STACK(1) << 16; + { + activator->SetPitch(STACK(1) << 16); + } } else { @@ -8278,7 +8282,7 @@ scriptwait: while ( (actor = iterator.Next ()) ) { - actor->pitch = STACK(1) << 16; + actor->SetPitch(STACK(1) << 16); } } sp -= 2; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 492dd3389..69d4203fe 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2962,6 +2962,30 @@ void AActor::SetShade (int r, int g, int b) fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b); } +void AActor::SetPitch(int p) +{ + if (p != pitch) + { + pitch = p; + if (player != NULL) + { + player->cheats |= CF_INTERPVIEW; + } + } +} + +void AActor::SetAngle(angle_t ang) +{ + if (ang != angle) + { + angle = ang; + if (player != NULL) + { + player->cheats |= CF_INTERPVIEW; + } + } +} + // // P_MobjThinker // diff --git a/src/p_user.cpp b/src/p_user.cpp index 901f6cfaa..938c7727f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2252,6 +2252,9 @@ void P_PlayerThink (player_t *player) { player->inventorytics--; } + // Don't interpolate the view for more than one tic + player->cheats &= ~CF_INTERPVIEW; + // No-clip cheat if ((player->cheats & (CF_NOCLIP | CF_NOCLIP2)) == CF_NOCLIP2) { // No noclip2 without noclip diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 0b51578ed..606cca840 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -581,6 +581,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi viewy = iview->oviewy + FixedMul (frac, iview->nviewy - iview->oviewy); viewz = iview->oviewz + FixedMul (frac, iview->nviewz - iview->oviewz); if (player != NULL && + !(player->cheats & CF_INTERPVIEW) && player - players == consoleplayer && camera == player->mo && !demoplayback && diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9faeb7442..d48b18a2a 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3935,7 +3935,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) { ACTION_PARAM_START(1); ACTION_PARAM_ANGLE(angle, 0); - self->angle = angle; + self->SetAngle(angle); } //=========================================================================== @@ -3973,8 +3973,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) } pitch = clamp(pitch, min, max); } - - self->pitch = pitch; + self->SetPitch(pitch); } //=========================================================================== From 637798c1b569ac572b3b7dd36f030b89b4463f70 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 9 Oct 2013 22:11:33 -0500 Subject: [PATCH 032/311] Add handling for +warp at the command line. - Command-line console commands are executed before a level is entered, so trying to use +warp to position yourself at a specific location will not work. We now specially handle this command so that it does work. --- src/c_dispatch.cpp | 9 ++++++++- src/d_main.cpp | 8 +++++++- src/doomstat.h | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 76b6e395d..2bd255405 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -627,7 +627,14 @@ void C_DoCommand (const char *cmd, int keynum) } else { - new DStoredCommand (com, beg); + if (len == 4 && strnicmp(beg, "warp", 4) == 0) + { + StoredWarp = beg; + } + else + { + new DStoredCommand (com, beg); + } } } else diff --git a/src/d_main.cpp b/src/d_main.cpp index 507938519..f0e7e7676 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -218,6 +218,7 @@ int NoWipe; // [RH] Allow wipe? (Needs to be set each time) bool singletics = false; // debug flag to cancel adaptiveness FString startmap; bool autostart; +FString StoredWarp; bool advancedemo; FILE *debugfile; event_t events[MAXEVENTS]; @@ -2081,7 +2082,7 @@ static void CheckCmdLine() { startmap = "&wt@01"; } - autostart = false; + autostart = StoredWarp.IsNotEmpty(); const char *val = Args->CheckValue ("-skill"); if (val) @@ -2529,6 +2530,11 @@ void D_DoomMain (void) if (demorecording) G_BeginRecording (startmap); G_InitNew (startmap, false); + if (StoredWarp.IsNotEmpty()) + { + AddCommandString(StoredWarp.LockBuffer()); + StoredWarp = NULL; + } } else { diff --git a/src/doomstat.h b/src/doomstat.h index 2819f1bf0..92ab5b8f8 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -59,6 +59,8 @@ extern FString startmap; // [RH] Actual map name now extern bool autostart; +extern FString StoredWarp; // [RH] +warp at the command line + // Selected by user. EXTERN_CVAR (Int, gameskill); extern int NextSkill; // [RH] Skill to use at next level load From 02514dc9b202e16b9551284a8625f72addd4d91d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 9 Oct 2013 22:32:52 -0500 Subject: [PATCH 033/311] - Fixed: AFSwordMissile::DoSpecialDamage had a unique prototype so it would never actually be called. --- src/g_hexen/a_fighterquietus.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index 0ba8abd6f..846b30281 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -58,12 +58,12 @@ class AFSwordMissile : public AActor { DECLARE_CLASS (AFSwordMissile, AActor) public: - int DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype); + int DoSpecialDamage(AActor *victim, int damage, FName damagetype); }; IMPLEMENT_CLASS (AFSwordMissile) -int AFSwordMissile::DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype) +int AFSwordMissile::DoSpecialDamage(AActor *victim, int damage, FName damagetype) { if (victim->player) { From b9a1528747b5d98af77070518f2027612efdbd37 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 10 Oct 2013 17:40:15 -0700 Subject: [PATCH 034/311] - DYN_FLUIDSYNTH now defaults to ON. - Added ZDOOM_OUTPUT_OLDSTYLE (could probably use a more descriptive name) which causes CMake to vary the executable name by build type and place the exes and pk3s into the directory specified in ZDOOM_OUTPUT_DIR. - ALL_BUILD will now launch ZDoom. --- CMakeLists.txt | 16 +- CleanDirectoryList.cmake | 48 +++ CreateLaunchers.cmake | 336 +++++++++++++++++++ launcher-templates/genericlauncher.cmd.in | 14 + launcher-templates/launcher.env.cmd.in | 1 + launcher-templates/perconfig.vcproj.user.in | 28 ++ launcher-templates/perconfig.vcxproj.user.in | 7 + launcher-templates/targetlauncher.cmd.in | 8 + launcher-templates/vcproj.user.in | 10 + launcher-templates/vcxproj.user.in | 4 + src/CMakeLists.txt | 40 ++- 11 files changed, 496 insertions(+), 16 deletions(-) create mode 100644 CleanDirectoryList.cmake create mode 100644 CreateLaunchers.cmake create mode 100644 launcher-templates/genericlauncher.cmd.in create mode 100644 launcher-templates/launcher.env.cmd.in create mode 100644 launcher-templates/perconfig.vcproj.user.in create mode 100644 launcher-templates/perconfig.vcxproj.user.in create mode 100644 launcher-templates/targetlauncher.cmd.in create mode 100644 launcher-templates/vcproj.user.in create mode 100644 launcher-templates/vcxproj.user.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 087535b69..ecb4a5be7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required( VERSION 2.4 ) project(ZDoom) +list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ) +include( CreateLaunchers ) + # Generator expression are available some time in CMake 2.8. Due to # cmake_minimum_required, we can assume a minor version of > 7 implies major >= 2 if(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) @@ -19,16 +22,16 @@ function( add_pk3 PK3_NAME PK3_DIR ) set( PK3_TARGET "pk3" ) endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) - if( NOT NO_GENERATOR_EXPRESSIONS ) + if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $ DEPENDS zipdir ${PK3_DIR} ) - else( NOT NO_GENERATOR_EXPRESSIONS ) + else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} DEPENDS zipdir ${PK3_DIR} ) - endif( NOT NO_GENERATOR_EXPRESSIONS ) + endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_target( ${PK3_TARGET} ALL DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) @@ -42,6 +45,13 @@ ENDIF( NOT CMAKE_BUILD_TYPE ) set( ZDOOM_OUTPUT_DIR ${CMAKE_BINARY_DIR} CACHE PATH "Directory where zdoom.pk3 and the executable will be created." ) set( ZDOOM_EXE_NAME "zdoom" CACHE FILEPATH "Name of the executable to create." ) +if( MSVC ) + # Allow the user to use ZDOOM_OUTPUT_DIR as a single release point. + # Use zdoom, zdoomd, zdoom64, and zdoomd64 for the binary names + option( ZDOOM_OUTPUT_OLDSTYLE "Don't use Release/Debug directories." OFF ) +else( MSVC ) + set( ZDOOM_OUTPUT_OLDSTYLE OFF ) +endif( MSVC ) if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) set( PROFILE 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." ) diff --git a/CleanDirectoryList.cmake b/CleanDirectoryList.cmake new file mode 100644 index 000000000..58b8963f9 --- /dev/null +++ b/CleanDirectoryList.cmake @@ -0,0 +1,48 @@ +# - Removes duplicate entries and non-directories from a provided list +# +# clean_directory_list( [...]) +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__clean_directory_list) + return() +endif() +set(__clean_directory_list YES) + +function(clean_directory_list _var) + # combine variable's current value with additional list items + set(_in ${${_var}} ${ARGN}) + + if(_in) + # Initial list cleaning + list(REMOVE_DUPLICATES _in) + + # Grab the absolute path of each actual directory + set(_out) + foreach(_dir ${_in}) + if(IS_DIRECTORY "${_dir}") + get_filename_component(_dir "${_dir}" ABSOLUTE) + file(TO_CMAKE_PATH "${_dir}" _dir) + list(APPEND _out "${_dir}") + endif() + endforeach() + + if(_out) + # Clean up the output list now + list(REMOVE_DUPLICATES _out) + endif() + + # return _out + set(${_var} "${_out}" PARENT_SCOPE) + endif() +endfunction() diff --git a/CreateLaunchers.cmake b/CreateLaunchers.cmake new file mode 100644 index 000000000..8acca1c17 --- /dev/null +++ b/CreateLaunchers.cmake @@ -0,0 +1,336 @@ +# - Create launchers to set working directory, env. vars, etc. +# +# include(CreateLaunchers) - to make these available +# guess_runtime_library_dirs( [ ...]) +# create_default_target_launcher( +# [ARGS ] +# [FORWARD_ARGS] +# [RUNTIME_LIBRARY_DIRS ] +# [WORKING_DIRECTORY ] +# [ENVIRONMENT [...]]) +# +# create_target_launcher( +# [ARGS ] +# [FORWARD_ARGS] +# [RUNTIME_LIBRARY_DIRS ] +# [WORKING_DIRECTORY ] +# [ENVIRONMENT [...]]) +# +# create_generic_launcher( +# [RUNTIME_LIBRARY_DIRS ] +# [WORKING_DIRECTORY ] +# [ENVIRONMENT [...]]) +# - sets GENERIC_LAUNCHER_COMMAND and GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION +# +# Requires these CMake modules: +# ListFilter +# ProgramFilesGlob +# CleanDirectoryList +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__create_launchers) + return() +endif() +set(__create_launchers YES) + +include(CleanDirectoryList) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_launchermoddir + ${CMAKE_CURRENT_LIST_FILE} + PATH) +set(_launchermoddir "${_launchermoddir}/launcher-templates") + +macro(_launcher_system_settings) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(BITS 64) + else() + set(BITS 32) + endif() + + if(WIN32) + # Find user and system name + set(SYSTEM_NAME $ENV{USERDOMAIN}) + set(USER_NAME $ENV{USERNAME}) + set(VCPROJ_TYPE vcproj) + set(USERFILE_EXTENSION ${SYSTEM_NAME}.${USER_NAME}.user) + set(LAUNCHER_LINESEP " ") + if(MSVC90) + set(USERFILE_VC_VERSION 9.00) + elseif(MSVC80) + set(USERFILE_VC_VERSION 8.00) + elseif(MSVC71) + set(USERFILE_VC_VERSION 7.10) + elseif(MSVC10 OR (MSVC AND MSVC_VERSION GREATER 1600)) # 2010 or newer + set(LAUNCHER_LINESEP "\n") + set(USERFILE_VC_VERSION 10.00) + set(USERFILE_EXTENSION user) + set(VCPROJ_TYPE vcxproj) + endif() + if(BITS EQUAL 64) + set(USERFILE_PLATFORM x64) + else() + set(USERFILE_PLATFORM Win${BITS}) + endif() + set(_pathdelim ";") + set(_suffix "cmd") + else() + set(_pathdelim ":") + set(USERFILE_PLATFORM ${CMAKE_SYSTEM_NAME}${BITS}) + set(_suffix "sh") + find_package(GDB QUIET) + if(GDB_FOUND) + set(LAUNCHERS_GOT_GDB YES) + if(GDB_HAS_RETURN_CHILD_RESULT) + set(LAUNCHERS_GDB_ARG --return-child-result) + endif() + else() + set(LAUNCHERS_GOT_GDB) + endif() + endif() + + if(WIN32 AND NOT USERFILE_REMOTE_MACHINE) + site_name(USERFILE_REMOTE_MACHINE) + mark_as_advanced(USERFILE_REMOTE_MACHINE) + endif() +endmacro() + +macro(_launcher_process_args) + set(_nowhere) + set(_curdest _nowhere) + set(_val_args + ARGS + RUNTIME_LIBRARY_DIRS + WORKING_DIRECTORY + ENVIRONMENT) + set(_bool_args FORWARD_ARGS) + foreach(_arg ${_val_args} ${_bool_args}) + set(${_arg}) + endforeach() + foreach(_element ${ARGN}) + list(FIND _val_args "${_element}" _val_arg_find) + list(FIND _bool_args "${_element}" _bool_arg_find) + if("${_val_arg_find}" GREATER "-1") + set(_curdest "${_element}") + elseif("${_bool_arg_find}" GREATER "-1") + set("${_element}" ON) + set(_curdest _nowhere) + else() + list(APPEND ${_curdest} "${_element}") + endif() + endforeach() + + if(_nowhere) + message(FATAL_ERROR + "Syntax error in use of a function in CreateLaunchers!") + endif() + + # Turn into a list of native paths + set(_runtime_lib_dirs) + foreach(_dlldir ${RUNTIME_LIBRARY_DIRS}) + file(TO_NATIVE_PATH "${_dlldir}" _path) + set(_runtime_lib_dirs "${_runtime_lib_dirs}${_path}${_pathdelim}") + endforeach() + + if(NOT WORKING_DIRECTORY) + set(WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + if(FORWARD_ARGS) + if(WIN32) + set(FWD_ARGS %*) + else() + set(FWD_ARGS $*) + endif() + else() + set(FWD_ARGS) + endif() + + set(USERFILE_WORKING_DIRECTORY "${WORKING_DIRECTORY}") + set(USERFILE_COMMAND_ARGUMENTS "${ARGS}") + set(LAUNCHERSCRIPT_COMMAND_ARGUMENTS "${ARGS} ${FWD_ARGS}") + + if(WIN32) + set(RUNTIME_LIBRARIES_ENVIRONMENT "PATH=${_runtime_lib_dirs};%PATH%") + file(READ + "${_launchermoddir}/launcher.env.cmd.in" + _cmdenv) + else() + if(APPLE) + set(RUNTIME_LIBRARIES_ENVIRONMENT + "DYLD_LIBRARY_PATH=${_runtime_lib_dirs}:$DYLD_LIBRARY_PATH") + else() + set(RUNTIME_LIBRARIES_ENVIRONMENT + "LD_LIBRARY_PATH=${_runtime_lib_dirs}:$LD_LIBRARY_PATH") + endif() + file(READ + "${_launchermoddir}/launcher.env.sh.in" + _cmdenv) + endif() + set(USERFILE_ENVIRONMENT "${RUNTIME_LIBRARIES_ENVIRONMENT}") + + set(USERFILE_ENV_COMMANDS) + foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT}) + string(CONFIGURE + "@USERFILE_ENVIRONMENT@@LAUNCHER_LINESEP@@_arg@" + USERFILE_ENVIRONMENT + @ONLY) + string(CONFIGURE + "@USERFILE_ENV_COMMANDS@${_cmdenv}" + USERFILE_ENV_COMMANDS + @ONLY) + endforeach() +endmacro() + +macro(_launcher_produce_vcproj_user) + if(MSVC) + file(READ + "${_launchermoddir}/perconfig.${VCPROJ_TYPE}.user.in" + _perconfig) + set(USERFILE_CONFIGSECTIONS) + foreach(USERFILE_CONFIGNAME ${CMAKE_CONFIGURATION_TYPES}) + get_target_property(USERFILE_${USERFILE_CONFIGNAME}_COMMAND + ${_targetname} + LOCATION_${USERFILE_CONFIGNAME}) + file(TO_NATIVE_PATH + "${USERFILE_${USERFILE_CONFIGNAME}_COMMAND}" + USERFILE_${USERFILE_CONFIGNAME}_COMMAND) + string(CONFIGURE "${_perconfig}" _temp @ONLY ESCAPE_QUOTES) + string(CONFIGURE + "${USERFILE_CONFIGSECTIONS}${_temp}" + USERFILE_CONFIGSECTIONS + ESCAPE_QUOTES) + endforeach() + + + configure_file("${_launchermoddir}/${VCPROJ_TYPE}.user.in" + ${VCPROJNAME}.${VCPROJ_TYPE}.${USERFILE_EXTENSION} + @ONLY) + endif() + +endmacro() + +macro(_launcher_configure_executable _src _tmp _target) +# get_filename_component(_targetname "${_target}" NAME) + get_filename_component(_targetpath "${_target}" PATH) + configure_file("${_src}" + "${_tmp}" + @ONLY) + file(COPY "${_tmp}" + DESTINATION "${_targetpath}" + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +endmacro() + +macro(_launcher_create_target_launcher) + if(CMAKE_CONFIGURATION_TYPES) + # Multi-config generator - multiple launchers + foreach(_config ${CMAKE_CONFIGURATION_TYPES}) + get_target_property(USERFILE_${_config}_COMMAND + ${_targetname} + LOCATION_${_config}) + file(TO_NATIVE_PATH + "${USERFILE_${_config}_COMMAND}" + USERFILE_COMMAND) + set(_fn "launch-${_targetname}-${_config}.${_suffix}") + _launcher_configure_executable("${_launchermoddir}/targetlauncher.${_suffix}.in" + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_fn}" + "${CMAKE_CURRENT_BINARY_DIR}/${_fn}") + endforeach() + else() + # Single-config generator - single launcher + get_target_property(USERFILE_COMMAND + ${_targetname} + LOCATION) + file(TO_NATIVE_PATH + "${USERFILE_COMMAND}" + USERFILE_COMMAND) + _launcher_configure_executable("${_launchermoddir}/targetlauncher.${_suffix}.in" + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/launch-${_targetname}.${_suffix}" + "${CMAKE_CURRENT_BINARY_DIR}/launch-${_targetname}.${_suffix}" + @ONLY) + endif() +endmacro() + +function(create_default_target_launcher _targetname) + _launcher_system_settings() + _launcher_process_args(${ARGN}) + + set(VCPROJNAME "${CMAKE_BINARY_DIR}/ALL_BUILD") + _launcher_produce_vcproj_user() + + _launcher_create_target_launcher() +endfunction() + +function(create_target_launcher _targetname) + _launcher_system_settings() + _launcher_process_args(${ARGN}) + + set(VCPROJNAME "${CMAKE_CURRENT_BINARY_DIR}/${_targetname}") + _launcher_produce_vcproj_user() + + _launcher_create_target_launcher() +endfunction() + +function(create_generic_launcher _launchername) + _launcher_system_settings() + _launcher_process_args(${ARGN}) + + if(NOT IS_ABSOLUTE _launchername) + set(_launchername + "${CMAKE_CURRENT_BINARY_DIR}/${_launchername}.${_suffix}") + else() + set(_launchername "${_launchername}.${_suffix}") + endif() + if(WIN32) + set(GENERIC_LAUNCHER_COMMAND "${_launchername}" PARENT_SCOPE) + set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION) + else() + set(GENERIC_LAUNCHER_COMMAND sh "${_launchername}" PARENT_SCOPE) + set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION + "Program terminated with signal") + endif() + + _launcher_configure_executable("${_launchermoddir}/genericlauncher.${_suffix}.in" + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/genericlauncher.${_suffix}.in" + "${_launchername}") +endfunction() + +function(guess_runtime_library_dirs _var) + # Start off with the link directories of the calling listfile's directory + get_directory_property(_libdirs LINK_DIRECTORIES) + + # Add additional libraries passed to the function + foreach(_lib ${ARGN}) + get_filename_component(_libdir "${_lib}" PATH) + list(APPEND _libdirs "${_libdir}") + endforeach() + + # Now, build a list of potential dll directories + set(_dlldirs) + foreach(_libdir ${_libdirs}) + # Add the libdir itself + list(APPEND _dlldirs "${_libdir}") + + # Look also in libdir/../bin since the dll might not be with the lib + get_filename_component(_libdir "${_libdir}/../bin" ABSOLUTE) + list(APPEND _dlldirs "${_libdir}") + endforeach() + + # Only keep the valid, unique directories + clean_directory_list(_dlldirs) + + # Return _dlldirs + set(${_var} "${_dlldirs}" PARENT_SCOPE) +endfunction() diff --git a/launcher-templates/genericlauncher.cmd.in b/launcher-templates/genericlauncher.cmd.in new file mode 100644 index 000000000..9a19bbc7a --- /dev/null +++ b/launcher-templates/genericlauncher.cmd.in @@ -0,0 +1,14 @@ +cd @USERFILE_WORKING_DIRECTORY@ +@USERFILE_ENV_COMMANDS@ + +IF NOT [x%1]==[x--debugger] GOTO SkipDebuggingMess + +ECHO Need to ditch the debugger! +SHIFT /1 +%1 %2 %3 %4 %5 %6 %7 %8 %9 +GOTO EOF + +:SkipDebuggingMess +%* + +:EOF \ No newline at end of file diff --git a/launcher-templates/launcher.env.cmd.in b/launcher-templates/launcher.env.cmd.in new file mode 100644 index 000000000..72a24e67e --- /dev/null +++ b/launcher-templates/launcher.env.cmd.in @@ -0,0 +1 @@ +set @_arg@ diff --git a/launcher-templates/perconfig.vcproj.user.in b/launcher-templates/perconfig.vcproj.user.in new file mode 100644 index 000000000..95cacecff --- /dev/null +++ b/launcher-templates/perconfig.vcproj.user.in @@ -0,0 +1,28 @@ + + + diff --git a/launcher-templates/perconfig.vcxproj.user.in b/launcher-templates/perconfig.vcxproj.user.in new file mode 100644 index 000000000..ef0237999 --- /dev/null +++ b/launcher-templates/perconfig.vcxproj.user.in @@ -0,0 +1,7 @@ + + @USERFILE_ENVIRONMENT@ + WindowsLocalDebugger + ${USERFILE_@USERFILE_CONFIGNAME@_COMMAND} + @USERFILE_COMMAND_ARGUMENTS@ + @USERFILE_WORKING_DIRECTORY@ + diff --git a/launcher-templates/targetlauncher.cmd.in b/launcher-templates/targetlauncher.cmd.in new file mode 100644 index 000000000..c5715d679 --- /dev/null +++ b/launcher-templates/targetlauncher.cmd.in @@ -0,0 +1,8 @@ +cd @USERFILE_WORKING_DIRECTORY@ +@USERFILE_ENV_COMMANDS@ +if [%1]==[--debugger] ( + SHIFT +) + +"@USERFILE_COMMAND@" @LAUNCHERSCRIPT_COMMAND_ARGUMENTS@ +pause diff --git a/launcher-templates/vcproj.user.in b/launcher-templates/vcproj.user.in new file mode 100644 index 000000000..117473d70 --- /dev/null +++ b/launcher-templates/vcproj.user.in @@ -0,0 +1,10 @@ + + + +@USERFILE_CONFIGSECTIONS@ + + diff --git a/launcher-templates/vcxproj.user.in b/launcher-templates/vcxproj.user.in new file mode 100644 index 000000000..f3e423835 --- /dev/null +++ b/launcher-templates/vcxproj.user.in @@ -0,0 +1,4 @@ + + +@USERFILE_CONFIGSECTIONS@ + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 464d6db97..7c6820423 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,7 +24,7 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE endif( APPLE ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) -option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ) +option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON ) if( CMAKE_SIZEOF_VOID_P MATCHES "8" ) set( X64 64 ) @@ -1087,10 +1087,32 @@ include_directories( . add_dependencies( zdoom revision_check ) -# RUNTIME_OUTPUT_DIRECTORY does not exist in CMake 2.4. -# Linux distributions are slow to adopt 2.6. :( -set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) -set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) +if( MSVC ) + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") + add_custom_command(TARGET zdoom POST_BUILD + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#2 + COMMENT "Adding manifest..." + ) + + create_default_target_launcher( zdoom WORKING_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) +endif( MSVC ) + +if( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) + set_target_properties( zdoom PROPERTIES + RUNTIME_OUTPUT_NAME ${ZDOOM_EXE_NAME} + RUNTIME_OUTPUT_NAME_DEBUG ${ZDOOM_EXE_NAME}d + RUNTIME_OUTPUT_NAME_MINSIZEREL ${ZDOOM_EXE_NAME}msr + RUNTIME_OUTPUT_NAME_RELWITHDEBINFO ${ZDOOM_EXE_NAME}rd + ) + add_custom_command(TARGET zdoom POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ + COMMENT "Copying to output directory..." ) +else( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) + # RUNTIME_OUTPUT_DIRECTORY does not exist in CMake 2.4. + # Linux distributions are slow to adopt 2.6. :( + set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) + set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) +endif( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) if( NOT WIN32 ) FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME} ]; then ln -sf ${CMAKE_CURRENT_BINARY_DIR}/${ZDOOM_EXE_NAME} ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME}; fi" ) @@ -1108,14 +1130,6 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE endif( SSE_MATTERS ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) -if( MSVC ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") - add_custom_command(TARGET zdoom POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#2 - COMMENT "Adding manifest..." - ) -endif( MSVC ) - source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+") source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+") source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+") From 3e90b65014e7e8bcef2762a52a4ed803fd33cdc7 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 12 Oct 2013 00:24:04 -0400 Subject: [PATCH 035/311] - Use release compiler flags for debug builds of third party libraries. --- CMakeLists.txt | 10 ++++++++++ bzip2/CMakeLists.txt | 2 ++ dumb/CMakeLists.txt | 2 ++ game-music-emu/CMakeLists.txt | 2 ++ jpeg-6b/CMakeLists.txt | 2 ++ lzma/CMakeLists.txt | 2 ++ zlib/CMakeLists.txt | 2 ++ 7 files changed, 22 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecb4a5be7..48fe7145c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,16 @@ function( add_pk3 PK3_NAME PK3_DIR ) DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) endfunction( add_pk3 ) +# Macro for building libraries without debugging information +macro( make_release_only ) + set( CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_RELEASE} ) + set( CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_RELEASE} ) + set( CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELEASE} ) + set( CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_RELEASE} ) + set( CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_RELEASE} ) + set( CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELEASE} ) +endmacro( make_release_only ) + IF( NOT CMAKE_BUILD_TYPE ) SET( CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." diff --git a/bzip2/CMakeLists.txt b/bzip2/CMakeLists.txt index 6006f491c..5f35eb346 100644 --- a/bzip2/CMakeLists.txt +++ b/bzip2/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) +make_release_only() + if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt index ee50c4a0a..178de53a9 100644 --- a/dumb/CMakeLists.txt +++ b/dumb/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) +make_release_only() + include( CheckFunctionExists ) # DUMB is much slower in a Debug build than a Release build, so we force a Release diff --git a/game-music-emu/CMakeLists.txt b/game-music-emu/CMakeLists.txt index 5c4a03043..f880023ab 100644 --- a/game-music-emu/CMakeLists.txt +++ b/game-music-emu/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required( VERSION 2.4 ) include( CheckCXXCompilerFlag ) +make_release_only() + # I don't plan on debugging this, so make it a release build. if( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) diff --git a/jpeg-6b/CMakeLists.txt b/jpeg-6b/CMakeLists.txt index 5c8b5972e..21096465e 100644 --- a/jpeg-6b/CMakeLists.txt +++ b/jpeg-6b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) +make_release_only() + if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) diff --git a/lzma/CMakeLists.txt b/lzma/CMakeLists.txt index 7582712fe..019383d42 100644 --- a/lzma/CMakeLists.txt +++ b/lzma/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) +make_release_only() + if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index 7ac44940a..43795934d 100644 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 2.4.4) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) +make_release_only() + project(zlib C) set(VERSION "1.2.7") From 03b75ae7c18d2eda22704c8f835270cd762ccc0f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 12 Oct 2013 00:56:49 -0400 Subject: [PATCH 036/311] - Fixed a few flags for Visual Studio compilation. --- CMakeLists.txt | 8 +++++--- src/CMakeLists.txt | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48fe7145c..08fc30afb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ find_package( ZLIB ) if( MSVC ) # Eliminate unreferenced functions and data # Perform identical COMDAT folding - set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt" ) + set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt /TSAWARE" ) # String pooling # Function-level linking @@ -84,10 +84,10 @@ if( MSVC ) set( ALL_C_FLAGS "/GF /Gy /GR-" ) # Avoid CRT DLL dependancies in release builds - set( REL_C_FLAGS "/MT" ) + set( REL_C_FLAGS "/MT /Oy" ) # Debug allocations in debug builds - set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC" ) + set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd /Gm" ) # Disable warnings for unsecure CRT functions from VC8+ if( MSVC_VERSION GREATER 1399 ) @@ -98,9 +98,11 @@ if( MSVC ) string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} ) string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} ) string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ) + string(REPLACE "/MDd " " " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} ) string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} ) string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} ) string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} ) + string(REPLACE "/MDd " " " CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} ) string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) endif( MSVC ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c6820423..16f0e51f0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -430,6 +430,12 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE endif( NOT NO_STRIP ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +# MSVC Flags + +if( MSVC ) + set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DELAYLOAD:\"fmodex${X64}.dll\"" ) +endif( MSVC ) + # Check for functions that may or may not exist. CHECK_FUNCTION_EXISTS( filelength FILELENGTH_EXISTS ) From 0759a4b4383d8cceb5fc2f132bcc784db180dd1b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 12 Oct 2013 01:44:57 -0400 Subject: [PATCH 037/311] - Actually, lets not use /Gm since it's incompatible with /MP which will be much faster on multi-core machines. - Added ZDOOM_GENERATE_MAPFILE which enables linker map file generation. --- CMakeLists.txt | 6 +++--- src/CMakeLists.txt | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08fc30afb..4740603b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,12 +39,12 @@ endfunction( add_pk3 ) # Macro for building libraries without debugging information macro( make_release_only ) - set( CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_RELEASE} ) set( CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_RELEASE} ) set( CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELEASE} ) - set( CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_RELEASE} ) + string( REPLACE "/MT " "/MTd " CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_RELEASE} ) set( CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_RELEASE} ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELEASE} ) + string( REPLACE "/MT " "/MTd " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_RELEASE} ) endmacro( make_release_only ) IF( NOT CMAKE_BUILD_TYPE ) @@ -87,7 +87,7 @@ if( MSVC ) set( REL_C_FLAGS "/MT /Oy" ) # Debug allocations in debug builds - set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd /Gm" ) + set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" ) # Disable warnings for unsecure CRT functions from VC8+ if( MSVC_VERSION GREATER 1399 ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16f0e51f0..23b689847 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1093,8 +1093,22 @@ include_directories( . add_dependencies( zdoom revision_check ) +# Due to some quirks, we need to do this in this order +if( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) + # RUNTIME_OUTPUT_DIRECTORY does not exist in CMake 2.4. + # Linux distributions are slow to adopt 2.6. :( + set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) + set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) +endif( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) + if( MSVC ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") + option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) + if( ZDOOM_GENERATE_MAPFILE ) + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") + else( ZDOOM_GENERATE_MAPFILE ) + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /MAP:${ZDOOM_EXE_NAME}.map") + endif( ZDOOM_GENERATE_MAPFILE ) + add_custom_command(TARGET zdoom POST_BUILD COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#2 COMMENT "Adding manifest..." @@ -1103,22 +1117,25 @@ if( MSVC ) create_default_target_launcher( zdoom WORKING_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) endif( MSVC ) -if( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) +if( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSIONS ) set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_NAME ${ZDOOM_EXE_NAME} RUNTIME_OUTPUT_NAME_DEBUG ${ZDOOM_EXE_NAME}d RUNTIME_OUTPUT_NAME_MINSIZEREL ${ZDOOM_EXE_NAME}msr RUNTIME_OUTPUT_NAME_RELWITHDEBINFO ${ZDOOM_EXE_NAME}rd ) - add_custom_command(TARGET zdoom POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ - COMMENT "Copying to output directory..." ) -else( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) - # RUNTIME_OUTPUT_DIRECTORY does not exist in CMake 2.4. - # Linux distributions are slow to adopt 2.6. :( - set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) - set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) -endif( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSION ) + + if( ZDOOM_GENERATE_MAPFILE ) + add_custom_command(TARGET zdoom POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $/zdoom.map ${ZDOOM_OUTPUT_DIR}/$.map + COMMENT "Copying to output directory..." ) + else( ZDOOM_GENERATE_MAPFILE ) + add_custom_command(TARGET zdoom POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ + COMMENT "Copying to output directory..." ) + endif( ZDOOM_GENERATE_MAPFILE ) +endif( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSIONS ) if( NOT WIN32 ) FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME} ]; then ln -sf ${CMAKE_CURRENT_BINARY_DIR}/${ZDOOM_EXE_NAME} ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME}; fi" ) From 7dbf4ec38f3e08ec0fe9aeb8f994ae807acf5845 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 12 Oct 2013 01:58:39 -0400 Subject: [PATCH 038/311] - Slight cleanup and I accidentally inverted the map generation flag. --- src/CMakeLists.txt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23b689847..9506e6a59 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -430,12 +430,6 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE endif( NOT NO_STRIP ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) -# MSVC Flags - -if( MSVC ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DELAYLOAD:\"fmodex${X64}.dll\"" ) -endif( MSVC ) - # Check for functions that may or may not exist. CHECK_FUNCTION_EXISTS( filelength FILELENGTH_EXISTS ) @@ -1104,9 +1098,9 @@ endif( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) if( ZDOOM_GENERATE_MAPFILE ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO") + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:${ZDOOM_EXE_NAME}.map") else( ZDOOM_GENERATE_MAPFILE ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /MAP:${ZDOOM_EXE_NAME}.map") + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"") endif( ZDOOM_GENERATE_MAPFILE ) add_custom_command(TARGET zdoom POST_BUILD From f0b946c3cf73266d1d849e424a37330c39707bd1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 6 Nov 2013 13:37:34 -0500 Subject: [PATCH 039/311] - Allow use of system GME library. It defaults to forcing the use of the internal library at least for now though. --- CMakeLists.txt | 19 ++++++++++++++++++- src/CMakeLists.txt | 7 +++---- src/sound/music_gme.cpp | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4740603b0..3715cdac8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(ZDoom) list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ) include( CreateLaunchers ) +include( FindPackageHandleStandardArgs ) # Generator expression are available some time in CMake 2.8. Due to # cmake_minimum_required, we can assume a minor version of > 7 implies major >= 2 @@ -72,6 +73,13 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") find_package( BZip2 ) find_package( JPEG ) find_package( ZLIB ) +# GME +find_path( GME_INCLUDE_DIR gme.h ) +find_library( GME_LIBRARIES gme ) +mark_as_advanced( GME_INCLUDE_DIR GME_LIBRARIES ) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( GME + REQUIRED_VARS GME_LIBRARIES GME_INCLUDE_DIR +) if( MSVC ) # Eliminate unreferenced functions and data @@ -125,6 +133,7 @@ set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" ) option(FORCE_INTERNAL_ZLIB "Use internal zlib") option(FORCE_INTERNAL_JPEG "Use internal jpeg") option(FORCE_INTERNAL_BZIP2 "Use internal bzip2") +option(FORCE_INTERNAL_GME "Use internal gme" ON) if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB ) message( STATUS "Using system zlib" ) @@ -156,11 +165,19 @@ else( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 ) set( BZIP2_LIBRARY bz2 ) endif( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 ) +if( GME_FOUND AND NOT FORCE_INTERNAL_GME ) + message( STATUS "Using system gme library ${GME_INCLUDE_DIR}" ) +else( GME_FOUND AND NOT FORCE_INTERNAL_GME ) + message( STATUS "Using internal gme library" ) + add_subdirectory( game-music-emu ) + set( GME_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/game-music-emu" ) + set( GME_LIBRARIES gme ) +endif( GME_FOUND AND NOT FORCE_INTERNAL_GME ) + set( LZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lzma/C" ) add_subdirectory( lzma ) add_subdirectory( tools ) -add_subdirectory( game-music-emu ) add_subdirectory( dumb ) add_subdirectory( gdtoa ) add_subdirectory( wadsrc ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9506e6a59..268c1d705 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -503,8 +503,8 @@ add_custom_target( revision_check ALL # Libraries ZDoom needs message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" ) -set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${FMOD_LIBRARY}" ) -include_directories( "${ZLIB_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" ) +set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${GME_LIBRARIES}" "${FMOD_LIBRARY}" ) +include_directories( "${ZLIB_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" ) if( FLUIDSYNTH_FOUND ) if( NOT DYN_FLUIDSYNTH) @@ -1065,7 +1065,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") set( ZDOOM_LIBS ${ZDOOM_LIBS} nsl socket) endif(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") -target_link_libraries( zdoom ${ZDOOM_LIBS} gme gdtoa dumb lzma ) +target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma ) include_directories( . g_doom g_heretic @@ -1079,7 +1079,6 @@ include_directories( . thingdef timidity xlat - ../game-music-emu/gme ../gdtoa ../dumb/include ${CMAKE_BINARY_DIR}/gdtoa diff --git a/src/sound/music_gme.cpp b/src/sound/music_gme.cpp index 0c3d8c8c3..7f017b7d2 100644 --- a/src/sound/music_gme.cpp +++ b/src/sound/music_gme.cpp @@ -40,7 +40,7 @@ #include "i_musicinterns.h" #include "c_cvars.h" #include "critsec.h" -#include "gme.h" +#include #include "v_text.h" // MACROS ------------------------------------------------------------------ From 34457ce737ed2b67d7c928f27d853cc4a76a3de1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 6 Nov 2013 13:42:05 -0500 Subject: [PATCH 040/311] - Applied VoidMage's patch to strip color codes from system console on SDL platforms. --- src/sdl/i_system.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index ba126bf54..03cbd74bf 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -422,7 +422,27 @@ void I_SetIWADInfo () void I_PrintStr (const char *cp) { - fputs (cp, stdout); + // Strip out any color escape sequences before writing to the log file + char * copy = new char[strlen(cp)+1]; + const char * srcp = cp; + char * dstp = copy; + + while (*srcp != 0) + { + if (*srcp!=0x1c && *srcp!=0x1d && *srcp!=0x1e && *srcp!=0x1f) + { + *dstp++=*srcp++; + } + else + { + if (srcp[1]!=0) srcp+=2; + else break; + } + } + *dstp=0; + + fputs (copy, stdout); + delete [] copy; fflush (stdout); } From a967b05290f324787358b751b06d145d463c6629 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 11 Nov 2013 20:42:54 +1300 Subject: [PATCH 041/311] Improvements to restoring stalled netgames - The waiting message is now always cleared, regardless if it needed to be in the first place. It's a rather simple for-loop so I doubt it matters. - Nodes are also cleared from the list if they catch up while other nodes are still behind. - "lastglobalrecvtime" is now bumped after the waiting loop if a tic was successful, rather then bumping it every time a packet was received. It appears that you can receive a packet before the game knows it stalled, thus stalling it anyway. - Instead of comparing the nettics to the local node, all nodes are tested against gametic+counts (the real reason why the game has stopped). - More then one node can be marked as late at any one time. - In a packet-server game, the arbitrator is now assumed slow, rather then testing it. There is no point, seeing as we already know the game has stalled because of it. --- src/d_net.cpp | 52 ++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 0ea8e58c5..9c4bf14dd 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -704,8 +704,6 @@ void GetPackets (void) } continue; // extra setup packet } - - lastglobalrecvtime = I_GetTime (false); //Update the last time a packet was recieved netnode = doomcom.remotenode; netconsole = playerfornode[netnode] & ~PL_DRONE; @@ -1827,30 +1825,39 @@ void TryRunTics (void) I_Error ("TryRunTics: lowtic < gametic"); // [Ed850] Check to see the last time a packet was recieved. - // If it's longer then 3 seconds, a node has likely stalled. Check which one and re-request its last packet. + // If it's longer then 3 seconds, a node has likely stalled. if(I_GetTime(false) - lastglobalrecvtime >= TICRATE*3) { - int latenode = 0; // Node 0 is the local player, and should always be the highest lastglobalrecvtime = I_GetTime(false); //Bump the count if(NetMode == NET_PeerToPeer || consoleplayer == Net_Arbitrator) { + //Keep the local node in the for loop so we can still log any cases where the local node is /somehow/ late. + //However, we don't send a resend request for sanity reasons. for (i = 0; i < doomcom.numnodes; i++) - if (nodeingame[i] && nettics[i] < nettics[latenode]) - latenode = i; + { + if (nodeingame[i] && nettics[i] < gametic + counts) + { + if (debugfile) + fprintf (debugfile, "%i is slow (%i to %i)\n", + i, nettics[i], gametic+counts); + //Send resend request to the late node. Also mark the node as waiting to display it in the hud. + if(i != 0) + remoteresend[i] = players[playerfornode[i]].waiting = hadlate = true; + } + else + players[playerfornode[i]].waiting = false; + } } - else if (nodeingame[nodeforplayer[Net_Arbitrator]] && - nettics[nodeforplayer[Net_Arbitrator]] < nettics[0]) - { // Likely a packet server game. Only check the packet host. - latenode = Net_Arbitrator; + else + { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. + if (debugfile) + fprintf (debugfile, "Arbitrator is slow (%i to %i)\n", + Net_Arbitrator, nettics[Net_Arbitrator], gametic+counts); + //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. + if(i != 0) + remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true; } - - if (debugfile) - fprintf (debugfile, "lost tics from %i (%i to %i)\n", - latenode, nettics[latenode], gametic); - - if(latenode != 0) // Send resend request to late node (if not yourself... somehow). Also mark the node as waiting to display it in the hud. - remoteresend[latenode] = players[playerfornode[latenode]].waiting = hadlate = true; } // don't stay in here forever -- give the menu a chance to work @@ -1862,12 +1869,11 @@ void TryRunTics (void) } } - if (hadlate) - { - hadlate = false; - for (i = 0; i < MAXPLAYERS; i++) - players[i].waiting = false; - } + //Tic lowtic is high enough to process this gametic. Clear all possible waiting info + hadlate = false; + for (i = 0; i < MAXPLAYERS; i++) + players[i].waiting = false; + lastglobalrecvtime = I_GetTime (false); //Update the last time the game tic'd over // run the count tics if (counts > 0) From c7099744bd11baae1b8dd8c793faeeb95ab435fd Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 11 Nov 2013 23:56:58 -0500 Subject: [PATCH 042/311] - Minor changes to the CMake since it looks like VS2005 doesn't support a few things that were added. --- src/CMakeLists.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 268c1d705..7a9b0138d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -143,6 +143,11 @@ if( WIN32 ) ws2_32 setupapi oleaut32 ) + + # For some reason this isn't implied on 2005 + if( MSVC80 ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} DelayImp ) + endif( MSVC80 ) else( WIN32 ) if( APPLE ) set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" ) @@ -1097,7 +1102,11 @@ endif( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) if( ZDOOM_GENERATE_MAPFILE ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:${ZDOOM_EXE_NAME}.map") + if( NOT MSVC80 ) + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:${ZDOOM_EXE_NAME}.map") + else( NOT MSVC80 ) # 2005 doesn't support naming the map file. + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP") + endif( NOT MSVC80 ) else( ZDOOM_GENERATE_MAPFILE ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"") endif( ZDOOM_GENERATE_MAPFILE ) From 62ffe7e4e2673225aea12c4687a4770305c3d639 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 19 Nov 2013 19:42:13 -0600 Subject: [PATCH 043/311] Add NOGRAVITY to every Raven actor with FLOATBOB - Fixed: Heretic and Hexen completely skip all normal Z processing on mobjs with FLOATBOB set. To emulate that, we need to add NOGRAVITY to everything with that flag set. --- wadsrc/static/actors/heretic/hereticammo.txt | 1 + wadsrc/static/actors/heretic/hereticarmor.txt | 2 ++ wadsrc/static/actors/heretic/hereticartifacts.txt | 4 ++++ wadsrc/static/actors/hexen/blastradius.txt | 1 + wadsrc/static/actors/hexen/boostarmor.txt | 1 + wadsrc/static/actors/hexen/clericholy.txt | 1 + wadsrc/static/actors/hexen/fighterquietus.txt | 1 + wadsrc/static/actors/hexen/flechette.txt | 1 + wadsrc/static/actors/hexen/fog.txt | 1 + wadsrc/static/actors/hexen/healingradius.txt | 1 + wadsrc/static/actors/hexen/magestaff.txt | 1 + wadsrc/static/actors/hexen/mana.txt | 4 ++++ wadsrc/static/actors/hexen/speedboots.txt | 1 + wadsrc/static/actors/hexen/summon.txt | 1 + wadsrc/static/actors/hexen/teleportother.txt | 1 + wadsrc/static/actors/raven/artiegg.txt | 2 ++ wadsrc/static/actors/raven/artitele.txt | 1 + wadsrc/static/actors/raven/ravenartifacts.txt | 6 ++++++ wadsrc/static/actors/raven/ravenhealth.txt | 1 + 19 files changed, 32 insertions(+) diff --git a/wadsrc/static/actors/heretic/hereticammo.txt b/wadsrc/static/actors/heretic/hereticammo.txt index 96a20352b..8f02cce0a 100644 --- a/wadsrc/static/actors/heretic/hereticammo.txt +++ b/wadsrc/static/actors/heretic/hereticammo.txt @@ -221,6 +221,7 @@ ACTOR BagOfHolding : BackpackItem 8 Inventory.PickupMessage "$TXT_ITEMBAGOFHOLDING" +COUNTITEM +FLOATBOB + +NOGRAVITY States { Spawn: diff --git a/wadsrc/static/actors/heretic/hereticarmor.txt b/wadsrc/static/actors/heretic/hereticarmor.txt index e027f4f47..40ca671da 100644 --- a/wadsrc/static/actors/heretic/hereticarmor.txt +++ b/wadsrc/static/actors/heretic/hereticarmor.txt @@ -6,6 +6,7 @@ Actor SilverShield : BasicArmorPickup 85 Game Heretic SpawnID 68 +FLOATBOB + +NOGRAVITY Inventory.Pickupmessage "$TXT_ITEMSHIELD1" Inventory.Icon "SHLDA0" Armor.Savepercent 50 @@ -25,6 +26,7 @@ Actor EnchantedShield : BasicArmorPickup 31 Game Heretic SpawnID 69 +FLOATBOB + +NOGRAVITY Inventory.Pickupmessage "$TXT_ITEMSHIELD2" Inventory.Icon "SHD2A0" Armor.Savepercent 75 diff --git a/wadsrc/static/actors/heretic/hereticartifacts.txt b/wadsrc/static/actors/heretic/hereticartifacts.txt index 67d3946b9..404e5ba39 100644 --- a/wadsrc/static/actors/heretic/hereticartifacts.txt +++ b/wadsrc/static/actors/heretic/hereticartifacts.txt @@ -7,6 +7,7 @@ ACTOR SuperMap : MapRevealer 35 +COUNTITEM +INVENTORY.ALWAYSPICKUP +FLOATBOB + +NOGRAVITY Inventory.MaxAmount 0 Inventory.PickupMessage "$TXT_ITEMSUPERMAP" States @@ -26,6 +27,7 @@ ACTOR ArtiInvisibility : PowerupGiver 75 SpawnID 135 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH RenderStyle Translucent Alpha 0.4 @@ -51,6 +53,7 @@ ACTOR ArtiTomeOfPower : PowerupGiver 86 native SpawnID 134 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.Icon "ARTIPWBK" Powerup.Type Weaponlevel2 @@ -94,6 +97,7 @@ ACTOR ArtiTimeBomb : Inventory 34 native SpawnID 72 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.INVBAR +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/blastradius.txt b/wadsrc/static/actors/hexen/blastradius.txt index ad98d7ecc..28af3e698 100644 --- a/wadsrc/static/actors/hexen/blastradius.txt +++ b/wadsrc/static/actors/hexen/blastradius.txt @@ -4,6 +4,7 @@ ACTOR ArtiBlastRadius : CustomInventory 10110 Game Hexen SpawnID 74 +FLOATBOB + +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/boostarmor.txt b/wadsrc/static/actors/hexen/boostarmor.txt index 607c8d66a..8aa6b6eeb 100644 --- a/wadsrc/static/actors/hexen/boostarmor.txt +++ b/wadsrc/static/actors/hexen/boostarmor.txt @@ -7,6 +7,7 @@ ACTOR ArtiBoostArmor : Inventory 8041 native SpawnID 22 +COUNTITEM +FLOATBOB + +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/clericholy.txt b/wadsrc/static/actors/hexen/clericholy.txt index e97be8b17..cebc44610 100644 --- a/wadsrc/static/actors/hexen/clericholy.txt +++ b/wadsrc/static/actors/hexen/clericholy.txt @@ -8,6 +8,7 @@ ACTOR ClericWeaponPiece : WeaponPiece Inventory.ForbiddenTo FighterPlayer, MagePlayer WeaponPiece.Weapon CWeapWraithverge +FLOATBOB + +NOGRAVITY } // Cleric Weapon Piece 1 ---------------------------------------------------- diff --git a/wadsrc/static/actors/hexen/fighterquietus.txt b/wadsrc/static/actors/hexen/fighterquietus.txt index a77e851d8..b5ecd22e4 100644 --- a/wadsrc/static/actors/hexen/fighterquietus.txt +++ b/wadsrc/static/actors/hexen/fighterquietus.txt @@ -8,6 +8,7 @@ ACTOR FighterWeaponPiece : WeaponPiece Inventory.ForbiddenTo ClericPlayer, MagePlayer WeaponPiece.Weapon FWeapQuietus +FLOATBOB + +NOGRAVITY } // Fighter Weapon Piece 1 --------------------------------------------------- diff --git a/wadsrc/static/actors/hexen/flechette.txt b/wadsrc/static/actors/hexen/flechette.txt index 6e12bff53..74c7a0a6a 100644 --- a/wadsrc/static/actors/hexen/flechette.txt +++ b/wadsrc/static/actors/hexen/flechette.txt @@ -99,6 +99,7 @@ ACTOR ArtiPoisonBag : Inventory 8000 native Game Hexen SpawnID 72 +FLOATBOB + +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/fog.txt b/wadsrc/static/actors/hexen/fog.txt index 81f5aeea5..91fdfc3ee 100644 --- a/wadsrc/static/actors/hexen/fog.txt +++ b/wadsrc/static/actors/hexen/fog.txt @@ -6,6 +6,7 @@ ACTOR FogSpawner 10000 Game Hexen +NOSECTOR +NOBLOCKMAP +FLOATBOB + +NOGRAVITY +INVISIBLE action native A_FogSpawn(); diff --git a/wadsrc/static/actors/hexen/healingradius.txt b/wadsrc/static/actors/hexen/healingradius.txt index e0556915b..97efc0449 100644 --- a/wadsrc/static/actors/hexen/healingradius.txt +++ b/wadsrc/static/actors/hexen/healingradius.txt @@ -6,6 +6,7 @@ ACTOR ArtiHealingRadius : Inventory 10120 native Game Hexen +COUNTITEM +FLOATBOB + +NOGRAVITY Inventory.DefMaxAmount +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH diff --git a/wadsrc/static/actors/hexen/magestaff.txt b/wadsrc/static/actors/hexen/magestaff.txt index aa75ed446..a8584aae7 100644 --- a/wadsrc/static/actors/hexen/magestaff.txt +++ b/wadsrc/static/actors/hexen/magestaff.txt @@ -8,6 +8,7 @@ ACTOR MageWeaponPiece : WeaponPiece Inventory.ForbiddenTo FighterPlayer, ClericPlayer WeaponPiece.Weapon MWeapBloodscourge +FLOATBOB + +NOGRAVITY } // Mage Weapon Piece 1 ------------------------------------------------------ diff --git a/wadsrc/static/actors/hexen/mana.txt b/wadsrc/static/actors/hexen/mana.txt index ee7ddd37c..97bc419c8 100644 --- a/wadsrc/static/actors/hexen/mana.txt +++ b/wadsrc/static/actors/hexen/mana.txt @@ -11,6 +11,7 @@ ACTOR Mana1 : Ammo 122 Radius 8 Height 8 +FLOATBOB + +NOGRAVITY Inventory.Icon "MAN1I0" Inventory.PickupMessage "$TXT_MANA_1" States @@ -34,6 +35,7 @@ ACTOR Mana2 : Ammo 124 Radius 8 Height 8 +FLOATBOB + +NOGRAVITY Inventory.Icon "MAN2G0" Inventory.PickupMessage "$TXT_MANA_2" States @@ -53,6 +55,7 @@ ACTOR Mana3 : CustomInventory 8004 Radius 8 Height 8 +FLOATBOB + +NOGRAVITY Inventory.PickupMessage "$TXT_MANA_BOTH" States { @@ -73,6 +76,7 @@ ACTOR ArtiBoostMana : CustomInventory 8003 Game Hexen SpawnID 26 +FLOATBOB + +NOGRAVITY +COUNTITEM +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH diff --git a/wadsrc/static/actors/hexen/speedboots.txt b/wadsrc/static/actors/hexen/speedboots.txt index 5fd6703b8..c22699b62 100644 --- a/wadsrc/static/actors/hexen/speedboots.txt +++ b/wadsrc/static/actors/hexen/speedboots.txt @@ -5,6 +5,7 @@ ACTOR ArtiSpeedBoots : PowerupGiver 8002 Game Hexen SpawnID 13 +FLOATBOB + +NOGRAVITY +COUNTITEM +INVENTORY.PICKUPFLASH Inventory.Icon ARTISPED diff --git a/wadsrc/static/actors/hexen/summon.txt b/wadsrc/static/actors/hexen/summon.txt index a4b3b8584..28c3c3267 100644 --- a/wadsrc/static/actors/hexen/summon.txt +++ b/wadsrc/static/actors/hexen/summon.txt @@ -7,6 +7,7 @@ ACTOR ArtiDarkServant : Inventory 86 native SpawnID 16 +COUNTITEM +FLOATBOB + +NOGRAVITY Inventory.RespawnTics 4230 Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" diff --git a/wadsrc/static/actors/hexen/teleportother.txt b/wadsrc/static/actors/hexen/teleportother.txt index 77a05f6af..49b20a0bd 100644 --- a/wadsrc/static/actors/hexen/teleportother.txt +++ b/wadsrc/static/actors/hexen/teleportother.txt @@ -7,6 +7,7 @@ ACTOR ArtiTeleportOther : Inventory 10040 native SpawnID 17 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/artiegg.txt b/wadsrc/static/actors/raven/artiegg.txt index d94f00151..2a9c6867e 100644 --- a/wadsrc/static/actors/raven/artiegg.txt +++ b/wadsrc/static/actors/raven/artiegg.txt @@ -31,6 +31,7 @@ ACTOR ArtiEgg : CustomInventory 30 SpawnID 14 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND @@ -85,6 +86,7 @@ ACTOR ArtiPork : CustomInventory 30 SpawnID 14 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/artitele.txt b/wadsrc/static/actors/raven/artitele.txt index 79811fd53..b0eedf1cd 100644 --- a/wadsrc/static/actors/raven/artitele.txt +++ b/wadsrc/static/actors/raven/artitele.txt @@ -7,6 +7,7 @@ ACTOR ArtiTeleport : Inventory 36 native SpawnID 18 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/ravenartifacts.txt b/wadsrc/static/actors/raven/ravenartifacts.txt index c02c19c3b..4f31ad5fb 100644 --- a/wadsrc/static/actors/raven/ravenartifacts.txt +++ b/wadsrc/static/actors/raven/ravenartifacts.txt @@ -8,6 +8,7 @@ ACTOR ArtiHealth : HealthPickup 82 Health 25 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND Inventory.Icon ARTIPTN2 @@ -32,6 +33,7 @@ ACTOR ArtiSuperHealth : HealthPickup 32 Health 100 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND Inventory.Icon ARTISPHL @@ -55,6 +57,7 @@ ACTOR ArtiFly : PowerupGiver 83 SpawnID 15 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.INTERHUBSTRIP Inventory.RespawnTics 4230 @@ -78,6 +81,7 @@ ACTOR ArtiInvulnerability : PowerupGiver 84 SpawnID 133 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.RespawnTics 4230 Inventory.Icon ARTIINVU @@ -101,6 +105,7 @@ ACTOR ArtiInvulnerability2 : PowerupGiver 84 SpawnID 133 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.RespawnTics 4230 Inventory.Icon ARTIDEFN @@ -123,6 +128,7 @@ ACTOR ArtiTorch : PowerupGiver 33 SpawnID 73 +COUNTITEM +FLOATBOB + +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.Icon ARTITRCH Inventory.PickupMessage "$TXT_ARTITORCH" diff --git a/wadsrc/static/actors/raven/ravenhealth.txt b/wadsrc/static/actors/raven/ravenhealth.txt index af951be1b..45cbe59b9 100644 --- a/wadsrc/static/actors/raven/ravenhealth.txt +++ b/wadsrc/static/actors/raven/ravenhealth.txt @@ -3,6 +3,7 @@ ACTOR CrystalVial : Health 81 Game Raven SpawnID 23 +FLOATBOB + +NOGRAVITY Inventory.Amount 10 Inventory.PickupMessage "$TXT_ITEMHEALTH" States From d4304c3bde102fffa49708f331afe454dc67a5c9 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 19 Nov 2013 19:49:17 -0600 Subject: [PATCH 044/311] Change tspeed += 2 to *= 2 - Fixed: The initial keyboard turn rate used the running initial rate whether +speed was down or not. --- src/g_game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 506b8e24b..081ffdb53 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -565,7 +565,7 @@ void G_BuildTiccmd (ticcmd_t *cmd) int tspeed = speed; if (turnheld < SLOWTURNTICS) - tspeed *= 2; // slow turn + tspeed += 2; // slow turn if (Button_Right.bDown) { From f4e9edccb9f6eb0cb4a368070a780229e59e1f7d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 19 Nov 2013 19:55:57 -0600 Subject: [PATCH 045/311] Don't display the cost in dialogues twice - Fixed: Commit 75dd5503, which was to enable the use of LANGUAGE substitutions for conversation items with a cost attached, neglected to remove the original code that attached the cost to the end of the item, so the cost got added twice. --- src/p_conversation.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index e51389ce8..6493bca36 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -522,19 +522,8 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) // If the first item check has a positive amount required, then // add that to the reply string. Otherwise, use the reply as-is. - if (rsp->Count[0] > 0) - { - char moneystr[128]; - - mysnprintf (moneystr, countof(moneystr), "%s for %u", rsp->Reply, rsp->Count[0]); - reply->Reply = copystring (moneystr); - reply->NeedsGold = true; - } - else - { - reply->Reply = copystring (rsp->Reply); - reply->NeedsGold = false; - } + reply->Reply = copystring (rsp->Reply); + reply->NeedsGold = (rsp->Count[0] > 0); // QuickYes messages are shown when you meet the item checks. // QuickNo messages are shown when you don't. From 1710e92c3a1a4d5458a67a6506c90d20e5a21937 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 21 Nov 2013 01:54:56 -0500 Subject: [PATCH 046/311] - Fix issues with building XCode projects with CMake. --- gdtoa/CMakeLists.txt | 6 ++++-- tools/lemon/CMakeLists.txt | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 4ad0be6de..91079d94c 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -17,13 +17,15 @@ add_definitions( -DINFNAN_CHECK -DMULTIPLE_THREADS ) if( NOT MSVC ) add_executable( arithchk arithchk.c ) + get_target_property( ARITHCHK_EXE arithchk LOCATION ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arith.h - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/arithchk >${CMAKE_CURRENT_BINARY_DIR}/arith.h + COMMAND ${ARITHCHK_EXE} >${CMAKE_CURRENT_BINARY_DIR}/arith.h DEPENDS arithchk ) add_executable( qnan qnan.c arith.h ) + get_target_property( QNAN_EXE qnan LOCATION ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/qnan >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h + COMMAND ${QNAN_EXE} >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h DEPENDS qnan ) set( GEN_FP_FILES arith.h gd_qnan.h ) diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt index 91b144575..f3b07a72f 100644 --- a/tools/lemon/CMakeLists.txt +++ b/tools/lemon/CMakeLists.txt @@ -5,13 +5,13 @@ set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) add_executable( lemon lemon.c ) # Lemon wants lempar.c in its directory -if( MSVC ) +if( NOT NO_GENERATOR_EXPRESSIONS ) add_custom_command( TARGET lemon POST_BUILD COMMAND echo $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/lempar.c $ ) -else( MSVC ) +else( NOT NO_GENERATOR_EXPRESSIONS ) add_custom_command( TARGET lemon POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/lempar.c ${CMAKE_CURRENT_BINARY_DIR} ) -endif( MSVC ) \ No newline at end of file +endif( NOT NO_GENERATOR_EXPRESSIONS ) \ No newline at end of file From 8bf5872fc0087d22a0b307c573a58e6010d2b055 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Nov 2013 10:27:08 +0100 Subject: [PATCH 047/311] - always add DelayImp.lib for MSVC. --- src/CMakeLists.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a9b0138d..ee98563b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,12 +142,8 @@ if( WIN32 ) comdlg32 ws2_32 setupapi - oleaut32 ) - - # For some reason this isn't implied on 2005 - if( MSVC80 ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} DelayImp ) - endif( MSVC80 ) + oleaut32 + DelayImp ) else( WIN32 ) if( APPLE ) set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" ) From c7632174d832c30d7d55caa283b53bd897f4da41 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 26 Nov 2013 12:49:23 -0500 Subject: [PATCH 048/311] - Fixed error in manifest embedding that stopped the binary from working on Windows XP. - Tweaked PK3 copying commands so that it shouldn't be possible to end up with files named Debug/Release. --- CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3715cdac8..625fceb1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,11 +26,11 @@ function( add_pk3 PK3_NAME PK3_DIR ) if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $/${PK3_NAME} DEPENDS zipdir ${PK3_DIR} ) else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} - COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} + COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}/${PK3_NAME} DEPENDS zipdir ${PK3_DIR} ) endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee98563b6..aa4013503 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1108,7 +1108,7 @@ if( MSVC ) endif( ZDOOM_GENERATE_MAPFILE ) add_custom_command(TARGET zdoom POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#2 + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#1 COMMENT "Adding manifest..." ) From 0c1d92834acb6b09236f4f41976bd94c8235935f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 26 Nov 2013 17:58:55 -0500 Subject: [PATCH 049/311] - Fixed: Some setups require the dynamic linking library to be linked explicitly, so specify it when using DYN_FLUIDSYNTH --- src/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa4013503..6c31ca69c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -507,12 +507,14 @@ message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" ) set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${GME_LIBRARIES}" "${FMOD_LIBRARY}" ) include_directories( "${ZLIB_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" ) -if( FLUIDSYNTH_FOUND ) - if( NOT DYN_FLUIDSYNTH) - set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FLUIDSYNTH_LIBRARIES}" ) - include_directories( "${FLUIDSYNTH_INCLUDE_DIR}" ) - endif( NOT DYN_FLUIDSYNTH ) -endif( FLUIDSYNTH_FOUND ) +if( NOT DYN_FLUIDSYNTH) + if( FLUIDSYNTH_FOUND ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FLUIDSYNTH_LIBRARIES}" ) + include_directories( "${FLUIDSYNTH_INCLUDE_DIR}" ) + endif( FLUIDSYNTH_FOUND ) +else( NOT DYN_FLUIDSYNTH ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} ${CMAKE_DL_LIBS} ) +endif( NOT DYN_FLUIDSYNTH ) # Start defining source files for ZDoom set( PLAT_WIN32_SOURCES From 7cb70f60b351f9c4da627455adeea789169f201d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Nov 2013 11:03:19 +0100 Subject: [PATCH 050/311] - removed duplicate #define warning in fmodsound.cpp. - commented out output of Cr0NpxState for floating point state because this variable was renamed in most recent Windows headers. - added CMAKE option to generate assembly output for release builds. - added my CMake-based project directory to .gitignore. --- .gitignore | 1 + CMakeLists.txt | 11 ++++++++--- src/sound/fmodsound.cpp | 2 ++ src/win32/i_crash.cpp | 9 +++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 09e3fb4c4..e27cd5a59 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ /tools/lemon/build /tools/re2c/build /wadsrc/*.pk3 +/build_vc2013 diff --git a/CMakeLists.txt b/CMakeLists.txt index 625fceb1d..a442b9ea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,9 +91,14 @@ if( MSVC ) # Disable run-time type information set( ALL_C_FLAGS "/GF /Gy /GR-" ) - # Avoid CRT DLL dependancies in release builds - set( REL_C_FLAGS "/MT /Oy" ) - + # Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations. + option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF ) + if( ZDOOM_GENERATE_ASM ) + set( REL_C_FLAGS "/MT /Oy /FAcs" ) + else( ZDOOM_GENERATE_ASM ) + set( REL_C_FLAGS "/MT /Oy" ) + endif( ZDOOM_GENERATE_ASM ) + # Debug allocations in debug builds set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" ) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index f832183c0..4bdc43081 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -629,7 +629,9 @@ bool FMODSoundRenderer::IsValid() // //========================================================================== +#ifndef FACILITY_VISUALCPP #define FACILITY_VISUALCPP ((LONG)0x6d) +#endif #define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err) static int CheckException(DWORD code) diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index d629bacc9..68d78295d 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -842,10 +842,15 @@ HANDLE WriteTextReport () Writef (file, "\r\nFPU State:\r\n ControlWord=%04x StatusWord=%04x TagWord=%04x\r\n" " ErrorOffset=%08x\r\n ErrorSelector=%08x\r\n DataOffset=%08x\r\n DataSelector=%08x\r\n" - " Cr0NpxState=%08x\r\n\r\n", + // Cr0NpxState was renamed in recent Windows headers so better skip it here. Its meaning is unknown anyway. + //" Cr0NpxState=%08x\r\n" + "\r\n" + , (WORD)ctxt->FloatSave.ControlWord, (WORD)ctxt->FloatSave.StatusWord, (WORD)ctxt->FloatSave.TagWord, ctxt->FloatSave.ErrorOffset, ctxt->FloatSave.ErrorSelector, ctxt->FloatSave.DataOffset, - ctxt->FloatSave.DataSelector, ctxt->FloatSave.Cr0NpxState); + ctxt->FloatSave.DataSelector + //, ctxt->FloatSave.Cr0NpxState + ); for (i = 0; i < 8; ++i) { From c6c6487a3014e954d4db8cf4533619e98bda95cb Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 28 Nov 2013 14:41:40 -0500 Subject: [PATCH 051/311] - Fixed: Got a little hyper corrective in c763217. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a442b9ea5..c6f9fd6ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ function( add_pk3 PK3_NAME PK3_DIR ) DEPENDS zipdir ${PK3_DIR} ) else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} - COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}/${PK3_NAME} + COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} DEPENDS zipdir ${PK3_DIR} ) endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) From c21beb0b6c88e0cbf599c01c601da3ee31d4a25e Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 29 Nov 2013 01:54:46 -0500 Subject: [PATCH 052/311] - Fixed: Some versions of Visual Studio put the map file in a different location. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c31ca69c..ff29f27e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1101,7 +1101,7 @@ if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) if( ZDOOM_GENERATE_MAPFILE ) if( NOT MSVC80 ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:${ZDOOM_EXE_NAME}.map") + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:\"$(TargetDir)${ZDOOM_EXE_NAME}.map\"") else( NOT MSVC80 ) # 2005 doesn't support naming the map file. set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP") endif( NOT MSVC80 ) From a8090dc22c31a765961a01a64108576fd0637fc9 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 29 Nov 2013 02:09:27 -0500 Subject: [PATCH 053/311] - Remove a hardcoded "zdoom" so that the name passed into the copy operation should always match that passed to /MAP. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff29f27e7..60cdb01f8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1128,7 +1128,7 @@ if( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSIONS ) if( ZDOOM_GENERATE_MAPFILE ) add_custom_command(TARGET zdoom POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $/zdoom.map ${ZDOOM_OUTPUT_DIR}/$.map + COMMAND ${CMAKE_COMMAND} -E copy_if_different $/${ZDOOM_EXE_NAME}.map ${ZDOOM_OUTPUT_DIR}/$.map COMMENT "Copying to output directory..." ) else( ZDOOM_GENERATE_MAPFILE ) add_custom_command(TARGET zdoom POST_BUILD From b9c032461e7279fc11e7dfe7e92b9212d400e1f0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2013 12:35:45 +0100 Subject: [PATCH 054/311] - add a CMake option to enable/disable SSE2 with Visual C++. This is necessary because since VC 2012 SSE2 is the default instruction set. --- CMakeLists.txt | 18 ++++++++++++++++-- src/CMakeLists.txt | 31 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6f9fd6ad..6f07d3ada 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,13 +91,27 @@ if( MSVC ) # Disable run-time type information set( ALL_C_FLAGS "/GF /Gy /GR-" ) + if( CMAKE_SIZEOF_VOID_P MATCHES "4") + # SSE2 option (mostly to switch it off in VC2012 and later where it's the default + option (ZDOOM_USE_SSE2 "Use SSE2 instruction set") + if (ZDOOM_USE_SSE2) + set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") + else (ZDOOM_USE_SSE2) + if (MSVC_VERSION GREATER 1699) + # On Visual C++ 2012 and later SSE2 is the default, so we need to switch it off explicitly + set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:IA32") + endif (MSVC_VERSION GREATER 1699) + endif (ZDOOM_USE_SSE2) + endif( CMAKE_SIZEOF_VOID_P MATCHES "4") + # Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations. option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF ) if( ZDOOM_GENERATE_ASM ) - set( REL_C_FLAGS "/MT /Oy /FAcs" ) + set( REL_C_FLAGS "/MT /Oy /Oi /FAcs" ) else( ZDOOM_GENERATE_ASM ) - set( REL_C_FLAGS "/MT /Oy" ) + set( REL_C_FLAGS "/MT /Oy /Oi" ) endif( ZDOOM_GENERATE_ASM ) + # Debug allocations in debug builds set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60cdb01f8..972e187db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -367,20 +367,23 @@ endif( NOT NO_ASM ) set( SSE_MATTERS NO ) -# SSE only matters on 32-bit targets. We check compiler flags to know if we can do it. -if( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) - CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH ) - CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 ) - if( CAN_DO_MFPMATH ) - set( SSE1_ENABLE "-msse -mfpmath=sse" ) - set( SSE2_ENABLE "-msse2 -mfpmath=sse" ) - set( SSE_MATTERS YES ) - elseif( CAN_DO_ARCHSSE2 ) - set( SSE1_ENABLE -arch:SSE ) - set( SSE2_ENABLE -arch:SSE2 ) - set( SSE_MATTERS YES ) - endif( CAN_DO_MFPMATH ) -endif( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) +# with global use of SSE 2 we do not need special handling for selected files +if (NOT ZDOOM_USE_SSE2) + # SSE only matters on 32-bit targets. We check compiler flags to know if we can do it. + if( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) + CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH ) + CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 ) + if( CAN_DO_MFPMATH ) + set( SSE1_ENABLE "-msse -mfpmath=sse" ) + set( SSE2_ENABLE "-msse2 -mfpmath=sse" ) + set( SSE_MATTERS YES ) + elseif( CAN_DO_ARCHSSE2 ) + set( SSE1_ENABLE -arch:SSE ) + set( SSE2_ENABLE -arch:SSE2 ) + set( SSE_MATTERS YES ) + endif( CAN_DO_MFPMATH ) + endif( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) +endif (NOT ZDOOM_USE_SSE2) if( SSE_MATTERS ) if( WIN32 ) From cbed4624faeb4b192f908b1a2a66b7f3744fb32a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Nov 2013 13:24:38 +0100 Subject: [PATCH 055/311] - added a user-settable factor for earthquake intensity. Value can be between 0 (no shaking) and 1 (normal shaking.) --- src/r_utility.cpp | 13 +++++++++---- wadsrc/static/menudef.txt | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 606cca840..356bfe741 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -89,6 +89,11 @@ CVAR (Bool, r_deathcamera, false, CVAR_ARCHIVE) CVAR (Int, r_clearbuffer, 0, 0) CVAR (Bool, r_drawvoxels, true, 0) CVAR (Bool, r_drawplayersprites, true, 0) // [RH] Draw player sprites? +CUSTOM_CVAR(Float, r_quakeintensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 0.f) self = 0.f; + else if (self > 1.f) self = 1.f; +} DCanvas *RenderTarget; // [RH] canvas to render to @@ -837,10 +842,10 @@ void R_SetupFrame (AActor *actor) int intensity = DEarthquake::StaticGetQuakeIntensity (camera); if (intensity != 0) { - viewx += ((pr_torchflicker() % (intensity<<2)) - -(intensity<<1))< Date: Fri, 29 Nov 2013 14:41:03 -0500 Subject: [PATCH 056/311] - Get as many files as possible as dependencies for pk3 building. (Kind of feels like CMake changes the behavior of depending on directories every now and then, but maybe it's just me.) --- CMakeLists.txt | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f07d3ada..a257cceab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,20 @@ else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) set( NO_GENERATOR_EXPRESSIONS ON ) endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) +# Function to get a recursive list of files, but also get the directory names +# as well unlike GLOB_RECURSE +function( glob_recurse_with_directories OUTVAR DIR ) + file( GLOB CHILDREN ${DIR}/* ) + foreach( CHILD ${CHILDREN} ) + if( IS_DIRECTORY ${CHILD} ) + set( TEMP_LIST "" ) + glob_recurse_with_directories( TEMP_LIST ${CHILD} ) + set( ${OUTVAR} ${${OUTVAR}} ${TEMP_LIST} ) + endif( IS_DIRECTORY ${CHILD} ) + endforeach( CHILD ${CHILDREN} ) + set( ${OUTVAR} ${${OUTVAR}} ${CHILDREN} PARENT_SCOPE ) +endfunction( glob_recurse_with_directories ) + # Simplify pk3 building, add_pk3(filename srcdirectory) function( add_pk3 PK3_NAME PK3_DIR ) get_target_property(ZIPDIR_EXE zipdir LOCATION) @@ -23,15 +37,18 @@ function( add_pk3 PK3_NAME PK3_DIR ) set( PK3_TARGET "pk3" ) endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) + # Get as many files as we can to depend on. + glob_recurse_with_directories( PK3_DEPENDS ${PK3_DIR} ) + if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $/${PK3_NAME} - DEPENDS zipdir ${PK3_DIR} ) + DEPENDS zipdir ${PK3_DIR} ${PK3_DEPENDS} ) else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} - DEPENDS zipdir ${PK3_DIR} ) + DEPENDS zipdir ${PK3_DIR} ${PK3_DEPENDS} ) endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_target( ${PK3_TARGET} ALL From c04a800e2b855d05283759ef1b21c50c61157c85 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 29 Nov 2013 17:10:29 -0500 Subject: [PATCH 057/311] - When doing OLDSTYLE builds we can use the RUNTIME_OUTPUT_DIRECTORY_ properties to force the output location properly. --- src/CMakeLists.txt | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 972e187db..4e1152294 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1098,16 +1098,23 @@ if( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) # Linux distributions are slow to adopt 2.6. :( set_target_properties( zdoom PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) set_target_properties( zdoom PROPERTIES OUTPUT_NAME ${ZDOOM_EXE_NAME} ) +else( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) + set_target_properties( zdoom PROPERTIES + RUNTIME_OUTPUT_NAME ${ZDOOM_EXE_NAME} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${ZDOOM_OUTPUT_DIR} + RUNTIME_OUTPUT_NAME_DEBUG ${ZDOOM_EXE_NAME}d + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${ZDOOM_OUTPUT_DIR} + RUNTIME_OUTPUT_NAME_MINSIZEREL ${ZDOOM_EXE_NAME}msr + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${ZDOOM_OUTPUT_DIR} + RUNTIME_OUTPUT_NAME_RELWITHDEBINFO ${ZDOOM_EXE_NAME}rd + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${ZDOOM_OUTPUT_DIR} + ) endif( NOT ZDOOM_OUTPUT_OLDSTYLE OR NO_GENERATOR_EXPRESSIONS ) if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) if( ZDOOM_GENERATE_MAPFILE ) - if( NOT MSVC80 ) - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP:\"$(TargetDir)${ZDOOM_EXE_NAME}.map\"") - else( NOT MSVC80 ) # 2005 doesn't support naming the map file. - set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP") - endif( NOT MSVC80 ) + set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /MAP") else( ZDOOM_GENERATE_MAPFILE ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"") endif( ZDOOM_GENERATE_MAPFILE ) @@ -1120,26 +1127,6 @@ if( MSVC ) create_default_target_launcher( zdoom WORKING_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) endif( MSVC ) -if( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSIONS ) - set_target_properties( zdoom PROPERTIES - RUNTIME_OUTPUT_NAME ${ZDOOM_EXE_NAME} - RUNTIME_OUTPUT_NAME_DEBUG ${ZDOOM_EXE_NAME}d - RUNTIME_OUTPUT_NAME_MINSIZEREL ${ZDOOM_EXE_NAME}msr - RUNTIME_OUTPUT_NAME_RELWITHDEBINFO ${ZDOOM_EXE_NAME}rd - ) - - if( ZDOOM_GENERATE_MAPFILE ) - add_custom_command(TARGET zdoom POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $/${ZDOOM_EXE_NAME}.map ${ZDOOM_OUTPUT_DIR}/$.map - COMMENT "Copying to output directory..." ) - else( ZDOOM_GENERATE_MAPFILE ) - add_custom_command(TARGET zdoom POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ ${ZDOOM_OUTPUT_DIR}/$ - COMMENT "Copying to output directory..." ) - endif( ZDOOM_GENERATE_MAPFILE ) -endif( ZDOOM_OUTPUT_OLDSTYLE AND NOT NO_GENERATOR_EXPRESSIONS ) - if( NOT WIN32 ) FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME} ]; then ln -sf ${CMAKE_CURRENT_BINARY_DIR}/${ZDOOM_EXE_NAME} ${ZDOOM_OUTPUT_DIR}/${ZDOOM_EXE_NAME}; fi" ) add_custom_command( TARGET zdoom POST_BUILD From 974619d5be66c39f44e4bcf90d48ce31e2123838 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 29 Nov 2013 17:13:34 -0500 Subject: [PATCH 058/311] - According to Graf, we should just let zipdir determine if the pk3 needs updating. --- CMakeLists.txt | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a257cceab..fca2e59b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,20 +13,6 @@ else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) set( NO_GENERATOR_EXPRESSIONS ON ) endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) -# Function to get a recursive list of files, but also get the directory names -# as well unlike GLOB_RECURSE -function( glob_recurse_with_directories OUTVAR DIR ) - file( GLOB CHILDREN ${DIR}/* ) - foreach( CHILD ${CHILDREN} ) - if( IS_DIRECTORY ${CHILD} ) - set( TEMP_LIST "" ) - glob_recurse_with_directories( TEMP_LIST ${CHILD} ) - set( ${OUTVAR} ${${OUTVAR}} ${TEMP_LIST} ) - endif( IS_DIRECTORY ${CHILD} ) - endforeach( CHILD ${CHILDREN} ) - set( ${OUTVAR} ${${OUTVAR}} ${CHILDREN} PARENT_SCOPE ) -endfunction( glob_recurse_with_directories ) - # Simplify pk3 building, add_pk3(filename srcdirectory) function( add_pk3 PK3_NAME PK3_DIR ) get_target_property(ZIPDIR_EXE zipdir LOCATION) @@ -37,21 +23,21 @@ function( add_pk3 PK3_NAME PK3_DIR ) set( PK3_TARGET "pk3" ) endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" ) - # Get as many files as we can to depend on. - glob_recurse_with_directories( PK3_DEPENDS ${PK3_DIR} ) - if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $/${PK3_NAME} - DEPENDS zipdir ${PK3_DIR} ${PK3_DEPENDS} ) + DEPENDS zipdir ) else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR} - DEPENDS zipdir ${PK3_DIR} ${PK3_DEPENDS} ) + DEPENDS zipdir ) endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE ) + # Touch the zipdir executable here so that the pk3s are forced to rebuild + # each time since their dependecy has "changed." add_custom_target( ${PK3_TARGET} ALL + COMMAND ${CMAKE_COMMAND} -E touch ${ZIPDIR_EXE} DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ) endfunction( add_pk3 ) From e7225bced6a83314cc67812c3097890aeff2ea6e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 01:15:10 +0100 Subject: [PATCH 059/311] - check negative XScale on sprites to allow mirroring. --- src/r_things.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/r_things.cpp b/src/r_things.cpp index 9bdba99f9..7243ac6f9 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -608,6 +608,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } } + if (spritescaleX < 0) + { + spritescaleX = -spritescaleX; + flip = !flip; + } if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null)) { return; From 698495efc5525fa826d77e066ca100e0231f7664 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 01:21:43 +0100 Subject: [PATCH 060/311] - fixed: missing return in playerinfo CCMD added. --- src/d_netinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 12fb187ae..c2fb88aaf 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -1018,6 +1018,7 @@ CCMD (playerinfo) if (!playeringame[i]) { Printf(TEXTCOLOR_ORANGE "Player %d is not in the game\n", i); + return; } // Print special info From 7e062f394b11c300b77cc04fe94aa2cab7b0d434 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 01:26:30 +0100 Subject: [PATCH 061/311] - fixed: animated door textures defined by index were not added to the sequence. - fixed: animated doors should set 'no decals' for the texture. - added 'allowdecals' option to override the above. --- src/textures/animations.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 5a6f0729a..09518cd5e 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -776,8 +776,13 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc) { sc.ScriptError ("Unknown texture %s", sc.String); } - frames.Push (v); } + frames.Push(v); + if (!sc.CheckString("allowdecals")) + { + Texture(v)->bNoDecals = true; + } + } else { From 662bc7a3ac48ec0aa4e0ac8417db6ad20277616e Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 1 Dec 2013 22:06:48 +1300 Subject: [PATCH 062/311] cl_bloodtype could break playsim sync Corrected entries were blood would spawn inconsistently because of cl_bloodtype. Blood now always spawns but is marked invisible according to cl_bloodtype. --- src/g_hexen/a_fighteraxe.cpp | 2 -- src/p_map.cpp | 14 ++++++++------ src/p_mobj.cpp | 16 +++++++++++----- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index 50b378e50..f80af876b 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -26,8 +26,6 @@ void A_FAxeAttack (AActor *actor); extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget); -EXTERN_CVAR (Int, cl_bloodtype) - // The Fighter's Axe -------------------------------------------------------- class AFWeapAxe : public AFighterWeapon diff --git a/src/p_map.cpp b/src/p_map.cpp index a3379910d..0e66ee58d 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4879,7 +4879,8 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) const PClass *bloodcls = thing->GetBloodType(); P_TraceBleed (newdam > 0 ? newdam : cpos->crushchange, thing); - if (cl_bloodtype <= 1 && bloodcls != NULL) + + if (bloodcls != NULL) { AActor *mo; @@ -4892,14 +4893,15 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } + + if (!(cl_bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; } + + angle_t an; + an = (M_Random () - 128) << 24; if (cl_bloodtype >= 1) { - angle_t an; - - an = (M_Random () - 128) << 24; - P_DrawSplash2 (32, thing->x, thing->y, - thing->z + thing->height/2, an, 2, bloodcolor); + P_DrawSplash2(32, thing->x, thing->y, thing->z + thing->height / 2, an, 2, bloodcolor); } } if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 69d4203fe..0337ef0dd 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4874,7 +4874,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc if (bloodcls != NULL && !(GetDefaultByType(bloodcls)->flags4 & MF4_ALLOWPARTICLES)) bloodtype = 0; - if (bloodcls!=NULL && bloodtype <= 1) + if (bloodcls != NULL) { z += pr_spawnblood.Random2 () << 10; th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement @@ -4945,7 +4945,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc } statedone: - + if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE; if (bloodtype >= 1) P_DrawSplash2 (40, x, y, z, dir, 2, bloodcolor); } @@ -4966,7 +4966,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) if (bloodcls != NULL && !(GetDefaultByType(bloodcls)->flags4 & MF4_ALLOWPARTICLES)) bloodtype = 0; - if (bloodcls!=NULL && bloodtype <= 1) + if (bloodcls != NULL) { AActor *mo; @@ -4981,6 +4981,8 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } + + if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; } if (bloodtype >= 1) { @@ -5004,7 +5006,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) if (bloodcls != NULL && !(GetDefaultByType(bloodcls)->flags4 & MF4_ALLOWPARTICLES)) bloodtype = 0; - if (bloodcls!=NULL && bloodtype <= 1) + if (bloodcls != NULL) { AActor *mo; @@ -5019,6 +5021,8 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } + + if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; } if (bloodtype >= 1) { @@ -5047,7 +5051,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) if (bloodcls != NULL && !(GetDefaultByType(bloodcls)->flags4 & MF4_ALLOWPARTICLES)) bloodtype = 0; - if (bloodcls!=NULL && bloodtype <= 1) + if (bloodcls != NULL) { AActor *th; th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement @@ -5064,6 +5068,8 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) { th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } + + if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE; } if (bloodtype >= 1) { From c5b2c9557299eba078359af57531c1d31a957f1e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 15:11:41 +0100 Subject: [PATCH 063/311] - fixed placement and handling of 'allowdecals' for animated doors. --- src/textures/animations.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 09518cd5e..13413ae70 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -778,11 +778,10 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc) } } frames.Push(v); - if (!sc.CheckString("allowdecals")) - { - Texture(v)->bNoDecals = true; - } - + } + else if (!sc.Compare("allowdecals")) + { + if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = true; } else { From 7045f195f31eb4db41f38d4535dab45ed1fb427b Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 2 Dec 2013 06:23:22 +1300 Subject: [PATCH 064/311] Removed excess value from stall debug output The debug output for a stalled Arbitrator had an excess Net_Arbitrator value, bumping the gametic+counts value off the output. --- src/d_net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 9c4bf14dd..37e3f589e 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1853,7 +1853,7 @@ void TryRunTics (void) { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. if (debugfile) fprintf (debugfile, "Arbitrator is slow (%i to %i)\n", - Net_Arbitrator, nettics[Net_Arbitrator], gametic+counts); + nettics[Net_Arbitrator], gametic+counts); //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. if(i != 0) remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true; From 25f60779fdf907dbe628ad00a572777d73ff3ce9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 20:20:26 +0100 Subject: [PATCH 065/311] - fixed: The 'allowdecals' check in animated doors was wrong. --- src/textures/animations.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 13413ae70..e35550d51 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -779,7 +779,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc) } frames.Push(v); } - else if (!sc.Compare("allowdecals")) + else if (sc.Compare("allowdecals")) { if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = true; } From 86d7a326be234c645b10221248ecdbdc2ed1f0e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Dec 2013 21:11:33 +0100 Subject: [PATCH 066/311] - allowdecals logic was nonfunctional. --- src/textures/animations.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index e35550d51..433baa874 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -749,8 +749,11 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc) { error = true; } - - while (sc.GetString ()) + else + { + Texture(anim.BaseTexture)->bNoDecals = true; + } + while (sc.GetString()) { if (sc.Compare ("opensound")) { @@ -781,7 +784,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc) } else if (sc.Compare("allowdecals")) { - if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = true; + if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = false; } else { From c959b3f250386a239521e63f74b1c4e897fbfa36 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2013 15:28:09 +0100 Subject: [PATCH 067/311] - added 'subtract' render style to DECORATE parser. This is actually 'reverse subtract' --- src/r_data/renderstyle.cpp | 6 ++++-- src/r_data/renderstyle.h | 1 + src/thingdef/thingdef_properties.cpp | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/r_data/renderstyle.cpp b/src/r_data/renderstyle.cpp index 4b1d9fed4..4259b3440 100644 --- a/src/r_data/renderstyle.cpp +++ b/src/r_data/renderstyle.cpp @@ -57,7 +57,8 @@ FRenderStyle LegacyRenderStyles[STYLE_Count] = /* STYLE_Add */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0 }}, /* STYLE_Shaded */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed }}, /* STYLE_TranslucentStencil */{{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed }}, - /* STYLE_Shadow */{{ STYLEOP_Shadow, 0, 0, 0 }}, + /* STYLE_Shadow */ {{ STYLEOP_Shadow, 0, 0, 0 }}, + /* STYLE_Subtract*/ {{ STYLEOP_RevSub, STYLEALPHA_One, STYLEALPHA_One, 0 }}, }; #else FRenderStyle LegacyRenderStyles[STYLE_Count]; @@ -74,7 +75,8 @@ static const BYTE Styles[STYLE_Count * 4] = STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0, STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed, - STYLEOP_Shadow, 0, 0, 0 + STYLEOP_Shadow, 0, 0, 0, + STYLEOP_RevSub, STYLEALPHA_One, STYLEALPHA_One, 0, }; static struct LegacyInit diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index 8133557d5..bd589e8c7 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -49,6 +49,7 @@ enum ERenderStyle STYLE_Shaded, // Treat patch data as alpha values for alphacolor STYLE_TranslucentStencil, STYLE_Shadow, + STYLE_Subtract, // Actually this is 'reverse subtract' but this is what normal people would expect by 'subtract'. STYLE_Count }; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index d6731aafa..61ab5b968 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -796,11 +796,11 @@ DEFINE_PROPERTY(renderstyle, S, Actor) { PROP_STRING_PARM(str, 0); static const char * renderstyles[]={ - "NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD","SHADED", NULL}; + "NONE", "NORMAL", "FUZZY", "SOULTRANS", "OPTFUZZY", "STENCIL", "TRANSLUCENT", "ADD", "SHADED", "SUBTRACT", NULL }; static const int renderstyle_values[]={ STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, - STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded}; + STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded, STYLE_Subtract}; // make this work for old style decorations, too. if (!strnicmp(str, "style_", 6)) str+=6; From 31c9a0b0e892cecbd93780cbc08c65ceb7962550 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 5 Dec 2013 15:36:20 +0100 Subject: [PATCH 068/311] - Subtract should respect alpha. --- src/r_data/renderstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_data/renderstyle.cpp b/src/r_data/renderstyle.cpp index 4259b3440..660cd8f09 100644 --- a/src/r_data/renderstyle.cpp +++ b/src/r_data/renderstyle.cpp @@ -58,7 +58,7 @@ FRenderStyle LegacyRenderStyles[STYLE_Count] = /* STYLE_Shaded */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed }}, /* STYLE_TranslucentStencil */{{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed }}, /* STYLE_Shadow */ {{ STYLEOP_Shadow, 0, 0, 0 }}, - /* STYLE_Subtract*/ {{ STYLEOP_RevSub, STYLEALPHA_One, STYLEALPHA_One, 0 }}, + /* STYLE_Subtract*/ {{ STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0 }}, }; #else FRenderStyle LegacyRenderStyles[STYLE_Count]; @@ -76,7 +76,7 @@ static const BYTE Styles[STYLE_Count * 4] = STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed, STYLEOP_Shadow, 0, 0, 0, - STYLEOP_RevSub, STYLEALPHA_One, STYLEALPHA_One, 0, + STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0, }; static struct LegacyInit From 74dee4cd6397a7eacb06fb84f18f72bd69c3752a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Dec 2013 11:24:58 +0100 Subject: [PATCH 069/311] - removed ddraw.lib from CMake files because that library is not used anymore. --- src/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e1152294..2bf5a5a8c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -104,9 +104,6 @@ if( WIN32 ) include_directories( ${XINPUT_INCLUDE_DIR} ) endif( NOT XINPUT_INCLUDE_DIR ) - find_library( DX_ddraw_LIBRARY ddraw - PATHS ENV DXSDK_DIR - PATH_SUFFIXES Lib Lib/${XBITS} ) find_library( DX_dxguid_LIBRARY dxguid PATHS ENV DXSDK_DIR PATH_SUFFIXES Lib Lib/${XBITS} ) @@ -115,9 +112,6 @@ if( WIN32 ) PATH_SUFFIXES Lib Lib/${XBITS} ) set( DX_LIBS_FOUND YES ) - if( NOT DX_ddraw_LIBRARY ) - set( DX_LIBS_FOUND NO ) - endif( NOT DX_ddraw_LIBRARY ) if( NOT DX_dxguid_LIBRARY ) set( DX_LIBS_FOUND NO ) endif( NOT DX_dxguid_LIBRARY ) @@ -132,7 +126,6 @@ if( WIN32 ) set( ZDOOM_LIBS wsock32 winmm - "${DX_ddraw_LIBRARY}" "${DX_dxguid_LIBRARY}" "${DX_dinput8_LIBRARY}" ole32 From 10c312f55ce3a99f9cb027d6398d235982e6fc8d Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 13 Dec 2013 02:51:15 -0500 Subject: [PATCH 070/311] - Silence GCC PCD_PRINTBINARY warning since we've been able to since GCC 4.6. --- src/p_acs.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 32a70cd15..582385c48 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6796,7 +6796,18 @@ scriptwait: break; case PCD_PRINTBINARY: +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))) +#define HAS_DIAGNOSTIC_PRAGMA +#endif +#ifdef HAS_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat=" +#pragma GCC diagnostic ignored "-Wformat-extra-args" +#endif work.AppendFormat ("%B", STACK(1)); +#ifdef HAS_DIAGNOSTIC_PRAGMA +#pragma GCC diagnostic pop +#endif --sp; break; From 12d45bbc33ed833b1d30f7180e5d3dcca1a0f21e Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 13 Dec 2013 03:00:35 -0500 Subject: [PATCH 071/311] - Use setenv for LC_NUMERIC since setlocale gets reset by the libraries on some systems. --- src/sdl/i_main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 65b992f6a..1736305d8 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -257,7 +257,12 @@ int main (int argc, char **argv) #if defined(__MACH__) && !defined(NOASM) unprotect_rtext(); #endif - + + // Set LC_NUMERIC environment variable in case some library decides to + // clear the setlocale call at least this will be correct. + // Note that the LANG environment variable is overridden by LC_* + setenv ("LC_NUMERIC", "C", 1); + #ifndef NO_GTK GtkAvailable = gtk_init_check (&argc, &argv); #endif From a993b0288a0364eafe79c229af162dfc061cc717 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 16 Dec 2013 23:02:27 +1300 Subject: [PATCH 072/311] Stop prediction from playing and stopping sounds Player prediction would play *jump and stop falling sounds, creating odd cases of sound repetition before the gametic caught up. --- src/p_user.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 938c7727f..14fa9c12c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2473,9 +2473,10 @@ void P_PlayerThink (player_t *player) if ( player->cheats & CF_HIGHJUMP ) jumpvelz *= 2; player->mo->velz += jumpvelz; - S_Sound (player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM); player->mo->flags2 &= ~MF2_ONMOBJ; player->jumpTics = -1; + if (!(player->cheats & CF_PREDICTING)) + S_Sound(player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM); } } @@ -2502,7 +2503,7 @@ void P_PlayerThink (player_t *player) { player->mo->flags2 |= MF2_FLY; player->mo->flags |= MF_NOGRAVITY; - if (player->mo->velz <= -39*FRACUNIT) + if ((player->mo->velz <= -39 * FRACUNIT) && !(player->cheats & CF_PREDICTING)) { // Stop falling scream S_StopSound (player->mo, CHAN_VOICE); } From ae49044f96e39965b37f4f8ab4562fec130c9d84 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Dec 2013 17:59:58 +0100 Subject: [PATCH 073/311] - let 'showloadtimes' measure UDMF parsing. --- src/p_setup.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 3693e9f7e..315da4ffc 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3754,7 +3754,9 @@ void P_SetupLevel (char *lumpname, int position) } else { + times[0].Clock(); P_ParseTextMap(map, missingtex); + times[0].Unclock(); } times[6].Clock(); From 6e0f885135b4e562c0355b08aa52ef1a034dcf9f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 25 Dec 2013 22:30:47 +0100 Subject: [PATCH 074/311] - fixed: The 3D floor setup code treated alphas larger than 255 as translucent. This was causing problems with ZDCMP2 in GZDoom --- src/p_3dfloors.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 51ac24229..95ced549a 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -293,8 +293,9 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) FTextureID tex = line->sidedef[0]->GetTexture(side_t::top); if (!tex.Exists() && alpha<255) { - alpha=clamp(-tex.GetIndex(), 0, 255); + alpha = -tex.GetIndex(); } + alpha = clamp(alpha, 0, 255); if (alpha==0) flags&=~(FF_RENDERALL|FF_BOTHPLANES|FF_ALLSIDES); else if (alpha!=255) flags|=FF_TRANSLUCENT; From 455145d611e0707fbf4f6fbcaf9cf7b82cf1b94e Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Thu, 2 Jan 2014 00:04:32 +1300 Subject: [PATCH 075/311] Stall testing for interpolation Uncapped framerate never triggered the stall detection code, as it never tried to process a frame to start with. --- src/d_net.cpp | 77 ++++++++++++++++++++++++++++----------------------- src/d_net.h | 3 ++ 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 37e3f589e..c912d29a2 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1747,6 +1747,8 @@ void TryRunTics (void) if (counts == 0 && !doWait) { + // Check possible stall conditions + Net_CheckLastRecieved(counts); return; } @@ -1824,41 +1826,8 @@ void TryRunTics (void) if (lowtic < gametic) I_Error ("TryRunTics: lowtic < gametic"); - // [Ed850] Check to see the last time a packet was recieved. - // If it's longer then 3 seconds, a node has likely stalled. - if(I_GetTime(false) - lastglobalrecvtime >= TICRATE*3) - { - lastglobalrecvtime = I_GetTime(false); //Bump the count - - if(NetMode == NET_PeerToPeer || consoleplayer == Net_Arbitrator) - { - //Keep the local node in the for loop so we can still log any cases where the local node is /somehow/ late. - //However, we don't send a resend request for sanity reasons. - for (i = 0; i < doomcom.numnodes; i++) - { - if (nodeingame[i] && nettics[i] < gametic + counts) - { - if (debugfile) - fprintf (debugfile, "%i is slow (%i to %i)\n", - i, nettics[i], gametic+counts); - //Send resend request to the late node. Also mark the node as waiting to display it in the hud. - if(i != 0) - remoteresend[i] = players[playerfornode[i]].waiting = hadlate = true; - } - else - players[playerfornode[i]].waiting = false; - } - } - else - { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. - if (debugfile) - fprintf (debugfile, "Arbitrator is slow (%i to %i)\n", - nettics[Net_Arbitrator], gametic+counts); - //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. - if(i != 0) - remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true; - } - } + // Check possible stall conditions + Net_CheckLastRecieved (counts); // don't stay in here forever -- give the menu a chance to work if (I_GetTime (false) - entertic >= TICRATE/3) @@ -1901,6 +1870,44 @@ void TryRunTics (void) } } +void Net_CheckLastRecieved (int counts) +{ + // [Ed850] Check to see the last time a packet was recieved. + // If it's longer then 3 seconds, a node has likely stalled. + if (I_GetTime(false) - lastglobalrecvtime >= TICRATE * 3) + { + lastglobalrecvtime = I_GetTime(false); //Bump the count + + if (NetMode == NET_PeerToPeer || consoleplayer == Net_Arbitrator) + { + //Keep the local node in the for loop so we can still log any cases where the local node is /somehow/ late. + //However, we don't send a resend request for sanity reasons. + for (int i = 0; i < doomcom.numnodes; i++) + { + if (nodeingame[i] && nettics[i] <= gametic + counts) + { + if (debugfile && !players[playerfornode[i]].waiting) + fprintf(debugfile, "%i is slow (%i to %i)\n", + i, nettics[i], gametic + counts); + //Send resend request to the late node. Also mark the node as waiting to display it in the hud. + if (i != 0) + remoteresend[i] = players[playerfornode[i]].waiting = hadlate = true; + } + else + players[playerfornode[i]].waiting = false; + } + } + else + { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. + if (debugfile && !players[playerfornode[Net_Arbitrator]].waiting) + fprintf(debugfile, "Arbitrator is slow (%i to %i)\n", + nettics[Net_Arbitrator], gametic + counts); + //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. + remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true; + } + } +} + void Net_NewMakeTic (void) { specials.NewMakeTic (); diff --git a/src/d_net.h b/src/d_net.h index 507723d53..4cd3e66f5 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -115,6 +115,9 @@ void D_QuitNetGame (void); //? how many ticks to run? void TryRunTics (void); +//Use for checking to see if the netgame has stalled +void Net_CheckLastRecieved(int); + // [RH] Functions for making and using special "ticcmds" void Net_NewMakeTic (); void Net_WriteByte (BYTE); From 49edd7c60c53376a09c385adf841960f71b81662 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 2 Jan 2014 01:59:04 -0500 Subject: [PATCH 076/311] - Add support for cross compiling so that OS X PowerPC builds can still be made on systems without rosetta (10.7+). (Compiling x86 binaries on ppc should also be possible.) --- CMakeLists.txt | 15 +++++++++++++++ gdtoa/CMakeLists.txt | 9 +++++++-- tools/CMakeLists.txt | 2 ++ tools/fixrtext/CMakeLists.txt | 6 +++++- tools/lemon/CMakeLists.txt | 7 +++++-- tools/re2c/CMakeLists.txt | 7 +++++++ tools/updaterevision/CMakeLists.txt | 5 ++++- tools/zipdir/CMakeLists.txt | 18 +++++++++++------- 8 files changed, 56 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fca2e59b3..28379a377 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,17 @@ else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) set( NO_GENERATOR_EXPRESSIONS ON ) endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7) +# Support cross compiling +option( FORCE_CROSSCOMPILE "Turn on cross compiling." NO ) +if( FORCE_CROSSCOMPILE ) + set( CMAKE_CROSSCOMPILING TRUE ) +endif( FORCE_CROSSCOMPILE ) + +if(CMAKE_CROSSCOMPILING) + set(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Export file from native build.") + include(${IMPORT_EXECUTABLES}) +endif(CMAKE_CROSSCOMPILING) + # Simplify pk3 building, add_pk3(filename srcdirectory) function( add_pk3 PK3_NAME PK3_DIR ) get_target_property(ZIPDIR_EXE zipdir LOCATION) @@ -208,3 +219,7 @@ add_subdirectory( src ) if( NOT WIN32 AND NOT APPLE ) add_subdirectory( output_sdl ) endif( NOT WIN32 AND NOT APPLE ) + +if( NOT CMAKE_CROSSCOMPILING ) + export(TARGETS ${CROSS_EXPORTS} FILE "${CMAKE_BINARY_DIR}/ImportExecutables.cmake" ) +endif( NOT CMAKE_CROSSCOMPILING ) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 91079d94c..9403f1793 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -16,13 +16,18 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) add_definitions( -DINFNAN_CHECK -DMULTIPLE_THREADS ) if( NOT MSVC ) - add_executable( arithchk arithchk.c ) + if( NOT CMAKE_CROSSCOMPILING ) + add_executable( arithchk arithchk.c ) + endif( NOT CMAKE_CROSSCOMPILING ) get_target_property( ARITHCHK_EXE arithchk LOCATION ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arith.h COMMAND ${ARITHCHK_EXE} >${CMAKE_CURRENT_BINARY_DIR}/arith.h DEPENDS arithchk ) - add_executable( qnan qnan.c arith.h ) + if( NOT CMAKE_CROSSCOMPILING ) + add_executable( qnan qnan.c arith.h ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} arithchk qnan PARENT_SCOPE ) + endif( NOT CMAKE_CROSSCOMPILING ) get_target_property( QNAN_EXE qnan LOCATION ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h COMMAND ${QNAN_EXE} >${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 1d1de65e5..08a1c4f4b 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -7,3 +7,5 @@ if( WIN32 ) endif( WIN32 ) add_subdirectory( updaterevision ) add_subdirectory( zipdir ) + +set( CROSS_EXPORTS ${CROSS_EXPORTS} PARENT_SCOPE ) diff --git a/tools/fixrtext/CMakeLists.txt b/tools/fixrtext/CMakeLists.txt index 9af8eb7f4..2b0ab2cda 100644 --- a/tools/fixrtext/CMakeLists.txt +++ b/tools/fixrtext/CMakeLists.txt @@ -1,2 +1,6 @@ cmake_minimum_required( VERSION 2.4 ) -add_executable( fixrtext fixrtext.c ) + +if( NOT CMAKE_CROSSCOMPILING ) + add_executable( fixrtext fixrtext.c ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} fixrtext PARENT_SCOPE ) +endif( NOT CMAKE_CROSSCOMPILING ) diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt index f3b07a72f..0a9b558ee 100644 --- a/tools/lemon/CMakeLists.txt +++ b/tools/lemon/CMakeLists.txt @@ -1,8 +1,11 @@ cmake_minimum_required( VERSION 2.4 ) -set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) +if( NOT CMAKE_CROSSCOMPILING ) + set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) -add_executable( lemon lemon.c ) + add_executable( lemon lemon.c ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} lemon PARENT_SCOPE ) +endif( NOT CMAKE_CROSSCOMPILING ) # Lemon wants lempar.c in its directory if( NOT NO_GENERATOR_EXPRESSIONS ) diff --git a/tools/re2c/CMakeLists.txt b/tools/re2c/CMakeLists.txt index e6068a28d..1284f3506 100644 --- a/tools/re2c/CMakeLists.txt +++ b/tools/re2c/CMakeLists.txt @@ -1,4 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) + +if( NOT CMAKE_CROSSCOMPILING ) + include( CheckFunctionExists ) include( CheckTypeSize ) @@ -30,3 +33,7 @@ add_executable( re2c scanner.cc substr.cc translate.cc ) + +set( CROSS_EXPORTS ${CROSS_EXPORTS} re2c PARENT_SCOPE ) + +endif( NOT CMAKE_CROSSCOMPILING ) diff --git a/tools/updaterevision/CMakeLists.txt b/tools/updaterevision/CMakeLists.txt index d985b9e3f..b857ffbe7 100644 --- a/tools/updaterevision/CMakeLists.txt +++ b/tools/updaterevision/CMakeLists.txt @@ -17,7 +17,10 @@ if( WIN32 ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) endif( WIN32 ) -add_executable( updaterevision updaterevision.c ${TRUSTINFO} ) +if( NOT CMAKE_CROSSCOMPILING ) + add_executable( updaterevision updaterevision.c ${TRUSTINFO} ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} updaterevision PARENT_SCOPE ) +endif( NOT CMAKE_CROSSCOMPILING ) if( MT_MERGE ) get_target_property( UPDATEREVISION_EXE updaterevision LOCATION ) diff --git a/tools/zipdir/CMakeLists.txt b/tools/zipdir/CMakeLists.txt index 40c4042b9..3ee22ddc3 100644 --- a/tools/zipdir/CMakeLists.txt +++ b/tools/zipdir/CMakeLists.txt @@ -1,8 +1,12 @@ cmake_minimum_required( VERSION 2.4 ) -message(STATUS "${ZLIB_INCLUDE_DIR}" ) -message(STATUS "${BZIP2_INCLUDE_DIR}" ) -message(STATUS "${LZMA_INCLUDE_DIR}" ) -include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" ) -add_executable( zipdir - zipdir.c ) -target_link_libraries( zipdir ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} lzma ) + +if(NOT CMAKE_CROSSCOMPILING) + message(STATUS "${ZLIB_INCLUDE_DIR}" ) + message(STATUS "${BZIP2_INCLUDE_DIR}" ) + message(STATUS "${LZMA_INCLUDE_DIR}" ) + include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" ) + add_executable( zipdir + zipdir.c ) + target_link_libraries( zipdir ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} lzma ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} zipdir PARENT_SCOPE ) +endif(NOT CMAKE_CROSSCOMPILING) From 1e50a0af9ea70967bb4e2d5f343eb23e31e979df Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 2 Jan 2014 03:06:06 -0500 Subject: [PATCH 077/311] =?UTF-8?q?-=20Hard=20code=20gdtoa=20constants=20f?= =?UTF-8?q?or=20OS=20X=20since=20the=20programs=20can=E2=80=99t=20always?= =?UTF-8?q?=20be=20run=20on=20the=20target.=20=20(The=20values=20are=20the?= =?UTF-8?q?=20same=20for=20GCC=20and=20Clang.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gdtoa/CMakeLists.txt | 4 ++-- gdtoa/gdtoa.h | 22 +++++++++++++++++++++- gdtoa/gdtoaimp.h | 30 +++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 9403f1793..7a1304d0f 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -15,7 +15,7 @@ endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" S include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) add_definitions( -DINFNAN_CHECK -DMULTIPLE_THREADS ) -if( NOT MSVC ) +if( NOT MSVC AND NOT APPLE ) if( NOT CMAKE_CROSSCOMPILING ) add_executable( arithchk arithchk.c ) endif( NOT CMAKE_CROSSCOMPILING ) @@ -35,7 +35,7 @@ if( NOT MSVC ) set( GEN_FP_FILES arith.h gd_qnan.h ) set( GEN_FP_DEPS ${CMAKE_CURRENT_BINARY_DIR}/arith.h ${CMAKE_CURRENTY_BINARY_DIR}/gd_qnan.h ) -endif( NOT MSVC ) +endif( NOT MSVC AND NOT APPLE ) add_library( gdtoa ${GEN_FP_FILES} diff --git a/gdtoa/gdtoa.h b/gdtoa/gdtoa.h index 95132294e..2707ff7df 100644 --- a/gdtoa/gdtoa.h +++ b/gdtoa/gdtoa.h @@ -32,7 +32,7 @@ THIS SOFTWARE. #ifndef GDTOA_H_INCLUDED #define GDTOA_H_INCLUDED -#ifdef _MSC_VER +#if defined(_MSC_VER) /* [RH] Generating arith.h strikes me as too cumbersome under Visual * Studio, so here's the equivalent, given the limited number of * architectures that MSC can target. (Itanium? Who cares about that?) @@ -43,6 +43,26 @@ THIS SOFTWARE. #ifdef _M_X64 #define X64_bit_pointers #endif +#elif defined(__APPLE__) +/* [BL] While generating the files may be easy, on OS X we have cross + * compiling to deal with, which means we can't run the generation + * program on the target. + */ +#if defined(__x86_64__) +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers +#elif defined(__i386__) +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#else +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align +#endif #else #include "arith.h" #endif diff --git a/gdtoa/gdtoaimp.h b/gdtoa/gdtoaimp.h index 023d97062..f93e03ef5 100644 --- a/gdtoa/gdtoaimp.h +++ b/gdtoa/gdtoaimp.h @@ -167,7 +167,7 @@ THIS SOFTWARE. #define GDTOAIMP_H_INCLUDED #include "gdtoa.h" -#ifdef _MSC_VER +#if defined(_MSC_VER) /* [RH] Generating gd_qnan.h strikes me as too cumbersome under Visual * Studio, so here's the equivalent, given the limited number of * architectures that MSC can target. (Itanium? Who cares about that?) @@ -188,6 +188,34 @@ THIS SOFTWARE. * it turns out that it has a true long double type. I thought that * all ia32 compilers had phased out extended precision. */ +#elif defined(__APPLE__) +#if defined(__x86_64__) || defined(__i386__) +#define f_QNAN 0xffc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0xfff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0xffff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0xffff +#else +#define f_QNAN 0xffc00000 +#define d_QNAN0 0xfff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0xfff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0xfff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 +#endif #else #include "gd_qnan.h" #endif From 50cec119a08d048fc61a38f639a0acbdc1f8f0f3 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 2 Jan 2014 19:12:03 -0500 Subject: [PATCH 078/311] - Work around GCC 4.8 bug 54570 --- src/parsecontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parsecontext.cpp b/src/parsecontext.cpp index 6fa36b2a8..21b7a0ea6 100644 --- a/src/parsecontext.cpp +++ b/src/parsecontext.cpp @@ -157,6 +157,10 @@ loop: { return TokenTrans[NUM]; } +#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 + // Work around GCC 4.8 bug 54570 causing release build crashes. + asm("" : "+g" (yylval)); +#endif strcpy (yylval->sym, token); return TokenTrans[SYM]; } From 511bdc7208ea0589b059a49b2b43c5f761a53e7b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 2 Jan 2014 19:12:03 -0500 Subject: [PATCH 079/311] - Work around GCC 4.8 bug 54570 --- src/parsecontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parsecontext.cpp b/src/parsecontext.cpp index 6fa36b2a8..21b7a0ea6 100644 --- a/src/parsecontext.cpp +++ b/src/parsecontext.cpp @@ -157,6 +157,10 @@ loop: { return TokenTrans[NUM]; } +#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 + // Work around GCC 4.8 bug 54570 causing release build crashes. + asm("" : "+g" (yylval)); +#endif strcpy (yylval->sym, token); return TokenTrans[SYM]; } From 4770b9b27b0aebf29117ca1345db0cf0d0ea04fc Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 3 Jan 2014 01:21:21 -0500 Subject: [PATCH 080/311] - Fixed: Rampage timer should only reset when the weapon is ready to be fired. --- src/g_shared/sbar_mugshot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index 0849fd354..aa0f9302a 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -270,7 +270,8 @@ void FMugShot::Tick(player_t *player) RampageTimer++; } } - else + // Only reset the rampage timer if the weapon becomes ready to fire. + else if((player->WeaponState & (WF_WEAPONREADY|WF_WEAPONREADYALT))) { RampageTimer = 0; } From b0f40c07338cea851f03720e7355b4ed71d55705 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 4 Jan 2014 00:37:15 -0500 Subject: [PATCH 081/311] - So we did end up restoring the variable that the last commit was compensating for. --- src/g_shared/sbar_mugshot.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index aa0f9302a..96dd07265 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -263,15 +263,14 @@ void FMugShot::Tick(player_t *player) CurrentState = NULL; } } - if ((player->cmd.ucmd.buttons & (BT_ATTACK|BT_ALTATTACK)) && !(player->cheats & (CF_FROZEN | CF_TOTALLYFROZEN)) && player->ReadyWeapon) + if (player->attackdown && !(player->cheats & (CF_FROZEN | CF_TOTALLYFROZEN)) && player->ReadyWeapon) { if (RampageTimer != ST_RAMPAGEDELAY) { RampageTimer++; } } - // Only reset the rampage timer if the weapon becomes ready to fire. - else if((player->WeaponState & (WF_WEAPONREADY|WF_WEAPONREADYALT))) + else { RampageTimer = 0; } From cd3f5db16a8866d7ed2e97a05ab74e1f631feaf2 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 4 Jan 2014 16:58:21 -0500 Subject: [PATCH 082/311] - Updated gdtoa in order to fix clang warnings. --- gdtoa/README | 84 ++++++- gdtoa/arithchk.c | 2 +- gdtoa/dmisc.c | 2 +- gdtoa/dtoa.c | 210 +++++++++-------- gdtoa/g_Qfmt.c | 17 +- gdtoa/g__fmt.c | 126 +++++++++- gdtoa/g_ddfmt.c | 47 ++-- gdtoa/g_dfmt.c | 26 +- gdtoa/g_ffmt.c | 17 +- gdtoa/g_xLfmt.c | 17 +- gdtoa/g_xfmt.c | 23 +- gdtoa/gdtoa.c | 196 +++++++-------- gdtoa/gdtoa.h | 42 ++-- gdtoa/gdtoa_fltrnds.h | 18 ++ gdtoa/gdtoaimp.h | 81 +++++-- gdtoa/gethex.c | 155 +++++++++--- gdtoa/gmisc.c | 2 +- gdtoa/hd_init.c | 24 +- gdtoa/hexnan.c | 27 ++- gdtoa/misc.c | 136 ++++------- gdtoa/qnan.c | 45 ++-- gdtoa/smisc.c | 26 +- gdtoa/strtoIQ.c | 2 +- gdtoa/strtoId.c | 2 +- gdtoa/strtoIdd.c | 4 +- gdtoa/strtoIf.c | 2 +- gdtoa/strtoIg.c | 20 +- gdtoa/strtoIx.c | 2 +- gdtoa/strtoIxL.c | 2 +- gdtoa/strtod.c | 536 ++++++++++++++++++++++++------------------ gdtoa/strtodI.c | 90 ++++--- gdtoa/strtodg.c | 203 ++++++++++------ gdtoa/strtodnrp.c | 2 +- gdtoa/strtof.c | 11 +- gdtoa/strtopQ.c | 20 +- gdtoa/strtopd.c | 9 +- gdtoa/strtopdd.c | 47 ++-- gdtoa/strtopf.c | 11 +- gdtoa/strtopx.c | 24 +- gdtoa/strtopxL.c | 20 +- gdtoa/strtorQ.c | 15 +- gdtoa/strtord.c | 11 +- gdtoa/strtordd.c | 58 ++--- gdtoa/strtorf.c | 11 +- gdtoa/strtorx.c | 20 +- gdtoa/strtorxL.c | 18 +- gdtoa/ulp.c | 21 +- 47 files changed, 1528 insertions(+), 956 deletions(-) create mode 100644 gdtoa/gdtoa_fltrnds.h diff --git a/gdtoa/README b/gdtoa/README index cf1947aa2..1bf7d91e4 100644 --- a/gdtoa/README +++ b/gdtoa/README @@ -56,7 +56,9 @@ two letters: whose sum is the desired value For decimal -> binary conversions, there are three families of -helper routines: one for round-nearest: +helper routines: one for round-nearest (or the current rounding +mode on IEEE-arithmetic systems that provide the C99 fegetround() +function, if compiled with -DHonor_FLT_ROUNDS): strtof strtod @@ -150,12 +152,14 @@ suffer double rounding due to use of extended-precision registers. For some conversions this variant of strtod is less efficient than the one in strtod.c when the latter is run with 53-bit rounding precision. -The values that the strto* routines return for NaNs are determined by -gd_qnan.h, which the makefile generates by running the program whose -source is qnan.c. Note that the rules for distinguishing signaling -from quiet NaNs are system-dependent. For cross-compilation, you need -to determine arith.h and gd_qnan.h suitably, e.g., using the -arithmetic of the target machine. +When float or double are involved, the values that the strto* routines +return for NaNs are determined by gd_qnan.h, which the makefile +generates by running the program whose source is qnan.c. For other +types, default NaN values are specified in g__fmt.c and may need +adjusting. Note that the rules for distinguishing signaling from +quiet NaNs are system-dependent. For cross-compilation, you need to +determine arith.h and gd_qnan.h suitably, e.g., using the arithmetic +of the target machine. C99's hexadecimal floating-point constants are recognized by the strto* routines (but this feature has not yet been heavily tested). @@ -170,10 +174,11 @@ hexadecimal digits, it is taken for the fraction bits of the resulting NaN; if there are two or more strings of hexadecimal digits, each string is assigned to the next available sequence of 32-bit words of fractions bits (starting with the most significant), right-aligned in -each sequence. +each sequence. Strings of hexadecimal digits may be preceded by "0x" +or "0X". -For binary -> decimal conversions, I've provided just one family -of helper routines: +For binary -> decimal conversions, I've provided a family of helper +routines: g_ffmt g_dfmt @@ -181,6 +186,12 @@ of helper routines: g_xfmt g_xLfmt g_Qfmt + g_ffmt_p + g_dfmt_p + g_ddfmt_p + g_xfmt_p + g_xLfmt_p + g_Qfmt_p which do a "%g" style conversion either to a specified number of decimal places (if their ndig argument is positive), or to the shortest @@ -191,6 +202,36 @@ in the buffer, if the buffer was long enough, or 0. Other forms of conversion are easily done with the help of gdtoa(), such as %e or %f style and conversions with direction of rounding specified (so that, if desired, the decimal value is either >= or <= the binary value). +On IEEE-arithmetic systems that provide the C99 fegetround() function, +if compiled with -DHonor_FLT_ROUNDS, these routines honor the current +rounding mode. For pedants, the ...fmt_p() routines are similar to the +...fmt() routines, but have an additional final int argument, nik, +that for conversions of Infinity or NaN, determines whether upper, +lower, or mixed case is used, whether (...) is added to NaN values, +and whether the sign of a NaN is reported or suppressed: + + nik = ic + 6*(nb + 3*ns), + +where ic with 0 <= ic < 6 controls the rendering of Infinity and NaN: + + 0 ==> Infinity or NaN + 1 ==> infinity or nan + 2 ==> INFINITY or NAN + 3 ==> Inf or NaN + 4 ==> inf or nan + 5 ==> INF or NAN + +nb with 0 <= nb < 3 determines whether NaN values are rendered +as NaN(...): + + 0 ==> no + 1 ==> yes + 2 ==> no for default NaN values; yes otherwise + +ns = 0 or 1 determines whether the sign of NaN values reported: + + 0 ==> distinguish NaN and -NaN + 1 ==> report both as NaN For an example of more general conversions based on dtoa(), see netlib's "printf.c from ampl/solvers". @@ -332,5 +373,28 @@ Compiling g__fmt.c, strtod.c, and strtodg.c with -DUSE_LOCALE causes the decimal-point character to be taken from the current locale; otherwise it is '.'. +Source files dtoa.c and strtod.c in this directory are derived from +netlib's "dtoa.c from fp" and are meant to function equivalently. +When compiled with Honor_FLT_ROUNDS #defined (on systems that provide +FLT_ROUNDS and fegetround() as specified in the C99 standard), they +honor the current rounding mode. Because FLT_ROUNDS is buggy on some +(Linux) systems -- not reflecting calls on fesetround(), as the C99 +standard says it should -- when Honor_FLT_ROUNDS is #defined, the +current rounding mode is obtained from fegetround() rather than from +FLT_ROUNDS, unless Trust_FLT_ROUNDS is also #defined. + +Compile with -DUSE_LOCALE to use the current locale; otherwise +decimal points are assumed to be '.'. With -DUSE_LOCALE, unless +you also compile with -DNO_LOCALE_CACHE, the details about the +current "decimal point" character string are cached and assumed not +to change during the program's execution. + +On machines with a 64-bit long double and perhaps a 113-bit "quad" +type, you can invoke "make Printf" to add Printf (and variants, such +as Fprintf) to gdtoa.a. These are analogs, declared in stdio1.h, of +printf and fprintf, etc. in which %La, %Le, %Lf, and %Lg are for long +double and (if appropriate) %Lqa, %Lqe, %Lqf, and %Lqg are for quad +precision printing. + Please send comments to David M. Gay (dmg at acm dot org, with " at " changed at "@" and " dot " changed to "."). diff --git a/gdtoa/arithchk.c b/gdtoa/arithchk.c index 3211aeda4..ef6cda3db 100644 --- a/gdtoa/arithchk.c +++ b/gdtoa/arithchk.c @@ -106,7 +106,7 @@ ccheck() long Cray1; /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */ - Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762; + Cray1 = printf("%s", emptyfmt) < 0 ? 0 : 4617762; if (printf(emptyfmt, Cray1) >= 0) Cray1 = 1000000*Cray1 + 693716; if (printf(emptyfmt, Cray1) >= 0) diff --git a/gdtoa/dmisc.c b/gdtoa/dmisc.c index 72d271ca9..3e712511b 100644 --- a/gdtoa/dmisc.c +++ b/gdtoa/dmisc.c @@ -46,7 +46,7 @@ rv_alloc(int i) j = sizeof(ULong); for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (size_t)i; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (size_t)(i); j <<= 1) k++; r = (int*)Balloc(k); diff --git a/gdtoa/dtoa.c b/gdtoa/dtoa.c index 4fc6633b7..c96e6a545 100644 --- a/gdtoa/dtoa.c +++ b/gdtoa/dtoa.c @@ -30,7 +30,6 @@ THIS SOFTWARE. * with " at " changed at "@" and " dot " changed to "."). */ #include "gdtoaimp.h" -#include /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * @@ -67,7 +66,6 @@ THIS SOFTWARE. */ #ifdef Honor_FLT_ROUNDS -#define Rounding rounding #undef Check_FLT_ROUNDS #define Check_FLT_ROUNDS #else @@ -77,17 +75,17 @@ THIS SOFTWARE. char * dtoa #ifdef KR_headers - (d, mode, ndigits, decpt, sign, rve) - double d; int mode, ndigits, *decpt, *sign; char **rve; + (d0, mode, ndigits, decpt, sign, rve) + double d0; int mode, ndigits, *decpt, *sign; char **rve; #else - (double _d, int mode, int ndigits, int *decpt, int *sign, char **rve) + (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to INT_MAX. + then *decpt is set to 9999. mode: 0 ==> shortest string that yields d when read in @@ -129,12 +127,22 @@ dtoa U d, d2, eps; double ds; char *s, *s0; -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif #ifdef SET_INEXACT int inexact, oldinexact; #endif +#ifdef Honor_FLT_ROUNDS /*{*/ + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ #ifndef MULTIPLE_THREADS if (dtoa_result) { @@ -142,36 +150,35 @@ dtoa dtoa_result = 0; } #endif - - dval(d) = _d; - if (word0(d) & Sign_bit) { + d.d = d0; + if (word0(&d) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ + word0(&d) &= ~Sign_bit; /* clear sign bit */ } else *sign = 0; #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) + if ((word0(&d) & Exp_mask) == Exp_mask) #else - if (word0(d) == 0x8000) + if (word0(&d) == 0x8000) #endif { /* Infinity or NaN */ - *decpt = INT_MAX; + *decpt = 9999; #ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) + if (!word1(&d) && !(word0(&d) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); #endif return nrv_alloc("NaN", rve, 3); } #endif #ifdef IBM - dval(d) += 0; /* normalize */ + dval(&d) += 0; /* normalize */ #endif - if (!dval(d)) { + if (!dval(&d)) { *decpt = 1; return nrv_alloc("0", rve, 1); } @@ -181,35 +188,35 @@ dtoa inexact = 1; #endif #ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { + if (Rounding >= 2) { if (*sign) - rounding = rounding == 2 ? 0 : 2; + Rounding = Rounding == 2 ? 0 : 2; else - if (rounding != 2) - rounding = 0; + if (Rounding != 2) + Rounding = 0; } #endif - b = d2b(dval(d), &be, &bbits); + b = d2b(dval(&d), &be, &bbits); #ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { + if (( i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { #endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; + dval(&d2) = dval(&d); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; #ifdef IBM - if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0) - dval(d2) /= 1 << j; + if (( j = 11 - hi0bits(word0(&d2) & Frac_mask) )!=0) + dval(&d2) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -238,21 +245,21 @@ dtoa /* d is denormalized */ i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 - : word1(d) << 32 - i; - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + x = i > 32 ? word0(&d) << (64 - i) | word1(&d) >> (i - 32) + : word1(&d) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } #endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) k--; /* want k = floor(ds) */ k_check = 1; if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -291,10 +298,11 @@ dtoa try_quick = 0; } leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: - ilim = ilim1 = -1; i = 18; ndigits = 0; break; @@ -319,7 +327,7 @@ dtoa s = s0 = rv_alloc(i); #ifdef Honor_FLT_ROUNDS - if (mode > 1 && rounding != 1) + if (mode > 1 && Rounding != 1) leftright = 0; #endif @@ -328,7 +336,7 @@ dtoa /* Try to get by with floating-point arithmetic. */ i = 0; - dval(d2) = dval(d); + dval(&d2) = dval(&d); k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ @@ -338,7 +346,7 @@ dtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -346,32 +354,32 @@ dtoa ieps++; ds *= bigtens[i]; } - dval(d) /= ds; + dval(&d) /= ds; } else if (( j1 = -k )!=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; + dval(&eps) = ieps*dval(&d) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -380,34 +388,34 @@ dtoa /* Use Steele & White method of only * generating digits needed. */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = (Long)dval(d); - dval(d) -= L; + L = (Long)dval(&d); + dval(&d) -= L; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) + if (dval(&d) < dval(&eps)) goto ret1; - if (1. - dval(d) < dval(eps)) + if (1. - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 10.; + dval(&eps) *= 10.; + dval(&d) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&d) *= 10.) { + L = (Long)(dval(&d)); + if (!(dval(&d) -= L)) ilim = i; *s++ = '0' + (int)L; if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) + if (dval(&d) > 0.5 + dval(&eps)) goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { + else if (dval(&d) < 0.5 - dval(&eps)) { while(*--s == '0'); s++; goto ret1; @@ -420,7 +428,7 @@ dtoa #endif fast_failed: s = s0; - dval(d) = dval(d2); + dval(&d) = dval(&d2); k = k0; ilim = ilim0; } @@ -432,22 +440,22 @@ dtoa ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; + for(i = 1;; i++, dval(&d) *= 10.) { + L = (Long)(dval(&d) / ds); + dval(&d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (!dval(d)) { + if (!dval(&d)) { #ifdef SET_INEXACT inexact = 0; #endif @@ -456,13 +464,18 @@ dtoa if (i == ilim) { #ifdef Honor_FLT_ROUNDS if (mode > 1) - switch(rounding) { + switch(Rounding) { case 0: goto ret1; case 2: goto bump_up; } #endif - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); +#ifdef ROUND_BIASED + if (dval(&d) >= ds) +#else + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) +#endif + { bump_up: while(*--s == '9') if (s == s0) { @@ -524,12 +537,12 @@ dtoa spec_case = 0; if ((mode < 2 || leftright) #ifdef Honor_FLT_ROUNDS - && rounding == 1 + && Rounding == 1 #endif ) { - if (!word1(d) && !(word0(d) & Bndry_mask) + if (!word1(&d) && !(word0(&d) & Bndry_mask) #ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) + && word0(&d) & (Exp_mask & ~Exp_msk1) #endif ) { /* The special case */ @@ -615,9 +628,9 @@ dtoa j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) + if (j1 == 0 && mode != 1 && !(word1(&d) & 1) #ifdef Honor_FLT_ROUNDS - && rounding >= 1 + && Rounding >= 1 #endif ) { if (dig == '9') @@ -632,11 +645,11 @@ dtoa goto ret; } #endif - if (j < 0 || j == 0 && mode != 1 + if (j < 0 || (j == 0 && mode != 1 #ifndef ROUND_BIASED - && !(word1(d) & 1) + && !(word1(&d) & 1) #endif - ) { + )) { if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT inexact = 0; @@ -645,7 +658,7 @@ dtoa } #ifdef Honor_FLT_ROUNDS if (mode > 1) - switch(rounding) { + switch(Rounding) { case 0: goto accept_dig; case 2: goto keep_dig; } @@ -653,7 +666,11 @@ dtoa if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif && dig++ == '9') goto round_9_up; } @@ -663,7 +680,7 @@ dtoa } if (j1 > 0) { #ifdef Honor_FLT_ROUNDS - if (!rounding) + if (!Rounding) goto accept_dig; #endif if (dig == '9') { /* possible if i == 1 */ @@ -706,14 +723,19 @@ dtoa /* Round off last digit */ #ifdef Honor_FLT_ROUNDS - switch(rounding) { + switch(Rounding) { case 0: goto trimzeros; case 2: goto roundoff; } #endif b = lshift(b, 1); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { roundoff: while(*--s == '9') if (s == s0) { @@ -724,7 +746,9 @@ dtoa ++*s++; } else { +#ifdef Honor_FLT_ROUNDS trimzeros: +#endif while(*--s == '0'); s++; } @@ -739,9 +763,9 @@ dtoa #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; + word0(&d) = Exp_1 + (70 << Exp_shift); + word1(&d) = 0; + dval(&d) += 1.; } } else if (!oldinexact) diff --git a/gdtoa/g_Qfmt.c b/gdtoa/g_Qfmt.c index 9d227d170..0f0697005 100644 --- a/gdtoa/g_Qfmt.c +++ b/gdtoa/g_Qfmt.c @@ -51,19 +51,24 @@ THIS SOFTWARE. char* #ifdef KR_headers -g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize; #else -g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize) +g_Qfmt(char *buf, void *V, int ndig, size_t bufsize) #endif { - static CONST FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 }; + static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0, Int_max }; char *b, *s, *se; ULong bits[4], *L, sign; int decpt, ex, i, mode; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif if (ndig < 0) ndig = 0; - if (bufsize < (unsigned)(ndig + 10)) + if (bufsize < (size_t)(ndig + 10)) return 0; L = (ULong*)V; @@ -109,6 +114,6 @@ g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize) return 0; mode = 0; } - s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - return g__fmt(buf, s, se, decpt, sign); + s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign, bufsize); } diff --git a/gdtoa/g__fmt.c b/gdtoa/g__fmt.c index 021ecfb57..652c82b68 100644 --- a/gdtoa/g__fmt.c +++ b/gdtoa/g__fmt.c @@ -35,26 +35,77 @@ THIS SOFTWARE. #include "locale.h" #endif +#ifndef ldus_QNAN0 +#define ldus_QNAN0 0x7fff +#endif +#ifndef ldus_QNAN1 +#define ldus_QNAN1 0xc000 +#endif +#ifndef ldus_QNAN2 +#define ldus_QNAN2 0 +#endif +#ifndef ldus_QNAN3 +#define ldus_QNAN3 0 +#endif +#ifndef ldus_QNAN4 +#define ldus_QNAN4 0 +#endif + + const char *InfName[6] = { "Infinity", "infinity", "INFINITY", "Inf", "inf", "INF" }; + const char *NanName[3] = { "NaN", "nan", "NAN" }; + ULong NanDflt_Q_D2A[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff }; + ULong NanDflt_d_D2A[2] = { d_QNAN1, d_QNAN0 }; + ULong NanDflt_f_D2A[1] = { f_QNAN }; + ULong NanDflt_xL_D2A[3] = { 1, 0x80000000, 0x7fff0000 }; + UShort NanDflt_ldus_D2A[5] = { ldus_QNAN4, ldus_QNAN3, ldus_QNAN2, ldus_QNAN1, ldus_QNAN0 }; + char * #ifdef KR_headers -g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign; +g__fmt(b, s, se, decpt, sign, blen) char *b; char *s; char *se; int decpt; ULong sign; size_t blen; #else -g__fmt(char *b, char *s, char *se, int decpt, ULong sign) +g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen) #endif { int i, j, k; - char *s0 = s; + char *be, *s0; + size_t len; #ifdef USE_LOCALE - char decimalpoint = *localeconv()->decimal_point; +#ifdef NO_LOCALE_CACHE + char *decimalpoint = localeconv()->decimal_point; + size_t dlen = strlen(decimalpoint); #else -#define decimalpoint '.' + char *decimalpoint; + static char *decimalpoint_cache; + static size_t dlen; + if (!(s0 = decimalpoint_cache)) { + s0 = localeconv()->decimal_point; + dlen = strlen(s0); + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; #endif +#else +#define dlen 0 +#endif + s0 = s; + len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */ + if (blen < len) + goto ret0; + be = b + blen - 1; if (sign) *b++ = '-'; if (decpt <= -4 || decpt > se - s + 5) { *b++ = *s++; if (*s) { - *b++ = decimalpoint; +#ifdef USE_LOCALE + while((*b = *decimalpoint++)) + ++b; +#else + *b++ = '.'; +#endif while((*b = *s++) !=0) b++; } @@ -69,6 +120,8 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign) for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} for(;;) { i = decpt / k; + if (b >= be) + goto ret0; *b++ = i + '0'; if (--j <= 0) break; @@ -78,22 +131,73 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign) *b = 0; } else if (decpt <= 0) { - *b++ = decimalpoint; +#ifdef USE_LOCALE + while((*b = *decimalpoint++)) + ++b; +#else + *b++ = '.'; +#endif + if (be < b - decpt + (se - s)) + goto ret0; for(; decpt < 0; decpt++) *b++ = '0'; - while((*b = *s++) !=0) + while((*b = *s++) != 0) b++; } else { - while((*b = *s++) !=0) { + while((*b = *s++) != 0) { b++; - if (--decpt == 0 && *s) - *b++ = decimalpoint; + if (--decpt == 0 && *s) { +#ifdef USE_LOCALE + while(*b = *decimalpoint++) + ++b; +#else + *b++ = '.'; +#endif + } + } + if (b + decpt > be) { + ret0: + b = 0; + goto ret; } for(; decpt > 0; decpt--) *b++ = '0'; *b = 0; } + ret: freedtoa(s0); return b; } + + char * +add_nanbits_D2A(char *b, size_t blen, ULong *bits, int nb) +{ + ULong t; + char *rv; + int i, j; + size_t L; + static char Hexdig[16] = "0123456789abcdef"; + + while(!bits[--nb]) + if (!nb) + return b; + L = 8*nb + 3; + t = bits[nb]; + do ++L; while((t >>= 4)); + if (L > blen) + return b; + b += L; + *--b = 0; + rv = b; + *--b = /*(*/ ')'; + for(i = 0; i < nb; ++i) { + t = bits[i]; + for(j = 0; j < 8; ++j, t >>= 4) + *--b = Hexdig[t & 0xf]; + } + t = bits[nb]; + do *--b = Hexdig[t & 0xf]; while(t >>= 4); + *--b = '('; /*)*/ + return rv; + } diff --git a/gdtoa/g_ddfmt.c b/gdtoa/g_ddfmt.c index d96e78dbe..5ce4a076b 100644 --- a/gdtoa/g_ddfmt.c +++ b/gdtoa/g_ddfmt.c @@ -33,9 +33,9 @@ THIS SOFTWARE. char * #ifdef KR_headers -g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize; +g_ddfmt(buf, dd0, ndig, bufsize) char *buf; double *dd0; int ndig; size_t bufsize; #else -g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) +g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize) #endif { FPI fpi; @@ -43,12 +43,28 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) ULong *L, bits0[4], *bits, *zx; int bx, by, decpt, ex, ey, i, j, mode; Bigint *x, *y, *z; - double ddx[2]; + U *dd, ddx[2]; +#ifdef Honor_FLT_ROUNDS /*{{*/ + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ +#else /*}{*/ +#define Rounding FPI_Round_near +#endif /*}}*/ - if (bufsize < 10 || bufsize < (unsigned)(ndig + 8)) + if (bufsize < 10 || bufsize < (size_t)(ndig + 8)) return 0; - L = (ULong*)dd; + dd = (U*)dd0; + L = dd->L; if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { /* Infinity or NaN */ if (L[_0] & 0xfffff || L[_1]) { @@ -73,7 +89,7 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) goto nanret; goto infret; } - if (dd[0] + dd[1] == 0.) { + if (dval(&dd[0]) + dval(&dd[1]) == 0.) { b = buf; #ifndef IGNORE_ZERO_SIGN if (L[_0] & L[2+_0] & 0x80000000L) @@ -84,16 +100,16 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) return b; } if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { - ddx[1] = dd[0]; - ddx[0] = dd[1]; + dval(&ddx[1]) = dval(&dd[0]); + dval(&ddx[0]) = dval(&dd[1]); dd = ddx; - L = (ULong*)dd; + L = dd->L; } - z = d2b(dd[0], &ex, &bx); - if (dd[1] == 0.) + z = d2b(dval(&dd[0]), &ex, &bx); + if (dval(&dd[1]) == 0.) goto no_y; x = z; - y = d2b(dd[1], &ey, &by); + y = d2b(dval(&dd[1]), &ey, &by); if ( (i = ex - ey) !=0) { if (i > 0) { x = lshift(x, i); @@ -136,7 +152,7 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) } mode = 2; if (ndig <= 0) { - if (bufsize < (unsigned)((int)(fpi.nbits * .301029995664) + 10)) { + if (bufsize < (size_t)((int)(fpi.nbits * .301029995664) + 10)) { Bfree(z); return 0; } @@ -144,11 +160,12 @@ g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) } fpi.emin = 1-1023-53+1; fpi.emax = 2046-1023-106+1; - fpi.rounding = FPI_Round_near; + fpi.rounding = Rounding; fpi.sudden_underflow = 0; + fpi.int_max = Int_max; i = STRTOG_Normal; s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - b = g__fmt(buf, s, se, decpt, z->sign); + b = g__fmt(buf, s, se, decpt, z->sign, bufsize); Bfree(z); return b; } diff --git a/gdtoa/g_dfmt.c b/gdtoa/g_dfmt.c index 74b4ccc28..d8e1438c4 100644 --- a/gdtoa/g_dfmt.c +++ b/gdtoa/g_dfmt.c @@ -33,25 +33,32 @@ THIS SOFTWARE. char* #ifdef KR_headers -g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize; +g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; size_t bufsize; #else -g_dfmt(char *buf, double *d, int ndig, unsigned bufsize) +g_dfmt(char *buf, double *d, int ndig, size_t bufsize) #endif { - static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 }; + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0, Int_max }; char *b, *s, *se; ULong bits[2], *L, sign; int decpt, ex, i, mode; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif if (ndig < 0) ndig = 0; - if (bufsize < (unsigned)(ndig + 10)) + if (bufsize < (size_t)(ndig + 10)) return 0; L = (ULong*)d; sign = L[_0] & 0x80000000L; if ((L[_0] & 0x7ff00000) == 0x7ff00000) { /* Infinity or NaN */ + if (bufsize < 10) + return 0; if (L[_0] & 0xfffff || L[_1]) { return strcp(buf, "NaN"); } @@ -78,12 +85,11 @@ g_dfmt(char *buf, double *d, int ndig, unsigned bufsize) ex = 1; ex -= 0x3ff + 52; mode = 2; - if (ndig <= 0) { - if (bufsize < 25) - return 0; + if (ndig <= 0) mode = 0; - } i = STRTOG_Normal; - s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - return g__fmt(buf, s, se, decpt, sign); + if (sign) + i = STRTOG_Normal | STRTOG_Neg; + s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign, bufsize); } diff --git a/gdtoa/g_ffmt.c b/gdtoa/g_ffmt.c index 9b2c5fea6..30b53ae7e 100644 --- a/gdtoa/g_ffmt.c +++ b/gdtoa/g_ffmt.c @@ -33,19 +33,24 @@ THIS SOFTWARE. char* #ifdef KR_headers -g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize; +g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; size_t bufsize; #else -g_ffmt(char *buf, float *f, int ndig, unsigned bufsize) +g_ffmt(char *buf, float *f, int ndig, size_t bufsize) #endif { - static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, 0, 6 }; char *b, *s, *se; ULong bits[1], *L, sign; int decpt, ex, i, mode; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif if (ndig < 0) ndig = 0; - if (bufsize < (unsigned)(ndig + 10)) + if (bufsize < (size_t)(ndig + 10)) return 0; L = (ULong*)f; @@ -83,6 +88,6 @@ g_ffmt(char *buf, float *f, int ndig, unsigned bufsize) mode = 0; } i = STRTOG_Normal; - s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - return g__fmt(buf, s, se, decpt, sign); + s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign, bufsize); } diff --git a/gdtoa/g_xLfmt.c b/gdtoa/g_xLfmt.c index a2a993b59..5cda8d59e 100644 --- a/gdtoa/g_xLfmt.c +++ b/gdtoa/g_xLfmt.c @@ -49,19 +49,24 @@ THIS SOFTWARE. char* #ifdef KR_headers -g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize; #else -g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize) +g_xLfmt(char *buf, void *V, int ndig, size_t bufsize) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max }; char *b, *s, *se; ULong bits[2], *L, sign; int decpt, ex, i, mode; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif if (ndig < 0) ndig = 0; - if (bufsize < (unsigned)(ndig + 10)) + if (bufsize < (size_t)(ndig + 10)) return 0; L = (ULong*)V; @@ -103,6 +108,6 @@ g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize) return 0; mode = 0; } - s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - return g__fmt(buf, s, se, decpt, sign); + s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign, bufsize); } diff --git a/gdtoa/g_xfmt.c b/gdtoa/g_xfmt.c index c51a16dce..a0baa518c 100644 --- a/gdtoa/g_xfmt.c +++ b/gdtoa/g_xfmt.c @@ -53,20 +53,25 @@ THIS SOFTWARE. char* #ifdef KR_headers -g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize; #else -g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) +g_xfmt(char *buf, void *V, int ndig, size_t bufsize) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max }; char *b, *s, *se; ULong bits[2], sign; UShort *L; int decpt, ex, i, mode; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif if (ndig < 0) ndig = 0; - if (bufsize < (unsigned)(ndig + 10)) + if (bufsize < (size_t)(ndig + 10)) return 0; L = (UShort *)V; @@ -76,14 +81,14 @@ g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) if ( (ex = L[_0] & 0x7fff) !=0) { if (ex == 0x7fff) { /* Infinity or NaN */ - if (bits[0] | bits[1]) - b = strcp(buf, "NaN"); - else { + if (!bits[0] && bits[1]== 0x80000000) { b = buf; if (sign) *b++ = '-'; b = strcp(b, "Infinity"); } + else + b = strcp(buf, "NaN"); return b; } i = STRTOG_Normal; @@ -109,6 +114,6 @@ g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) return 0; mode = 0; } - s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); - return g__fmt(buf, s, se, decpt, sign); + s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign, bufsize); } diff --git a/gdtoa/gdtoa.c b/gdtoa/gdtoa.c index 7e8d2b2bf..a4759968a 100644 --- a/gdtoa/gdtoa.c +++ b/gdtoa/gdtoa.c @@ -30,7 +30,6 @@ THIS SOFTWARE. * with " at " changed at "@" and " dot " changed to "."). */ #include "gdtoaimp.h" -#include static Bigint * #ifdef KR_headers @@ -62,7 +61,7 @@ bitstob(ULong *bits, int nbits, int *bbits) *x++ = (*bits >> 16) & ALL_ON; #endif } while(++bits <= be); - i = (int)(x - x0); + i = x - x0; while(!x0[--i]) if (!i) { b->wds = 0; @@ -116,14 +115,15 @@ gdtoa FPI *fpi; int be; ULong *bits; int *kindp, mode, ndigits, *decpt; char **rve; #else - (CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) + (FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) #endif { /* Arguments ndigits and decpt are similar to the second and third arguments of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to INT_MAX. + then *decpt is set to 9999. + be = exponent: value = (integer represented by bits) * (2 to the power of be). mode: 0 ==> shortest string that yields d when read in @@ -159,8 +159,8 @@ gdtoa Long L; Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; double d2, ds; - U d, eps; char *s, *s0; + U d, eps; #ifndef MULTIPLE_THREADS if (dtoa_result) { @@ -177,10 +177,10 @@ gdtoa case STRTOG_Denormal: break; case STRTOG_Infinite: - *decpt = INT_MAX; + *decpt = -32768; return nrv_alloc("Infinity", rve, 8); case STRTOG_NaN: - *decpt = INT_MAX; + *decpt = -32768; return nrv_alloc("NaN", rve, 3); default: return 0; @@ -199,21 +199,21 @@ gdtoa return nrv_alloc("0", rve, 1); } - dval(d) = b2d(b, &i); + dval(&d) = b2d(b, &i); i = be + bbits - 1; - word0(d) &= Frac_mask1; - word0(d) |= Exp_11; + word0(&d) &= Frac_mask1; + word0(&d) |= Exp_11; #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2) * - * This suggests computing an approximation k to log10(d) by + * This suggests computing an approximation k to log10(&d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); @@ -233,7 +233,7 @@ gdtoa i <<= 2; i += j; #endif - ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; /* correct assumption about exponent range */ if ((j = i) < 0) @@ -248,13 +248,13 @@ gdtoa #ifdef IBM j = be + bbits - 1; if ( (j1 = j & 3) !=0) - dval(d) *= 1 << j1; - word0(d) += j << Exp_shift - 2 & Exp_mask; + dval(&d) *= 1 << j1; + word0(&d) += j << Exp_shift - 2 & Exp_mask; #else - word0(d) += (be + bbits - 1) << Exp_shift; + word0(&d) += (be + bbits - 1) << Exp_shift; #endif if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) + if (dval(&d) < tens[k]) k--; k_check = 0; } @@ -284,11 +284,14 @@ gdtoa mode -= 4; try_quick = 0; } + else if (i >= -4 - Emin || i < Emin) + try_quick = 0; leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ switch(mode) { case 0: case 1: - ilim = ilim1 = -1; i = (int)(nbits * .30103) + 3; ndigits = 0; break; @@ -330,10 +333,10 @@ gdtoa /* Try to get by with floating-point arithmetic. */ i = 0; - d2 = dval(d); + d2 = dval(&d); #ifdef IBM - if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) - dval(d) /= 1 << j; + if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) + dval(&d) /= 1 << j; #endif k0 = k; ilim0 = ilim; @@ -344,7 +347,7 @@ gdtoa if (j & Bletch) { /* prevent overflows */ j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; + dval(&d) /= bigtens[n_bigtens-1]; ieps++; } for(; j; j >>= 1, i++) @@ -356,30 +359,30 @@ gdtoa else { ds = 1.; if ( (j1 = -k) !=0) { - dval(d) *= tens[j1 & 0xf]; + dval(&d) *= tens[j1 & 0xf]; for(j = j1 >> 4; j; j >>= 1, i++) if (j & 1) { ieps++; - dval(d) *= bigtens[i]; + dval(&d) *= bigtens[i]; } } } - if (k_check && dval(d) < 1. && ilim > 0) { + if (k_check && dval(&d) < 1. && ilim > 0) { if (ilim1 <= 0) goto fast_failed; ilim = ilim1; k--; - dval(d) *= 10.; + dval(&d) *= 10.; ieps++; } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; + dval(&eps) = ieps*dval(&d) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; if (ilim == 0) { S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) + dval(&d) -= 5.; + if (dval(&d) > dval(&eps)) goto one_digit; - if (dval(d) < -dval(eps)) + if (dval(&d) < -dval(&eps)) goto no_digits; goto fast_failed; } @@ -388,42 +391,40 @@ gdtoa /* Use Steele & White method of only * generating digits needed. */ - dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = (Long)(dval(d)/ds); - dval(d) -= L*ds; + L = (Long)(dval(&d)/ds); + dval(&d) -= L*ds; *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) { - if (dval(d)) + if (dval(&d) < dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; goto ret1; } - if (ds - dval(d) < dval(eps)) + if (ds - dval(&d) < dval(&eps)) goto bump_up; if (++i >= ilim) break; - dval(eps) *= 10.; - dval(d) *= 10.; + dval(&eps) *= 10.; + dval(&d) *= 10.; } } else { #endif /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - if ( (L = (Long)(dval(d)/ds)) !=0) - dval(d) -= L*ds; + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&d) *= 10.) { + if ( (L = (Long)(dval(&d)/ds)) !=0) + dval(&d) -= L*ds; *s++ = '0' + (int)L; if (i == ilim) { ds *= 0.5; - if (dval(d) > ds + dval(eps)) + if (dval(&d) > ds + dval(&eps)) goto bump_up; - else if (dval(d) < ds - dval(eps)) { - while(*--s == '0'){} - s++; - if (dval(d)) + else if (dval(&d) < ds - dval(&eps)) { + if (dval(&d)) inex = STRTOG_Inexlo; - goto ret1; + goto clear_trailing0; } break; } @@ -433,34 +434,34 @@ gdtoa #endif fast_failed: s = s0; - dval(d) = d2; + dval(&d) = d2; k = k0; ilim = ilim0; } /* Do we have a "small" integer? */ - if (be >= 0 && k <= Int_max) { + if (be >= 0 && k <= fpi->int_max) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) + if (ilim < 0 || dval(&d) <= 5*ds) goto no_digits; goto one_digit; } - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; + for(i = 1;; i++, dval(&d) *= 10.) { + L = (Long)(dval(&d) / ds); + dval(&d) -= L*ds; #ifdef Check_FLT_ROUNDS /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { + if (dval(&d) < 0) { L--; - dval(d) += ds; + dval(&d) += ds; } #endif *s++ = '0' + (int)L; - if (dval(d) == 0.) + if (dval(&d) == 0.) break; if (i == ilim) { if (rdir) { @@ -469,8 +470,13 @@ gdtoa inex = STRTOG_Inexlo; goto ret1; } - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { + dval(&d) += dval(&d); +#ifdef ROUND_BIASED + if (dval(&d) >= ds) +#else + if (dval(&d) > ds || (dval(&d) == ds && L & 1)) +#endif + { bump_up: inex = STRTOG_Inexhi; while(*--s == '9') @@ -481,8 +487,12 @@ gdtoa } ++*s++; } - else + else { inex = STRTOG_Inexlo; + clear_trailing0: + while(*--s == '0'){} + ++s; + } break; } } @@ -493,13 +503,15 @@ gdtoa m5 = b5; mhi = mlo = 0; if (leftright) { - if (mode < 2) { - i = nbits - bbits; - if (be - i++ < fpi->emin) - /* denormal */ - i = be - fpi->emin + 1; + i = nbits - bbits; + if (be - i++ < fpi->emin && mode != 3 && mode != 5) { + /* denormal */ + i = be - fpi->emin + 1; + if (mode >= 2 && ilim > 0 && ilim < i) + goto small_ilim; } - else { + else if (mode >= 2) { + small_ilim: j = ilim - 1; if (m5 >= j) m5 -= j; @@ -560,28 +572,11 @@ gdtoa * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ -#ifdef Pack_32 - if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0) - i = 32 - i; -#else - if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) + i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask; + m2 += i; + if ((b2 += i) > 0) b = lshift(b, b2); - if (s2 > 0) + if ((s2 += i) > 0) S = lshift(S, s2); if (k_check) { if (cmp(b,S) < 0) { @@ -646,11 +641,11 @@ gdtoa goto ret; } #endif - if (j < 0 || j == 0 && !mode + if (j < 0 || (j == 0 && !mode #ifndef ROUND_BIASED && !(bits[0] & 1) #endif - ) { + )) { if (rdir && (b->wds > 1 || b->x[0])) { if (rdir == 2) { inex = STRTOG_Inexlo; @@ -673,7 +668,11 @@ gdtoa if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif && dig++ == '9') goto round_9_up; inex = STRTOG_Inexhi; @@ -718,13 +717,18 @@ gdtoa /* Round off last digit */ if (rdir) { - if (rdir == 2 || b->wds <= 1 && !b->x[0]) + if (rdir == 2 || (b->wds <= 1 && !b->x[0])) goto chopzeros; goto roundoff; } b = lshift(b, 1); j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { roundoff: inex = STRTOG_Inexhi; while(*--s == '9') @@ -740,7 +744,7 @@ gdtoa if (b->wds > 1 || b->x[0]) inex = STRTOG_Inexlo; while(*--s == '0'){} - s++; + ++s; } ret: Bfree(S); diff --git a/gdtoa/gdtoa.h b/gdtoa/gdtoa.h index 2707ff7df..49c637beb 100644 --- a/gdtoa/gdtoa.h +++ b/gdtoa/gdtoa.h @@ -66,16 +66,13 @@ THIS SOFTWARE. #else #include "arith.h" #endif +#include /* for size_t */ -/* [RH] On 64-bit Unix systems, long is a 64-bit type. I do not that is - * is what is desired here, so I sacrifice compatibility with systems - * that use 16-bit ints (oh no!) and make Long an int instead. - */ #ifndef Long -typedef int Long; +#define Long int #endif #ifndef ULong -typedef unsigned int ULong; +typedef unsigned Long ULong; #endif #ifndef UShort typedef unsigned short UShort; @@ -111,9 +108,9 @@ typedef unsigned short UShort; /* The following may be or-ed into one of the above values. */ - STRTOG_Neg = 0x08, - STRTOG_Inexlo = 0x10, - STRTOG_Inexhi = 0x20, + STRTOG_Neg = 0x08, /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */ + STRTOG_Inexlo = 0x10, /* returned result rounded toward zero */ + STRTOG_Inexhi = 0x20, /* returned result rounded away from zero */ STRTOG_Inexact = 0x30, STRTOG_Underflow= 0x40, STRTOG_Overflow = 0x80 @@ -126,6 +123,7 @@ FPI { int emax; int rounding; int sudden_underflow; + int int_max; } FPI; enum { /* FPI.rounding values: same as FLT_ROUNDS */ @@ -135,29 +133,31 @@ enum { /* FPI.rounding values: same as FLT_ROUNDS */ FPI_Round_down = 3 }; -// Our strtod is not the CRT's strtod. -#include -#define strtod mystrtod - #ifdef __cplusplus extern "C" { #endif extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); -extern char* gdtoa ANSI((CONST FPI *fpi, int be, ULong *bits, int *kindp, +extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)); extern void freedtoa ANSI((char*)); extern float strtof ANSI((CONST char *, char **)); extern double strtod ANSI((CONST char *, char **)); -extern int strtodg ANSI((CONST char*, char**, CONST FPI*, Long*, ULong*)); +extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); -extern char* g_ddfmt ANSI((char*, double*, int, unsigned)); -extern char* g_dfmt ANSI((char*, double*, int, unsigned)); -extern char* g_ffmt ANSI((char*, float*, int, unsigned)); -extern char* g_Qfmt ANSI((char*, void*, int, unsigned)); -extern char* g_xfmt ANSI((char*, void*, int, unsigned)); -extern char* g_xLfmt ANSI((char*, void*, int, unsigned)); +extern char* g_ddfmt ANSI((char*, double*, int, size_t)); +extern char* g_ddfmt_p ANSI((char*, double*, int, size_t, int)); +extern char* g_dfmt ANSI((char*, double*, int, size_t)); +extern char* g_dfmt_p ANSI((char*, double*, int, size_t, int)); +extern char* g_ffmt ANSI((char*, float*, int, size_t)); +extern char* g_ffmt_p ANSI((char*, float*, int, size_t, int)); +extern char* g_Qfmt ANSI((char*, void*, int, size_t)); +extern char* g_Qfmt_p ANSI((char*, void*, int, size_t, int)); +extern char* g_xfmt ANSI((char*, void*, int, size_t)); +extern char* g_xfmt_p ANSI((char*, void*, int, size_t, int)); +extern char* g_xLfmt ANSI((char*, void*, int, size_t)); +extern char* g_xLfmt_p ANSI((char*, void*, int, size_t, int)); extern int strtoId ANSI((CONST char*, char**, double*, double*)); extern int strtoIdd ANSI((CONST char*, char**, double*, double*)); diff --git a/gdtoa/gdtoa_fltrnds.h b/gdtoa/gdtoa_fltrnds.h new file mode 100644 index 000000000..33e5f9e53 --- /dev/null +++ b/gdtoa/gdtoa_fltrnds.h @@ -0,0 +1,18 @@ + FPI *fpi, fpi1; + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ + fpi = &fpi0; + if (Rounding != 1) { + fpi1 = fpi0; + fpi = &fpi1; + fpi1.rounding = Rounding; + } diff --git a/gdtoa/gdtoaimp.h b/gdtoa/gdtoaimp.h index f93e03ef5..4dea69e56 100644 --- a/gdtoa/gdtoaimp.h +++ b/gdtoa/gdtoaimp.h @@ -89,12 +89,18 @@ THIS SOFTWARE. * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic (D_floating). * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. + * computation of dtoa and gdtoa. This will cause modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines * that use extended-precision instructions to compute rounded * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic + * that rounds toward +Infinity. + * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. * #define Inaccurate_Divide for IEEE-format with correctly rounded * products but inaccurate quotients, e.g., for Intel i860. * #define NO_LONG_LONG on machines that do not have a "long long" @@ -113,7 +119,12 @@ THIS SOFTWARE. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a gdtoa call after a gdtoa return in + * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, @@ -126,8 +137,10 @@ THIS SOFTWARE. * conversions of IEEE doubles in single-threaded executions with * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, * strtodg also accepts (case insensitively) strings of the form * NaN(x), where x is a string of hexadecimal digits (optionally @@ -151,7 +164,7 @@ THIS SOFTWARE. * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. * #define IMPRECISE_INEXACT if you do not care about the setting of * the STRTOG_Inexact bits in the special case of doing IEEE double - * precision conversions (which could also be done by the strtog in + * precision conversions (which could also be done by the strtod in * dtoa.c). * #define NO_HEX_FP to disable recognition of C9x's hexadecimal * floating-point constants. @@ -220,6 +233,10 @@ THIS SOFTWARE. #include "gd_qnan.h" #endif +#ifdef Honor_FLT_ROUNDS +#include +#endif + #ifdef DEBUG #include "stdio.h" #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} @@ -229,13 +246,13 @@ THIS SOFTWARE. #include "string.h" #ifdef KR_headers -#define KR_VOID char +#define Char char #else -#define KR_VOID void +#define Char void #endif #ifdef MALLOC -extern KR_VOID *MALLOC ANSI((size_t)); +extern Char *MALLOC ANSI((size_t)); #else #define MALLOC malloc #endif @@ -307,19 +324,19 @@ extern "C" { #endif #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 -#error Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. #endif typedef union { double d; ULong L[2]; } U; #ifdef IEEE_8087 -#define word0(x) x.L[1] -#define word1(x) x.L[0] +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] #else -#define word0(x) x.L[0] -#define word1(x) x.L[1] +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #endif -#define dval(x) x.d +#define dval(x) (x)->d /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is @@ -433,6 +450,11 @@ typedef union { double d; ULong L[2]; } U; #ifndef IEEE_Arith #define ROUND_BIASED +#else +#ifdef ROUND_BIASED_without_Round_Up +#undef ROUND_BIASED +#define ROUND_BIASED +#endif #endif #ifdef RND_PRODQUOT @@ -488,12 +510,12 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #define ALL_ON 0xffff #endif -#ifndef MULTIPLE_THREADS +//#ifndef MULTIPLE_THREADS #define ACQUIRE_DTOA_LOCK(n) /*nothing*/ #define FREE_DTOA_LOCK(n) /*nothing*/ -#endif +//#endif -#define Kmax (sizeof(size_t) << 3) +#define Kmax 9 struct Bigint { @@ -516,12 +538,15 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); #define Balloc Balloc_D2A #define Bfree Bfree_D2A +#define InfName InfName_D2A +#define NanName NanName_D2A #define ULtoQ ULtoQ_D2A #define ULtof ULtof_D2A #define ULtod ULtod_D2A #define ULtodd ULtodd_D2A #define ULtox ULtox_D2A #define ULtoxL ULtoxL_D2A +#define add_nanbits add_nanbits_D2A #define any_on any_on_D2A #define b2d b2d_D2A #define bigtens bigtens_D2A @@ -560,9 +585,11 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); #define trailz trailz_D2A #define ulp ulp_D2A + extern char *add_nanbits ANSI((char*, size_t, ULong*, int)); extern char *dtoa_result; extern CONST double bigtens[], tens[], tinytens[]; extern unsigned char hexdig[]; + extern const char *InfName[6], *NanName[3]; extern Bigint *Balloc ANSI((int)); extern void Bfree ANSI((Bigint*)); @@ -577,14 +604,14 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern int cmp ANSI((Bigint*, Bigint*)); extern void copybits ANSI((ULong*, int, Bigint*)); extern Bigint *d2b ANSI((double, int*, int*)); - extern int decrement ANSI((Bigint*)); + extern void decrement ANSI((Bigint*)); extern Bigint *diff ANSI((Bigint*, Bigint*)); extern char *dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); - extern char *g__fmt ANSI((char*, char*, char*, int, ULong)); - extern int gethex ANSI((CONST char**, CONST FPI*, Long*, Bigint**, int)); + extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t)); + extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int)); extern void hexdig_init_D2A(Void); - extern int hexnan ANSI((CONST char**, CONST FPI*, ULong*)); + extern int hexnan ANSI((CONST char**, FPI*, ULong*)); extern int hi0bits_D2A ANSI((ULong)); extern Bigint *i2b ANSI((int)); extern Bigint *increment ANSI((Bigint*)); @@ -599,14 +626,14 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern double ratio ANSI((Bigint*, Bigint*)); extern void rshift ANSI((Bigint*, int)); extern char *rv_alloc ANSI((int)); - extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong, int)); extern Bigint *set_ones ANSI((Bigint*, int)); extern char *strcp ANSI((char*, const char*)); - extern int strtoIg ANSI((CONST char*, char**, CONST FPI*, Long*, Bigint**, int*)); + extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); extern double strtod ANSI((const char *s00, char **se)); extern Bigint *sum ANSI((Bigint*, Bigint*)); extern int trailz ANSI((Bigint*)); - extern double ulp ANSI((double)); + extern double ulp ANSI((U*)); #ifdef __cplusplus } @@ -621,6 +648,10 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) */ #ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif #ifdef IEEE_MC68k #define _0 0 #define _1 1 diff --git a/gdtoa/gethex.c b/gdtoa/gethex.c index 7273a6c3b..72da9d326 100644 --- a/gdtoa/gethex.c +++ b/gdtoa/gethex.c @@ -40,22 +40,34 @@ THIS SOFTWARE. gethex(sp, fpi, exp, bp, sign) CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; #else -gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) #endif { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; - int esign, havedig, irv, k, n, nbits, up, zret; + int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE - unsigned char decimalpoint = *localeconv()->decimal_point; + int i; +#ifdef NO_LOCALE_CACHE + const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point; #else -#define decimalpoint '.' + const unsigned char *decimalpoint; + static unsigned char *decimalpoint_cache; + if (!(s0 = decimalpoint_cache)) { + s0 = (unsigned char*)localeconv()->decimal_point; + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; +#endif #endif - if (!hexdig['0']) - hexdig_init_D2A(); + /**** if (!hexdig['0']) hexdig_init_D2A(); ****/ + *bp = 0; havedig = 0; s0 = *(CONST unsigned char **)sp + 2; while(s0[havedig] == '0') @@ -65,11 +77,21 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) decpt = 0; zret = 0; e = 0; - if (!hexdig[*s]) { + if (hexdig[*s]) + havedig++; + else { zret = 1; - if (*s != decimalpoint) +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s != '.') goto pcheck; decpt = ++s; +#endif if (!hexdig[*s]) goto pcheck; while(*s == '0') @@ -81,19 +103,28 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) } while(hexdig[*s]) s++; - if (*s == decimalpoint && !decpt) { +#ifdef USE_LOCALE + if (*s == *decimalpoint && !decpt) { + for(i = 1; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s == '.' && !decpt) { decpt = ++s; +#endif while(hexdig[*s]) s++; - } + }/*}*/ if (decpt) e = -(((Long)(s-decpt)) << 2); pcheck: s1 = s; + big = esign = 0; switch(*s) { case 'p': case 'P': - esign = 0; switch(*++s) { case '-': esign = 1; @@ -106,29 +137,87 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) break; } e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) + while((n = hexdig[*++s]) !=0 && n <= 0x19) { + if (e1 & 0xf8000000) + big = 1; e1 = 10*e1 + n - 0x10; + } if (esign) e1 = -e1; e += e1; } *sp = (char*)s; - if (zret) { - if (!havedig) - *sp = s0 - 1; + if (!havedig) + *sp = (char*)s0 - 1; + if (zret) return STRTOG_Zero; + if (big) { + if (esign) { + switch(fpi->rounding) { + case FPI_Round_up: + if (sign) + break; + goto ret_tiny; + case FPI_Round_down: + if (!sign) + break; + goto ret_tiny; + } + goto retz; + ret_tiny: + b = Balloc(0); + b->wds = 1; + b->x[0] = 1; + goto dret; + } + switch(fpi->rounding) { + case FPI_Round_near: + goto ovfl1; + case FPI_Round_up: + if (!sign) + goto ovfl1; + goto ret_big; + case FPI_Round_down: + if (sign) + goto ovfl1; + goto ret_big; + } + ret_big: + nbits = fpi->nbits; + n0 = n = nbits >> kshift; + if (nbits & kmask) + ++n; + for(j = n, k = 0; j >>= 1; ++k); + *bp = b = Balloc(k); + b->wds = n; + for(j = 0; j < n0; ++j) + b->x[j] = ALL_ON; + if (n > n0) + b->x[j] = ULbits >> (ULbits - (nbits & kmask)); + *exp = fpi->emin; + return STRTOG_Normal | STRTOG_Inexlo; } - n = (int)(s1 - s0 - 1); - for(k = 0; n > 7; n >>= 1) + n = s1 - s0 - 1; + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) k++; b = Balloc(k); x = b->x; n = 0; L = 0; +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i+1]; ++i); +#endif while(s1 > s0) { - if (*--s1 == decimalpoint) +#ifdef USE_LOCALE + if (*--s1 == decimalpoint[i]) { + s1 -= i; continue; - if (n == 32) { + } +#else + if (*--s1 == '.') + continue; +#endif + if (n == ULbits) { *x++ = L; L = 0; n = 0; @@ -137,8 +226,8 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) n += 4; } *x++ = L; - b->wds = n = (int)(x - b->x); - n = 32*n - hi0bits(L); + b->wds = n = x - b->x; + n = ULbits*n - hi0bits(L); nbits = fpi->nbits; lostbits = 0; x = b->x; @@ -149,7 +238,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) k = n - 1; if (x[k>>kshift] & 1 << (k & kmask)) { lostbits = 2; - if (k > 1 && any_on(b,k-1)) + if (k > 0 && any_on(b,k)) lostbits = 3; } } @@ -165,7 +254,10 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) if (e > fpi->emax) { ovfl: Bfree(b); - *bp = 0; + ovfl1: +#ifndef NO_ERRNO + errno = ERANGE; +#endif return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; } irv = STRTOG_Normal; @@ -185,15 +277,22 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) case FPI_Round_down: if (sign) { one_bit: - *exp = fpi->emin; x[0] = b->wds = 1; + dret: *bp = b; + *exp = fpi->emin; +#ifndef NO_ERRNO + errno = ERANGE; +#endif return STRTOG_Denormal | STRTOG_Inexhi | STRTOG_Underflow; } } Bfree(b); - *bp = 0; + retz: +#ifndef NO_ERRNO + errno = ERANGE; +#endif return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; } k = n - 1; @@ -214,7 +313,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) break; case FPI_Round_near: if (lostbits & 2 - && (lostbits & 1) | x[0] & 1) + && (lostbits | x[0]) & 1) up = 1; break; case FPI_Round_up: @@ -233,8 +332,8 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign) irv = STRTOG_Normal; } else if (b->wds > k - || (n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n) { + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { rshift(b,1); if (++e > fpi->emax) goto ovfl; diff --git a/gdtoa/gmisc.c b/gdtoa/gmisc.c index 988d3bfbb..8270ef944 100644 --- a/gdtoa/gmisc.c +++ b/gdtoa/gmisc.c @@ -60,7 +60,7 @@ rshift(Bigint *b, int k) while(x < xe) *x1++ = *x++; } - if ((b->wds = (int)(x1 - b->x)) == 0) + if ((b->wds = x1 - b->x) == 0) b->x[0] = 0; } diff --git a/gdtoa/hd_init.c b/gdtoa/hd_init.c index fa6e18dee..d79ae2ec8 100644 --- a/gdtoa/hd_init.c +++ b/gdtoa/hd_init.c @@ -31,6 +31,7 @@ THIS SOFTWARE. #include "gdtoaimp.h" +#if 0 unsigned char hexdig[256]; static void @@ -46,10 +47,31 @@ htinit(unsigned char *h, unsigned char *s, int inc) } void -hexdig_init_D2A(Void) +hexdig_init_D2A(Void) /* Use of hexdig_init omitted 20121220 to avoid a */ + /* race condition when multiple threads are used. */ { #define USC (unsigned char *) htinit(hexdig, USC "0123456789", 0x10); htinit(hexdig, USC "abcdef", 0x10 + 10); htinit(hexdig, USC "ABCDEF", 0x10 + 10); } +#else + unsigned char hexdig[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0, + 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; +#endif diff --git a/gdtoa/hexnan.c b/gdtoa/hexnan.c index 0ee127f56..80721e97a 100644 --- a/gdtoa/hexnan.c +++ b/gdtoa/hexnan.c @@ -54,15 +54,14 @@ L_shift(ULong *x, ULong *x1, int i) hexnan(sp, fpi, x0) CONST char **sp; FPI *fpi; ULong *x0; #else -hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) +hexnan( CONST char **sp, FPI *fpi, ULong *x0) #endif { ULong c, h, *x, *x1, *xe; CONST char *s; int havedig, hd0, i, nbits; - if (!hexdig['0']) - hexdig_init_D2A(); + /**** if (!hexdig['0']) hexdig_init_D2A(); ****/ nbits = fpi->nbits; x = x0 + (nbits >> kshift); if (nbits & kmask) @@ -72,12 +71,15 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) havedig = hd0 = i = 0; s = *sp; /* allow optional initial 0x or 0X */ - while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') { + if (!c) + goto retnan; ++s; + } if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') && *(CONST unsigned char*)(s+3) > ' ') s += 2; - while(c = *(CONST unsigned char*)++s) { + while((c = *(CONST unsigned char*)++s)) { if (!(h = hexdig[c])) { if (c <= ' ') { if (hd0 < havedig) { @@ -92,8 +94,11 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) x1 = x; i = 0; } - while(*(CONST unsigned char*)(s+1) <= ' ') + while((c = *(CONST unsigned char*)(s+1)) <= ' ') { + if (!c) + goto retnan; ++s; + } if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') && *(CONST unsigned char*)(s+3) > ' ') s += 2; @@ -107,10 +112,11 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) do { if (/*(*/ c == ')') { *sp = s + 1; - break; + goto break2; } - } while(c = *++s); + } while((c = *++s)); #endif + retnan: return STRTOG_NaN; } havedig++; @@ -120,8 +126,11 @@ hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) i = 1; *--x = 0; } - *x = (*x << 4) | h & 0xf; + *x = (*x << 4) | (h & 0xf); } +#ifndef GDTOA_NON_PEDANTIC_NANCHECK + break2: +#endif if (!havedig) return STRTOG_NaN; if (x < x1 && i < 8) diff --git a/gdtoa/misc.c b/gdtoa/misc.c index 51f8f52fe..d13046732 100644 --- a/gdtoa/misc.c +++ b/gdtoa/misc.c @@ -38,11 +38,6 @@ THIS SOFTWARE. #endif #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#ifdef MULTIPLE_THREADS -static void ACQUIRE_DTOA_LOCK(int n); -static void FREE_DTOA_LOCK(int n); #endif Bigint * @@ -60,7 +55,9 @@ Balloc #endif ACQUIRE_DTOA_LOCK(0); - if ( (rv = freelist[k]) !=0) { + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k]) !=0) { freelist[k] = rv->next; } else { @@ -70,7 +67,7 @@ Balloc #else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -94,10 +91,18 @@ Bfree #endif { if (v) { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); + if (v->k > Kmax) +#ifdef FREE + FREE((void*)v); +#else + free((void*)v); +#endif + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } } } @@ -109,8 +114,8 @@ lo0bits (ULong *y) #endif { - register int k; - register ULong x = *y; + int k; + ULong x = *y; if (x & 7) { if (x & 1) @@ -209,12 +214,12 @@ multadd int hi0bits_D2A #ifdef KR_headers - (x) register ULong x; + (x) ULong x; #else - (register ULong x) + (ULong x) #endif { - register int k = 0; + int k = 0; if (!(x & 0xffff0000)) { k = 16; @@ -621,8 +626,8 @@ b2d #ifdef VAX ULong d0, d1; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) #endif xa0 = a->x; @@ -635,16 +640,16 @@ b2d *e = 32 - k; #ifdef Pack_32 if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; + d0 = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; + d0 = Exp_1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; + d1 = z << k | y >> (32 - k); } else { d0 = Exp_1 | y; @@ -668,10 +673,10 @@ b2d #endif ret_d: #ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; #endif - return dval(d); + return dval(&d); } #undef d0 #undef d1 @@ -679,29 +684,28 @@ b2d Bigint * d2b #ifdef KR_headers - (d, e, bits) double d; int *e, *bits; + (dd, e, bits) double dd; int *e, *bits; #else - (double _d, int *e, int *bits) + (double dd, int *e, int *bits) #endif { Bigint *b; + U d; #ifndef Sudden_Underflow int i; #endif int de, k; ULong *x, y, z; - U d; #ifdef VAX ULong d0, d1; #else -#define d0 word0(d) -#define d1 word1(d) +#define d0 word0(&d) +#define d1 word1(&d) #endif - - dval(d) = _d; + d.d = dd; #ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; + d0 = word0(&d) >> 16 | word0(&d) << 16; + d1 = word1(&d) >> 16 | word1(&d) << 16; #endif #ifdef Pack_32 @@ -725,7 +729,7 @@ d2b #ifdef Pack_32 if ( (y = d1) !=0) { if ( (k = lo0bits(&y)) !=0) { - x[0] = y | z << 32 - k; + x[0] = y | z << (32 - k); z >>= k; } else @@ -736,10 +740,6 @@ d2b b->wds = (x[1] = z) !=0 ? 2 : 1; } else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow @@ -798,7 +798,7 @@ d2b #endif #ifdef IBM *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask); #else *e = de - Bias - (P-1) + k; *bits = P - k; @@ -851,71 +851,25 @@ strcp_D2A(a, b) char *a; char *b; strcp_D2A(char *a, CONST char *b) #endif { - while(*a = *b++) + while((*a = *b++)) a++; return a; } #ifdef NO_STRING_H - KR_VOID * + Char * #ifdef KR_headers -memcpy_D2A(a, b, len) char *a; char *b; size_t len; +memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; #else memcpy_D2A(void *a1, void *b1, size_t len) #endif { - register char *a = (char*)a1, *ae = a + len; - register char *b = (char*)b1, *a0 = a; + char *a = (char*)a1, *ae = a + len; + char *b = (char*)b1, *a0 = a; while(a < ae) *a++ = *b++; return a0; } #endif /* NO_STRING_H */ - - -#ifdef MULTIPLE_THREADS -#ifdef _WIN32 - -#undef Bias -#define WIN32_LEAN_AND_MEAN -#include - -static CRITICAL_SECTION dtoa_lock[2]; -static int did_init; - -void ACQUIRE_DTOA_LOCK(int n) -{ - if (!did_init) - { - did_init = 1; - InitializeCriticalSection(&dtoa_lock[0]); - InitializeCriticalSection(&dtoa_lock[1]); - } - EnterCriticalSection(&dtoa_lock[n]); -} - -void FREE_DTOA_LOCK(int n) -{ - LeaveCriticalSection(&dtoa_lock[n]); -} - -#else - -#include - -static pthread_mutex_t dtoa_lock[2] = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }; - -void ACQUIRE_DTOA_LOCK(int n) -{ - pthread_mutex_lock(&dtoa_lock[n]); -} - -void FREE_DTOA_LOCK(int n) -{ - pthread_mutex_unlock(&dtoa_lock[n]); -} - -#endif -#endif diff --git a/gdtoa/qnan.c b/gdtoa/qnan.c index 118e74921..ea7e8745b 100644 --- a/gdtoa/qnan.c +++ b/gdtoa/qnan.c @@ -55,11 +55,19 @@ typedef unsigned Long Ulong; #ifdef IEEE_8087 #define _0 1 #define _1 0 +#define _3 3 +#if defined(Gen_ld_QNAN) && !defined(NO_LONG_LONG) +static int perm[4] = { 0, 1, 2, 3 }; +#endif #define HAVE_IEEE #endif #ifdef IEEE_MC68k #define _0 0 #define _1 1 +#define _3 0 +#if defined(Gen_ld_QNAN) && !defined(NO_LONG_LONG) +static int perm[4] = { 3, 2, 1, 0 }; +#endif #define HAVE_IEEE #endif @@ -79,31 +87,32 @@ main(void) #endif } U; U a, b, c; +#if defined(Gen_ld_QNAN) && !defined(NO_LONG_LONG) int i; +#endif a.L[0] = b.L[0] = 0x7f800000; c.f = a.f - b.f; - printf("#define f_QNAN 0x%lx\n", UL c.L[0]); + printf("#define f_QNAN 0x%lx\n", UL (c.L[0] & 0x7fffffff)); a.L[_0] = b.L[_0] = 0x7ff00000; a.L[_1] = b.L[_1] = 0; c.d = a.d - b.d; /* quiet NaN */ - printf("#define d_QNAN0 0x%lx\n", UL c.L[0]); - printf("#define d_QNAN1 0x%lx\n", UL c.L[1]); -#ifdef NO_LONG_LONG - for(i = 0; i < 4; i++) - printf("#define ld_QNAN%d 0xffffffff\n", i); - for(i = 0; i < 5; i++) - printf("#define ldus_QNAN%d 0xffff\n", i); -#else - b.D = c.D = a.d; - if (printf("") < 0) - c.D = 37; /* never executed; just defeat optimization */ - a.L[2] = a.L[3] = 0; - a.D = b.D - c.D; - for(i = 0; i < 4; i++) - printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]); - for(i = 0; i < 5; i++) - printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]); + c.L[_0] &= 0x7fffffff; + printf("#define d_QNAN0 0x%lx\n", UL c.L[_0]); + printf("#define d_QNAN1 0x%lx\n", UL c.L[_1]); +#ifndef NO_LONG_LONG +#ifdef Gen_ld_QNAN + if (sizeof(a.D) >= 16) { + b.D = c.D = a.d; + if (printf("") < 0) + c.D = 37; /* never executed; just defeat optimization */ + a.L[0] = a.L[1] = a.L[2] = a.L[3] = 0; + a.D = b.D - c.D; + a.L[_3] &= 0x7fffffff; + for(i = 0; i < 4; i++) + printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[perm[i]]); + } +#endif #endif #endif /* HAVE_IEEE */ return 0; diff --git a/gdtoa/smisc.c b/gdtoa/smisc.c index 858024c9e..f4dbafb21 100644 --- a/gdtoa/smisc.c +++ b/gdtoa/smisc.c @@ -34,9 +34,9 @@ THIS SOFTWARE. Bigint * s2b #ifdef KR_headers - (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; + (s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9; #else - (CONST char *s, int nd0, int nd, ULong y9) + (CONST char *s, int nd0, int nd, ULong y9, int dplen) #endif { Bigint *b; @@ -60,10 +60,10 @@ s2b s += 9; do b = multadd(b, 10, *s++ - '0'); while(++i < nd0); - s++; + s += dplen; } else - s += 10; + s += dplen + 9; for(; i < nd; i++) b = multadd(b, 10, *s++ - '0'); return b; @@ -80,30 +80,30 @@ ratio U da, db; int k, ka, kb; - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); k = ka - kb + ULbits*(a->wds - b->wds); #ifdef IBM if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; + word0(&da) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(da) *= 1 << k; + dval(&da) *= 1 << k; } else { k = -k; - word0(db) += (k >> 2)*Exp_msk1; + word0(&db) += (k >> 2)*Exp_msk1; if (k &= 3) - dval(db) *= 1 << k; + dval(&db) *= 1 << k; } #else if (k > 0) - word0(da) += k*Exp_msk1; + word0(&da) += k*Exp_msk1; else { k = -k; - word0(db) += k*Exp_msk1; + word0(&db) += k*Exp_msk1; } #endif - return dval(da) / dval(db); + return dval(&da) / dval(&db); } #ifdef INFNAN_CHECK diff --git a/gdtoa/strtoIQ.c b/gdtoa/strtoIQ.c index 000fa3645..9ce5120e6 100644 --- a/gdtoa/strtoIQ.c +++ b/gdtoa/strtoIQ.c @@ -38,7 +38,7 @@ strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; strtoIQ(CONST char *s, char **sp, void *a, void *b) #endif { - static CONST FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + static FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; diff --git a/gdtoa/strtoId.c b/gdtoa/strtoId.c index d34a278ee..1c97d382d 100644 --- a/gdtoa/strtoId.c +++ b/gdtoa/strtoId.c @@ -38,7 +38,7 @@ strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; strtoId(CONST char *s, char **sp, double *f0, double *f1) #endif { - static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; diff --git a/gdtoa/strtoIdd.c b/gdtoa/strtoIdd.c index 921597fe7..40b7936bc 100644 --- a/gdtoa/strtoIdd.c +++ b/gdtoa/strtoIdd.c @@ -39,9 +39,9 @@ strtoIdd(CONST char *s, char **sp, double *f0, double *f1) #endif { #ifdef Sudden_Underflow - static CONST FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; + static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; #else - static CONST FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; + static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; #endif Long exp[2]; Bigint *B[2]; diff --git a/gdtoa/strtoIf.c b/gdtoa/strtoIf.c index b937ff079..65ecab2e0 100644 --- a/gdtoa/strtoIf.c +++ b/gdtoa/strtoIf.c @@ -38,7 +38,7 @@ strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1; strtoIf(CONST char *s, char **sp, float *f0, float *f1) #endif { - static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; diff --git a/gdtoa/strtoIg.c b/gdtoa/strtoIg.c index fd181fc9b..6a17760cf 100644 --- a/gdtoa/strtoIg.c +++ b/gdtoa/strtoIg.c @@ -35,7 +35,7 @@ THIS SOFTWARE. #ifdef KR_headers strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; #else -strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *rvp) +strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) #endif { Bigint *b, *b1; @@ -61,16 +61,20 @@ strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int * if (rv & STRTOG_Inexlo) { swap = 0; b1 = increment(b1); - if (fpi->sudden_underflow - && (rv & STRTOG_Retmask) == STRTOG_Zero) { - b1->x[0] = 0; - b1->x[nw1] = 1L << nb11; - rv1 += STRTOG_Normal - STRTOG_Zero; - rv1 &= ~STRTOG_Underflow; + if ((rv & STRTOG_Retmask) == STRTOG_Zero) { + if (fpi->sudden_underflow) { + b1->x[0] = 0; + b1->x[nw1] = 1L << nb11; + rv1 += STRTOG_Normal - STRTOG_Zero; + rv1 &= ~STRTOG_Underflow; + goto swapcheck; + } + rv1 &= STRTOG_Inexlo | STRTOG_Underflow | STRTOG_Zero; + rv1 |= STRTOG_Inexhi | STRTOG_Denormal; goto swapcheck; } if (b1->wds > nw - || nb1 && b1->x[nw1] & 1L << nb1) { + || (nb1 && b1->x[nw1] & 1L << nb1)) { if (++e1 > fpi->emax) rv1 = STRTOG_Infinite | STRTOG_Inexhi; rshift(b1, 1); diff --git a/gdtoa/strtoIx.c b/gdtoa/strtoIx.c index 8e972c976..783a631f0 100644 --- a/gdtoa/strtoIx.c +++ b/gdtoa/strtoIx.c @@ -38,7 +38,7 @@ strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; strtoIx(CONST char *s, char **sp, void *a, void *b) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; diff --git a/gdtoa/strtoIxL.c b/gdtoa/strtoIxL.c index 86dbc744a..869bfd16f 100644 --- a/gdtoa/strtoIxL.c +++ b/gdtoa/strtoIxL.c @@ -38,7 +38,7 @@ strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; strtoIxL(CONST char *s, char **sp, void *a, void *b) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; Long exp[2]; Bigint *B[2]; int k, rv[2]; diff --git a/gdtoa/strtod.c b/gdtoa/strtod.c index 1f01921a4..3c2230053 100644 --- a/gdtoa/strtod.c +++ b/gdtoa/strtod.c @@ -42,24 +42,43 @@ THIS SOFTWARE. #ifndef NO_IEEE_Scale #define Avoid_Underflow #undef tinytens -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, - 9007199254740992.e-256 + 9007199254740992.*9007199254740992.e-256 }; #endif #endif -#include - #ifdef Honor_FLT_ROUNDS -#define Rounding rounding #undef Check_FLT_ROUNDS #define Check_FLT_ROUNDS #else #define Rounding Flt_Rounds #endif +#ifdef Avoid_Underflow /*{*/ + static double +sulp +#ifdef KR_headers + (x, scale) U *x; int scale; +#else + (U *x, int scale) +#endif +{ + U u; + double rv; + int i; + + rv = ulp(x); + if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) + return rv; /* Is there an example where i <= 0 ? */ + word0(&u) = Exp_1 + (i << Exp_shift); + word1(&u) = 0; + return rv * u.d; + } +#endif /*}*/ + double strtod #ifdef KR_headers @@ -74,21 +93,55 @@ strtod int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; - double aadj, adj; - U rv, rv0, aadj1; + double aadj; Long L; + U adj, aadj1, rv, rv0; ULong y, z; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef Avoid_Underflow + ULong Lsb, Lsb1; +#endif #ifdef SET_INEXACT int inexact, oldinexact; #endif -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif +#ifdef USE_LOCALE /*{{*/ +#ifdef NO_LOCALE_CACHE + char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); +#else + char *decimalpoint; + static char *decimalpoint_cache; + static int dplen; + if (!(s0 = decimalpoint_cache)) { + s0 = localeconv()->decimal_point; + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + dplen = strlen(s0); + } + decimalpoint = (char*)s0; +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ + +#ifdef Honor_FLT_ROUNDS /*{*/ + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ - //_control87(_PC_53, _MCW_PC); sign = nz0 = nz = decpt = 0; - dval(rv) = 0.; + dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': sign = 1; @@ -111,22 +164,18 @@ strtod } break2: if (*s == '0') { -#ifndef NO_HEX_FP +#ifndef NO_HEX_FP /*{*/ { - static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; Long exp; ULong bits[2]; switch(s[1]) { case 'x': case 'X': { -#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) +#ifdef Honor_FLT_ROUNDS FPI fpi1 = fpi; - switch(fegetround()) { - case FE_TOWARDZERO: fpi1.rounding = 0; break; - case FE_UPWARD: fpi1.rounding = 2; break; - case FE_DOWNWARD: fpi1.rounding = 3; - } + fpi1.rounding = Rounding; #else #define fpi1 fpi #endif @@ -146,7 +195,7 @@ strtod goto ret; } } -#endif +#endif /*}*/ nz0 = 1; while(*++s == '0') ; if (!*s) @@ -161,13 +210,17 @@ strtod z = 10*z + c - '0'; nd0 = nd; #ifdef USE_LOCALE - if (c == *localeconv()->decimal_point) + if (c == *decimalpoint) { + for(i = 1; decimalpoint[i]; ++i) + if (s[i] != decimalpoint[i]) + goto dig_done; + s += i; + c = *s; #else - if (c == '.') -#endif - { - decpt = 1; + if (c == '.') { c = *++s; +#endif + decpt = 1; if (!nd) { for(; c == '0'; c = *++s) nz++; @@ -196,7 +249,7 @@ strtod nz = 0; } } - } + }/*}*/ dig_done: e = 0; if (c == 'e' || c == 'E') { @@ -240,7 +293,7 @@ strtod #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ ULong bits[2]; - static CONST FPI fpinan = /* only 52 explicit bits */ + static FPI fpinan = /* only 52 explicit bits */ { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; if (!decpt) switch(c) { @@ -250,8 +303,8 @@ strtod --s; if (!match(&s,"inity")) ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; goto ret; } break; @@ -262,13 +315,13 @@ strtod if (*s == '(' /*)*/ && hexnan(&s, &fpinan, bits) == STRTOG_NaNbits) { - word0(rv) = 0x7ff00000 | bits[1]; - word1(rv) = bits[0]; + word0(&rv) = 0x7ff00000 | bits[1]; + word1(&rv) = bits[0]; } else { #endif - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN } #endif @@ -292,13 +345,13 @@ strtod if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) oldinexact = get_inexact(); #endif - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; } bd0 = 0; if (nd <= DBL_DIG @@ -310,6 +363,7 @@ strtod ) { if (!e) goto ret; +#ifndef ROUND_BIASED_without_Round_Up if (e > 0) { if (e <= Ten_pmax) { #ifdef VAX @@ -318,11 +372,11 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + rv.d = -rv.d; sign = 0; } #endif - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; #endif } @@ -334,25 +388,25 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + rv.d = -rv.d; sign = 0; } #endif e -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto ovfl; - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; #else - /* rv = */ rounded_product(dval(rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); #endif goto ret; } @@ -362,14 +416,15 @@ strtod #ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) { - rv = -rv; + rv.d = -rv.d; sign = 0; } #endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } #endif +#endif /* ROUND_BIASED_without_Round_Up */ } e1 += nd - k; @@ -383,12 +438,12 @@ strtod scale = 0; #endif #ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { + if (Rounding >= 2) { if (sign) - rounding = rounding == 2 ? 0 : 2; + Rounding = Rounding == 2 ? 0 : 2; else - if (rounding != 2) - rounding = 0; + if (Rounding != 2) + Rounding = 0; } #endif #endif /*IEEE_Arith*/ @@ -397,67 +452,73 @@ strtod if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: -#ifndef NO_ERRNO - errno = ERANGE; -#endif /* Can't trust HUGE_VAL */ #ifdef IEEE_Arith #ifdef Honor_FLT_ROUNDS - switch(rounding) { + switch(Rounding) { case 0: /* toward 0 */ case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; break; default: - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; } #else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); #endif #else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; #endif /*IEEE_Arith*/ - if (bd0) - goto retfree; + range_err: + if (bd0) { + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + } +#ifndef NO_ERRNO + errno = ERANGE; +#endif goto ret; } e1 >>= 4; for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) goto ovfl; if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { /* set to largest number */ /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; @@ -466,44 +527,39 @@ strtod scale = 2*P; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + dval(&rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { /* scaled rv is denormal; zap j low bits */ if (j >= 32) { - word1(rv) = 0; + word1(&rv) = 0; if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; + word0(&rv) = (P+2)*Exp_msk1; else - word0(rv) &= 0xffffffff << j-32; + word0(&rv) &= 0xffffffff << (j-32); } else - word1(rv) &= 0xffffffff << j; + word1(&rv) &= 0xffffffff << j; } #else for(j = 0; e1 > 1; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; #endif - if (!dval(rv)) { + if (!dval(&rv)) { undfl: - dval(rv) = 0.; -#ifndef NO_ERRNO - errno = ERANGE; -#endif - if (bd0) - goto retfree; - goto ret; + dval(&rv) = 0.; + goto range_err; } #ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; /* The refinement below will clean * this approximation up. */ @@ -516,12 +572,12 @@ strtod /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ bs = i2b(1); if (e >= 0) { @@ -538,16 +594,23 @@ strtod bd2 -= bbe; bs2 = bb2; #ifdef Honor_FLT_ROUNDS - if (rounding != 1) + if (Rounding != 1) bs2++; #endif #ifdef Avoid_Underflow + Lsb = LSB; + Lsb1 = 0; j = bbe - scale; i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; + j = P + 1 - bbbits; + if (i < Emin) { /* denormal */ + i = Emin - i; + j -= i; + if (i < 32) + Lsb <<= i; + else + Lsb1 = Lsb << (i-32); + } #else /*Avoid_Underflow*/ #ifdef Sudden_Underflow #ifdef IBM @@ -557,7 +620,7 @@ strtod #endif #else /*Sudden_Underflow*/ j = bbe; - i = j + bbbits - 1; /* logb(rv) */ + i = j + bbbits - 1; /* logb(&rv) */ if (i < Emin) /* denormal */ j += P - Emin; else @@ -596,7 +659,7 @@ strtod delta->sign = 0; i = cmp(delta, bs); #ifdef Honor_FLT_ROUNDS - if (rounding != 1) { + if (Rounding != 1) { if (i < 0) { /* Error is less than an ulp */ if (!delta->x[0] && delta->wds <= 1) { @@ -606,17 +669,17 @@ strtod #endif break; } - if (rounding) { + if (Rounding) { if (dsign) { - adj = 1.; + dval(&adj) = 1.; goto apply_adj; } } else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; + dval(&adj) = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; #ifdef Avoid_Underflow if (!scale || y > 2*P*Exp_msk1) #else @@ -625,63 +688,66 @@ strtod { delta = lshift(delta,Log2P); if (cmp(delta, bs) <= 0) - adj = -0.5; + dval(&adj) = -0.5; } } apply_adj: #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj*ulp(&rv); + word0(&rv) -= P*Exp_msk1; } else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); + dval(&rv) += adj.d*ulp(&rv); } break; } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { - if (!((rounding>>1) ^ dsign)) + dval(&adj) = ratio(delta, bs); + if (adj.d < 1.) + dval(&adj) = 1.; + if (adj.d <= 0x7ffffffe) { + /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ + y = adj.d; + if (y != adj.d) { + if (!((Rounding>>1) ^ dsign)) y++; - adj = y; + dval(&adj) = y; } } #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&adj) *= ulp(&rv); if (dsign) - dval(rv) += adj; + dval(&rv) += adj; else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; + dval(&rv) -= adj; + word0(&rv) -= P*Exp_msk1; goto cont; } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; + dval(&adj) *= ulp(&rv); + if (dsign) { + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + dval(&rv) += adj.d; + } else - dval(rv) -= adj; + dval(&rv) -= adj.d; goto cont; } #endif /*Honor_FLT_ROUNDS*/ @@ -690,12 +756,12 @@ strtod /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask #ifdef IEEE_Arith #ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(rv) & Exp_mask) <= Exp_msk1 + || (word0(&rv) & Exp_mask) <= Exp_msk1 #endif #endif ) { @@ -720,32 +786,34 @@ strtod if (i == 0) { /* exactly half-way between */ if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( #ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : #endif 0xffffffff)) { /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1 #ifdef IBM | Exp_msk1 >> 4 #endif ; - word1(rv) = 0; + word1(&rv) = 0; #ifdef Avoid_Underflow dsign = 0; #endif break; } } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { drop_down: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; #ifdef IBM if (L < Exp_msk1) #else @@ -760,7 +828,7 @@ strtod #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow if (scale) { - L = word0(rv) & Exp_mask; + L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { if (L > (P+2)*Exp_msk1) /* round even ==> */ @@ -771,10 +839,10 @@ strtod } } #endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; + L = (word0(&rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; #ifdef IBM goto cont; #else @@ -782,16 +850,33 @@ strtod #endif } #ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) +#ifdef Avoid_Underflow + if (Lsb1) { + if (!(word0(&rv) & Lsb1)) + break; + } + else if (!(word1(&rv) & Lsb)) + break; +#else + if (!(word1(&rv) & LSB)) break; +#endif #endif if (dsign) - dval(rv) += ulp(dval(rv)); +#ifdef Avoid_Underflow + dval(&rv) += sulp(&rv, scale); +#else + dval(&rv) += ulp(&rv); +#endif #ifndef ROUND_BIASED else { - dval(rv) -= ulp(dval(rv)); +#ifdef Avoid_Underflow + dval(&rv) -= sulp(&rv, scale); +#else + dval(&rv) -= ulp(&rv); +#endif #ifndef Sudden_Underflow - if (!dval(rv)) + if (!dval(&rv)) goto undfl; #endif } @@ -803,14 +888,14 @@ strtod } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) - aadj = dval(aadj1) = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { + aadj = dval(&aadj1) = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) + if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; #endif aadj = 1.; - dval(aadj1) = -1.; + dval(&aadj1) = -1.; } else { /* special case -- power of FLT_RADIX to be */ @@ -820,45 +905,45 @@ strtod aadj = 1./FLT_RADIX; else aadj *= 0.5; - dval(aadj1) = -aadj; + dval(&aadj1) = -aadj; } } else { aadj *= 0.5; - dval(aadj1) = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch(Rounding) { case 2: /* towards +infinity */ - aadj1 -= 0.5; + dval(&aadj1) -= 0.5; break; case 0: /* towards 0 */ case 3: /* towards -infinity */ - aadj1 += 0.5; + dval(&aadj1) += 0.5; } #else if (Flt_Rounds == 0) - dval(aadj1) += 0.5; + dval(&aadj1) += 0.5; #endif /*Check_FLT_ROUNDS*/ } - y = word0(rv) & Exp_mask; + y = word0(&rv) & Exp_mask; /* Check for overflow */ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); + if ((word0(&rv) & Exp_mask) >= Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; goto cont; } else - word0(rv) += P*Exp_msk1; + word0(&rv) += P*Exp_msk1; } else { #ifdef Avoid_Underflow @@ -867,58 +952,58 @@ strtod if ((z = (ULong)aadj) <= 0) z = 1; aadj = z; - dval(aadj1) = dsign ? aadj : -aadj; + dval(&aadj1) = dsign ? aadj : -aadj; } - word0(aadj1) += (2*P+1)*Exp_msk1 - y; + word0(&aadj1) += (2*P+1)*Exp_msk1 - y; } - adj = dval(aadj1) * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += dval(&adj); #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) #else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) #endif { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; goto cont; } else - word0(rv) -= P*Exp_msk1; + word0(&rv) -= P*Exp_msk1; } else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., + /* Compute dval(&adj) so that the IEEE rounding rules will + * correctly round rv + dval(&adj) in some half-way cases. + * If rv * ulp(&rv) is denormalized (i.e., * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid * trouble from bits lost to denormalization; * example: 1.2e-307 . */ if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); + dval(&aadj1) = (double)(int)(aadj + 0.5); if (!dsign) - aadj1 = -aadj1; + dval(&aadj1) = -dval(&aadj1); } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + dval(&adj) = dval(&aadj1) * ulp(&rv); + dval(&rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ } - z = word0(rv) & Exp_mask; + z = word0(&rv) & Exp_mask; #ifndef SET_INEXACT #ifdef Avoid_Underflow if (!scale) @@ -928,7 +1013,7 @@ strtod L = (Long)aadj; aadj -= L; /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { if (aadj < .4999999 || aadj > .5000001) break; } @@ -942,12 +1027,17 @@ strtod Bfree(bs); Bfree(delta); } + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); #ifdef SET_INEXACT if (inexact) { if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; } } else if (!oldinexact) @@ -955,32 +1045,30 @@ strtod #endif #ifdef Avoid_Underflow if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ - if (word0(rv) == 0 && word1(rv) == 0) +#ifdef IEEE_Arith + if (!(word0(&rv) & Exp_mask)) +#else + if (word0(&rv) == 0 && word1(&rv) == 0) +#endif errno = ERANGE; #endif } #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { + if (inexact && !(word0(&rv) & Exp_mask)) { /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); } #endif - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); ret: if (se) *se = (char *)s; - return sign ? -dval(rv) : dval(rv); + return sign ? -dval(&rv) : dval(&rv); } diff --git a/gdtoa/strtodI.c b/gdtoa/strtodI.c index 992702e25..0b7b8a45c 100644 --- a/gdtoa/strtodI.c +++ b/gdtoa/strtodI.c @@ -33,16 +33,16 @@ THIS SOFTWARE. static double #ifdef KR_headers -ulpdown(d) double *d; +ulpdown(d) U *d; #else -ulpdown(double *d) +ulpdown(U *d) #endif { double u; - ULong *L = (ULong*)d; + ULong *L = d->L; - u = ulp(*d); - if (!(L[_1] | L[_0] & 0xfffff) + u = ulp(d); + if (!(L[_1] | (L[_0] & 0xfffff)) && (L[_0] & 0x7ff00000) > 0x00100000) u *= 0.5; return u; @@ -55,14 +55,10 @@ strtodI(s, sp, dd) CONST char *s; char **sp; double *dd; strtodI(CONST char *s, char **sp, double *dd) #endif { - static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2], sign; Long exp; int j, k; - typedef union { - double d[2]; - ULong L[4]; - } U; U *u; k = strtodg(s, sp, &fpi, &exp, bits); @@ -70,17 +66,17 @@ strtodI(CONST char *s, char **sp, double *dd) sign = k & STRTOG_Neg ? 0x80000000L : 0; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: - u->d[0] = u->d[1] = 0.; + dval(&u[0]) = dval(&u[1]) = 0.; break; case STRTOG_Zero: - u->d[0] = u->d[1] = 0.; + dval(&u[0]) = dval(&u[1]) = 0.; #ifdef Sudden_Underflow if (k & STRTOG_Inexact) { if (sign) - u->L[_0] = 0x80100000L; + word0(&u[0]) = 0x80100000L; else - u->L[2+_0] = 0x100000L; + word0(&u[1]) = 0x100000L; } break; #else @@ -88,80 +84,80 @@ strtodI(CONST char *s, char **sp, double *dd) #endif case STRTOG_Denormal: - u->L[_1] = bits[0]; - u->L[_0] = bits[1]; + word1(&u[0]) = bits[0]; + word0(&u[0]) = bits[1]; goto contain; case STRTOG_Normal: - u->L[_1] = bits[0]; - u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + word1(&u[0]) = bits[0]; + word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); contain: j = k & STRTOG_Inexact; if (sign) { - u->L[_0] |= sign; + word0(&u[0]) |= sign; j = STRTOG_Inexact - j; } switch(j) { case STRTOG_Inexlo: #ifdef Sudden_Underflow if ((u->L[_0] & 0x7ff00000) < 0x3500000) { - u->L[2+_0] = u->L[_0] + 0x3500000; - u->L[2+_1] = u->L[_1]; - u->d[1] += ulp(u->d[1]); - u->L[2+_0] -= 0x3500000; - if (!(u->L[2+_0] & 0x7ff00000)) { - u->L[2+_0] = sign; - u->L[2+_1] = 0; + word0(&u[1]) = word0(&u[0]) + 0x3500000; + word1(&u[1]) = word1(&u[0]); + dval(&u[1]) += ulp(&u[1]); + word0(&u[1]) -= 0x3500000; + if (!(word0(&u[1]) & 0x7ff00000)) { + word0(&u[1]) = sign; + word1(&u[1]) = 0; } } else #endif - u->d[1] = u->d[0] + ulp(u->d[0]); + dval(&u[1]) = dval(&u[0]) + ulp(&u[0]); break; case STRTOG_Inexhi: - u->d[1] = u->d[0]; + dval(&u[1]) = dval(&u[0]); #ifdef Sudden_Underflow - if ((u->L[_0] & 0x7ff00000) < 0x3500000) { - u->L[_0] += 0x3500000; - u->d[0] -= ulpdown(u->d); - u->L[_0] -= 0x3500000; - if (!(u->L[_0] & 0x7ff00000)) { - u->L[_0] = sign; - u->L[_1] = 0; + if ((word0(&u[0]) & 0x7ff00000) < 0x3500000) { + word0(&u[0]) += 0x3500000; + dval(&u[0]) -= ulpdown(u); + word0(&u[0]) -= 0x3500000; + if (!(word0(&u[0]) & 0x7ff00000)) { + word0(&u[0]) = sign; + word1(&u[0]) = 0; } } else #endif - u->d[0] -= ulpdown(u->d); + dval(&u[0]) -= ulpdown(u); break; default: - u->d[1] = u->d[0]; + dval(&u[1]) = dval(&u[0]); } break; case STRTOG_Infinite: - u->L[_0] = u->L[2+_0] = sign | 0x7ff00000; - u->L[_1] = u->L[2+_1] = 0; + word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000; + word1(&u[0]) = word1(&u[1]) = 0; if (k & STRTOG_Inexact) { if (sign) { - u->L[2+_0] = 0xffefffffL; - u->L[2+_1] = 0xffffffffL; + word0(&u[1]) = 0xffefffffL; + word1(&u[1]) = 0xffffffffL; } else { - u->L[_0] = 0x7fefffffL; - u->L[_1] = 0xffffffffL; + word0(&u[0]) = 0x7fefffffL; + word1(&u[0]) = 0xffffffffL; } } break; case STRTOG_NaN: - u->L[0] = u->L[2] = d_QNAN0; - u->L[1] = u->L[3] = d_QNAN1; + u->L[0] = (u+1)->L[0] = d_QNAN0; + u->L[1] = (u+1)->L[1] = d_QNAN1; break; case STRTOG_NaNbits: - u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1]; - u->L[_1] = u->L[2+_1] = bits[0]; + word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1]; + word1(&u[0]) = word1(&u[1]) = bits[0]; } return k; } diff --git a/gdtoa/strtodg.c b/gdtoa/strtodg.c index 2d154148d..c2e3365c7 100644 --- a/gdtoa/strtodg.c +++ b/gdtoa/strtodg.c @@ -89,7 +89,7 @@ increment(Bigint *b) return b; } - int + void #ifdef KR_headers decrement(b) Bigint *b; #else @@ -119,7 +119,6 @@ decrement(Bigint *b) *x++ = y & 0xffff; } while(borrow && x < xe); #endif - return STRTOG_Inexlo; } static int @@ -173,9 +172,9 @@ set_ones(Bigint *b, int n) rvOK #ifdef KR_headers (d, fpi, exp, bits, exact, rd, irv) - double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; + U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; #else - (double d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) + (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) #endif { Bigint *b; @@ -183,7 +182,7 @@ rvOK int bdif, e, j, k, k1, nb, rv; carry = rv = 0; - b = d2b(d, &e, &bdif); + b = d2b(dval(d), &e, &bdif); bdif -= nb = fpi->nbits; e += bdif; if (bdif <= 0) { @@ -206,9 +205,9 @@ rvOK goto ret; } switch(rd) { - case 1: + case 1: /* round down (toward -Infinity) */ goto trunc; - case 2: + case 2: /* round up (toward +Infinity) */ break; default: /* round near */ k = bdif - 1; @@ -292,15 +291,12 @@ rvOK static int #ifdef KR_headers -mantbits(d) double d; +mantbits(d) U *d; #else -mantbits(double _d) +mantbits(U *d) #endif { ULong L; - U d; - - dval(d) = _d; #ifdef VAX L = word1(d) << 16 | word1(d) >> 16; if (L) @@ -322,7 +318,7 @@ strtodg (s00, se, fpi, exp, bits) CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; #else - (CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits) + (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) #endif { int abe, abits, asub; @@ -332,14 +328,35 @@ strtodg int sudden_underflow; CONST char *s, *s0, *s1; double adj0, tol; - U adj, rv; Long L; - ULong y, z; + U adj, rv; + ULong *b, *be, y, z; Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; +#ifdef USE_LOCALE /*{{*/ +#ifdef NO_LOCALE_CACHE + char *decimalpoint = localeconv()->decimal_point; + int dplen = strlen(decimalpoint); +#else + char *decimalpoint; + static char *decimalpoint_cache; + static int dplen; + if (!(s0 = decimalpoint_cache)) { + s0 = localeconv()->decimal_point; + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + dplen = strlen(s0); + } + decimalpoint = (char*)s0; +#endif /*NO_LOCALE_CACHE*/ +#else /*USE_LOCALE}{*/ +#define dplen 1 +#endif /*USE_LOCALE}}*/ irv = STRTOG_Zero; denorm = sign = nz0 = nz = 0; - dval(rv) = 0.; + dval(&rv) = 0.; rvb = 0; nbits = fpi->nbits; for(s = s00;;s++) switch(*s) { @@ -394,13 +411,17 @@ strtodg z = 10*z + c - '0'; nd0 = nd; #ifdef USE_LOCALE - if (c == *localeconv()->decimal_point) + if (c == *decimalpoint) { + for(i = 1; decimalpoint[i]; ++i) + if (s[i] != decimalpoint[i]) + goto dig_done; + s += i; + c = *s; #else - if (c == '.') -#endif - { - decpt = 1; + if (c == '.') { c = *++s; +#endif + decpt = 1; if (!nd) { for(; c == '0'; c = *++s) nz++; @@ -429,7 +450,7 @@ strtodg nz = 0; } } - } + }/*}*/ dig_done: e = 0; if (c == 'e' || c == 'E') { @@ -527,13 +548,13 @@ strtodg if (!nd0) nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; + dval(&rv) = y; if (k > 9) - dval(rv) = tens[k - 9] * dval(rv) + z; + dval(&rv) = tens[k - 9] * dval(&rv) + z; bd0 = 0; if (nbits <= P && nd <= DBL_DIG) { if (!e) { - if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv)) goto ret; } else if (e > 0) { @@ -541,9 +562,9 @@ strtodg #ifdef VAX goto vax_ovfl_check; #else - i = fivesbits[e] + mantbits(dval(rv)) <= P; - /* rv = */ rounded_product(dval(rv), tens[e]); - if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + i = fivesbits[e] + mantbits(&rv) <= P; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if (rvOK(&rv, fpi, exp, bits, i, rd, &irv)) goto ret; e1 -= e; goto rv_notOK; @@ -556,32 +577,32 @@ strtodg */ e2 = e - i; e1 -= i; - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; #ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here... */ vax_ovfl_check: - dval(adj) = dval(rv); - word0(adj) -= P*Exp_msk1; - /* adj = */ rounded_product(dval(adj), tens[e2]); - if ((word0(adj) & Exp_mask) + dval(&adj) = dval(&rv); + word0(&adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(&adj), tens[e2]); + if ((word0(&adj) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) goto rv_notOK; - word0(adj) += P*Exp_msk1; - dval(rv) = dval(adj); + word0(&adj) += P*Exp_msk1; + dval(&rv) = dval(&adj); #else - /* rv = */ rounded_product(dval(rv), tens[e2]); + /* rv = */ rounded_product(dval(&rv), tens[e2]); #endif - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e2; } } #ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv)) goto ret; e1 -= e; } @@ -595,45 +616,45 @@ strtodg e2 = 0; if (e1 > 0) { if ( (i = e1 & 15) !=0) - dval(rv) *= tens[i]; + dval(&rv) *= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= bigtens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= bigtens[j]; + dval(&rv) *= bigtens[j]; } } else if (e1 < 0) { e1 = -e1; if ( (i = e1 & 15) !=0) - dval(rv) /= tens[i]; + dval(&rv) /= tens[i]; if (e1 &= ~15) { e1 >>= 4; - while(e1 >= (1 << n_bigtens-1)) { - e2 += ((word0(rv) & Exp_mask) + while(e1 >= (1 << (n_bigtens-1))) { + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; - dval(rv) *= tinytens[n_bigtens-1]; - e1 -= 1 << n_bigtens-1; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; + dval(&rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << (n_bigtens-1); } - e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; - word0(rv) &= ~Exp_mask; - word0(rv) |= Bias << Exp_shift1; + e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(&rv) &= ~Exp_mask; + word0(&rv) |= Bias << Exp_shift1; for(j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) - dval(rv) *= tinytens[j]; + dval(&rv) *= tinytens[j]; } } #ifdef IBM @@ -644,7 +665,7 @@ strtodg */ e2 <<= 2; #endif - rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */ rve += e2; if ((j = rvbits - nbits) > 0) { rshift(rvb, j); @@ -688,7 +709,7 @@ strtodg /* Put digits into bd: true value = bd * 10^e */ - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd, y, dplen); for(;;) { bd = Balloc(bd0->k); @@ -822,7 +843,7 @@ strtodg } else irv = STRTOG_Normal | STRTOG_Inexhi; - if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1)) break; if (dsign) { rvb = increment(rvb); @@ -839,7 +860,7 @@ strtodg } break; } - if ((dval(adj) = ratio(delta, bs)) <= 2.) { + if ((dval(&adj) = ratio(delta, bs)) <= 2.) { adj1: inex = STRTOG_Inexlo; if (dsign) { @@ -853,15 +874,15 @@ strtodg irv = STRTOG_Underflow | STRTOG_Inexlo; break; } - adj0 = dval(adj) = 1.; + adj0 = dval(&adj) = 1.; } else { - adj0 = dval(adj) *= 0.5; + adj0 = dval(&adj) *= 0.5; if (dsign) { asub = 0; inex = STRTOG_Inexlo; } - if (dval(adj) < 2147483647.) { + if (dval(&adj) < 2147483647.) { L = (Long)adj0; adj0 -= L; switch(rd) { @@ -880,12 +901,12 @@ strtodg inex = STRTOG_Inexact - inex; } } - dval(adj) = L; + dval(&adj) = L; } } y = rve + rvbits; - /* adj *= ulp(dval(rv)); */ + /* adj *= ulp(dval(&rv)); */ /* if (asub) rv -= adj; else rv += adj; */ if (!denorm && rvbits < nbits) { @@ -893,7 +914,7 @@ strtodg rve -= j; rvbits = nbits; } - ab = d2b(dval(adj), &abe, &abits); + ab = d2b(dval(&adj), &abe, &abits); if (abe < 0) rshift(ab, -abe); else if (abe > 0) @@ -947,15 +968,15 @@ strtodg z = rve + rvbits; if (y == z && L) { /* Can we stop now? */ - tol = dval(adj) * 5e-16; /* > max rel error */ - dval(adj) = adj0 - .5; - if (dval(adj) < -tol) { + tol = dval(&adj) * 5e-16; /* > max rel error */ + dval(&adj) = adj0 - .5; + if (dval(&adj) < -tol) { if (adj0 > tol) { irv |= inex; break; } } - else if (dval(adj) > tol && adj0 < 1. - tol) { + else if (dval(&adj) > tol && adj0 < 1. - tol) { irv |= inex; break; } @@ -980,6 +1001,29 @@ strtodg Bfree(bd0); Bfree(delta); if (rve > fpi->emax) { + switch(fpi->rounding & 3) { + case FPI_Round_near: + goto huge; + case FPI_Round_up: + if (!sign) + goto huge; + break; + case FPI_Round_down: + if (sign) + goto huge; + } + /* Round to largest representable magnitude */ + Bfree(rvb); + rvb = 0; + irv = STRTOG_Normal | STRTOG_Inexlo; + *exp = fpi->emax; + b = bits; + be = b + ((fpi->nbits + 31) >> 5); + while(b < be) + *b++ = -1; + if ((j = fpi->nbits & 0x1f)) + *--be >>= (32 - j); + goto ret; huge: rvb->wds = 0; irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; @@ -994,12 +1038,19 @@ strtodg if (sudden_underflow) { rvb->wds = 0; irv = STRTOG_Underflow | STRTOG_Inexlo; +#ifndef NO_ERRNO + errno = ERANGE; +#endif } else { irv = (irv & ~STRTOG_Retmask) | (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); - if (irv & STRTOG_Inexact) + if (irv & STRTOG_Inexact) { irv |= STRTOG_Underflow; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + } } } if (se) diff --git a/gdtoa/strtodnrp.c b/gdtoa/strtodnrp.c index 3d0297f52..19a769f0b 100644 --- a/gdtoa/strtodnrp.c +++ b/gdtoa/strtodnrp.c @@ -44,7 +44,7 @@ strtod(s, sp) CONST char *s; char **sp; strtod(CONST char *s, char **sp) #endif { - static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2]; Long exp; int k; diff --git a/gdtoa/strtof.c b/gdtoa/strtof.c index 561264a1d..a8beb3520 100644 --- a/gdtoa/strtof.c +++ b/gdtoa/strtof.c @@ -38,13 +38,18 @@ strtof(s, sp) CONST char *s; char **sp; strtof(CONST char *s, char **sp) #endif { - static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1]; Long exp; int k; union { ULong L[1]; float f; } u; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: @@ -53,7 +58,7 @@ strtof(CONST char *s, char **sp) case STRTOG_Normal: case STRTOG_NaNbits: - u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: diff --git a/gdtoa/strtopQ.c b/gdtoa/strtopQ.c index 9eefd768f..2acf7e910 100644 --- a/gdtoa/strtopQ.c +++ b/gdtoa/strtopQ.c @@ -49,6 +49,9 @@ THIS SOFTWARE. #define _3 0 #endif + extern ULong NanDflt_Q_D2A[4]; + + int #ifdef KR_headers strtopQ(s, sp, V) CONST char *s; char **sp; void *V; @@ -56,13 +59,18 @@ strtopQ(s, sp, V) CONST char *s; char **sp; void *V; strtopQ(CONST char *s, char **sp, void *V) #endif { - static CONST FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; + static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; ULong bits[4]; Long exp; int k; ULong *L = (ULong*)V; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: @@ -90,10 +98,10 @@ strtopQ(CONST char *s, char **sp, void *V) break; case STRTOG_NaN: - L[0] = ld_QNAN0; - L[1] = ld_QNAN1; - L[2] = ld_QNAN2; - L[3] = ld_QNAN3; + L[_0] = NanDflt_Q_D2A[3]; + L[_1] = NanDflt_Q_D2A[2]; + L[_2] = NanDflt_Q_D2A[1]; + L[_3] = NanDflt_Q_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; diff --git a/gdtoa/strtopd.c b/gdtoa/strtopd.c index 4c8bbaf42..0fb35daea 100644 --- a/gdtoa/strtopd.c +++ b/gdtoa/strtopd.c @@ -38,12 +38,17 @@ strtopd(s, sp, d) char *s; char **sp; double *d; strtopd(CONST char *s, char **sp, double *d) #endif { - static CONST FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2]; Long exp; int k; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi0, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); ULtod((ULong*)d, bits, exp, k); return k; } diff --git a/gdtoa/strtopdd.c b/gdtoa/strtopdd.c index d2c6d9b89..738372d88 100644 --- a/gdtoa/strtopdd.c +++ b/gdtoa/strtopdd.c @@ -39,9 +39,9 @@ strtopdd(CONST char *s, char **sp, double *dd) #endif { #ifdef Sudden_Underflow - static CONST FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; + static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; #else - static CONST FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; + static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; #endif ULong bits[4]; Long exp; @@ -51,8 +51,13 @@ strtopdd(CONST char *s, char **sp, double *dd) ULong L[4]; } U; U *u; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - rv = strtodg(s, sp, &fpi, &exp, bits); + rv = strtodg(s, sp, fpi, &exp, bits); u = (U*)dd; switch(rv & STRTOG_Retmask) { case STRTOG_NoNumber: @@ -62,8 +67,8 @@ strtopdd(CONST char *s, char **sp, double *dd) case STRTOG_Normal: u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; - u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff - | exp + 0x3ff + 105 << 20; + u->L[_0] = (bits[2] >> 21) | ((bits[3] << 11) & 0xfffff) + | ((exp + 0x3ff + 105) << 20); exp += 0x3ff + 52; if (bits[1] &= 0x1fffff) { i = hi0bits(bits[1]) - 11; @@ -74,7 +79,7 @@ strtopdd(CONST char *s, char **sp, double *dd) else exp -= i; if (i > 0) { - bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[1] = bits[1] << i | bits[0] >> (32-i); bits[0] = bits[0] << i & 0xffffffffL; } } @@ -87,11 +92,11 @@ strtopdd(CONST char *s, char **sp, double *dd) else exp -= i; if (i < 32) { - bits[1] = bits[0] >> 32 - i; + bits[1] = bits[0] >> (32 - i); bits[0] = bits[0] << i & 0xffffffffL; } else { - bits[1] = bits[0] << i - 32; + bits[1] = bits[0] << (i - 32); bits[0] = 0; } } @@ -100,7 +105,7 @@ strtopdd(CONST char *s, char **sp, double *dd) break; } u->L[2+_1] = bits[0]; - u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); break; case STRTOG_Denormal: @@ -119,10 +124,10 @@ strtopdd(CONST char *s, char **sp, double *dd) nearly_normal: i = hi0bits(bits[3]) - 11; /* i >= 12 */ j = 32 - i; - u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff - | 65 - i << 20; + u->L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) + | ((65 - i) << 20); u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; break; @@ -131,34 +136,34 @@ strtopdd(CONST char *s, char **sp, double *dd) if (i < 0) { j = -i; i += 32; - u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; - u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[_0] = (bits[2] >> j & 0xfffff) | (33 + j) << 20; + u->L[_1] = ((bits[2] << i) | (bits[1] >> j)) & 0xffffffffL; + u->L[2+_0] = bits[1] & ((1L << j) - 1); u->L[2+_1] = bits[0]; break; } if (i == 0) { - u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_0] = (bits[2] & 0xfffff) | (33 << 20); u->L[_1] = bits[1]; u->L[2+_0] = 0; u->L[2+_1] = bits[0]; break; } j = 32 - i; - u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff - | j + 1 << 20; + u->L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) + | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); break; hardly_normal: j = 11 - hi0bits(bits[1]); i = 32 - j; - u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; u->L[2+_0] = 0; - u->L[2+_1] = bits[0] & (1L << j) - 1; + u->L[2+_1] = bits[0] & ((1L << j) - 1); break; case STRTOG_Infinite: diff --git a/gdtoa/strtopf.c b/gdtoa/strtopf.c index 806e14f6f..23ca5cbe5 100644 --- a/gdtoa/strtopf.c +++ b/gdtoa/strtopf.c @@ -38,12 +38,17 @@ strtopf(s, sp, f) CONST char *s; char **sp; float *f; strtopf(CONST char *s, char **sp, float *f) #endif { - static CONST FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1], *L; Long exp; int k; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); L = (ULong*)f; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: @@ -53,7 +58,7 @@ strtopf(CONST char *s, char **sp, float *f) case STRTOG_Normal: case STRTOG_NaNbits: - L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: diff --git a/gdtoa/strtopx.c b/gdtoa/strtopx.c index ecd0b3991..32192c572 100644 --- a/gdtoa/strtopx.c +++ b/gdtoa/strtopx.c @@ -31,6 +31,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" + extern UShort NanDflt_ldus_D2A[5]; + #undef _0 #undef _1 @@ -58,13 +60,18 @@ strtopx(s, sp, V) CONST char *s; char **sp; void *V; strtopx(CONST char *s, char **sp, void *V) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ULong bits[2]; Long exp; int k; UShort *L = (UShort*)V; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: @@ -87,15 +94,16 @@ strtopx(CONST char *s, char **sp, void *V) case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = L[_2] = L[_3] = L[_4] = 0; + L[_1] = 0x8000; + L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: - L[0] = ldus_QNAN0; - L[1] = ldus_QNAN1; - L[2] = ldus_QNAN2; - L[3] = ldus_QNAN3; - L[4] = ldus_QNAN4; + L[_4] = NanDflt_ldus_D2A[0]; + L[_3] = NanDflt_ldus_D2A[1]; + L[_2] = NanDflt_ldus_D2A[2]; + L[_1] = NanDflt_ldus_D2A[3]; + L[_0] = NanDflt_ldus_D2A[4]; } if (k & STRTOG_Neg) L[_0] |= 0x8000; diff --git a/gdtoa/strtopxL.c b/gdtoa/strtopxL.c index 00810fa35..6166c1e62 100644 --- a/gdtoa/strtopxL.c +++ b/gdtoa/strtopxL.c @@ -31,6 +31,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" + extern ULong NanDflt_xL_D2A[3]; + #undef _0 #undef _1 @@ -54,13 +56,18 @@ strtopxL(s, sp, V) CONST char *s; char **sp; void *V; strtopxL(CONST char *s, char **sp, void *V) #endif { - static CONST FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; ULong bits[2]; Long exp; int k; ULong *L = (ULong*)V; +#ifdef Honor_FLT_ROUNDS +#include "gdtoa_fltrnds.h" +#else +#define fpi &fpi0 +#endif - k = strtodg(s, sp, &fpi, &exp, bits); + k = strtodg(s, sp, fpi, &exp, bits); switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: case STRTOG_Zero: @@ -77,13 +84,14 @@ strtopxL(CONST char *s, char **sp, void *V) case STRTOG_Infinite: L[_0] = 0x7fff << 16; - L[_1] = L[_2] = 0; + L[_1] = 0x80000000; + L[_2] = 0; break; case STRTOG_NaN: - L[0] = ld_QNAN0; - L[1] = ld_QNAN1; - L[2] = ld_QNAN2; + L[_0] = NanDflt_xL_D2A[2]; + L[_1] = NanDflt_xL_D2A[1]; + L[_2] = NanDflt_xL_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; diff --git a/gdtoa/strtorQ.c b/gdtoa/strtorQ.c index 1cb157890..f5fd7bba9 100644 --- a/gdtoa/strtorQ.c +++ b/gdtoa/strtorQ.c @@ -49,6 +49,8 @@ THIS SOFTWARE. #define _3 0 #endif + extern ULong NanDflt_Q_D2A[4]; + void #ifdef KR_headers ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; @@ -83,10 +85,10 @@ ULtoQ(ULong *L, ULong *bits, Long exp, int k) break; case STRTOG_NaN: - L[0] = ld_QNAN0; - L[1] = ld_QNAN1; - L[2] = ld_QNAN2; - L[3] = ld_QNAN3; + L[_0] = NanDflt_Q_D2A[3]; + L[_1] = NanDflt_Q_D2A[2]; + L[_2] = NanDflt_Q_D2A[1]; + L[_3] = NanDflt_Q_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; @@ -99,9 +101,8 @@ strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; strtorQ(CONST char *s, char **sp, int rounding, void *L) #endif { - static CONST FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; - CONST FPI *fpi; - FPI fpi1; + static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + FPI *fpi, fpi1; ULong bits[4]; Long exp; int k; diff --git a/gdtoa/strtord.c b/gdtoa/strtord.c index 1aa7aefe3..dd0769698 100644 --- a/gdtoa/strtord.c +++ b/gdtoa/strtord.c @@ -31,6 +31,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" + extern ULong NanDflt_d_D2A[2]; + void #ifdef KR_headers ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; @@ -61,8 +63,8 @@ ULtod(ULong *L, ULong *bits, Long exp, int k) break; case STRTOG_NaN: - L[0] = d_QNAN0; - L[1] = d_QNAN1; + L[_0] = NanDflt_d_D2A[1]; + L[_1] = NanDflt_d_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; @@ -75,9 +77,8 @@ strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d; strtord(CONST char *s, char **sp, int rounding, double *d) #endif { - static CONST FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; - CONST FPI *fpi; - FPI fpi1; + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + FPI *fpi, fpi1; ULong bits[2]; Long exp; int k; diff --git a/gdtoa/strtordd.c b/gdtoa/strtordd.c index 5b505f1b8..62152dbd4 100644 --- a/gdtoa/strtordd.c +++ b/gdtoa/strtordd.c @@ -31,6 +31,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" + extern ULong NanDflt_d_D2A[2]; + void #ifdef KR_headers ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; @@ -48,8 +50,8 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) case STRTOG_Normal: L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; - L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff - | exp + 0x3ff + 105 << 20; + L[_0] = (bits[2] >> 21) | (bits[3] << 11 & 0xfffff) + | ((exp + 0x3ff + 105) << 20); exp += 0x3ff + 52; if (bits[1] &= 0x1fffff) { i = hi0bits(bits[1]) - 11; @@ -60,7 +62,7 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) else exp -= i; if (i > 0) { - bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[1] = bits[1] << i | bits[0] >> (32-i); bits[0] = bits[0] << i & (ULong)0xffffffffL; } } @@ -73,11 +75,11 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) else exp -= i; if (i < 32) { - bits[1] = bits[0] >> 32 - i; + bits[1] = bits[0] >> (32 - i); bits[0] = bits[0] << i & (ULong)0xffffffffL; } else { - bits[1] = bits[0] << i - 32; + bits[1] = bits[0] << (i - 32); bits[0] = 0; } } @@ -86,7 +88,7 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) break; } L[2+_1] = bits[0]; - L[2+_0] = bits[1] & 0xfffff | exp << 20; + L[2+_0] = (bits[1] & 0xfffff) | (exp << 20); break; case STRTOG_Denormal: @@ -105,10 +107,10 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) nearly_normal: i = hi0bits(bits[3]) - 11; /* i >= 12 */ j = 32 - i; - L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff - | 65 - i << 20; + L[_0] = ((bits[3] << i | bits[2] >> j) & 0xfffff) + | ((65 - i) << 20); L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_0] = bits[1] & (((ULong)1L << j) - 1); L[2+_1] = bits[0]; break; @@ -117,34 +119,34 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) if (i < 0) { j = -i; i += 32; - L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + L[_0] = (bits[2] >> j & 0xfffff) | ((33 + j) << 20); L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; - L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_0] = bits[1] & (((ULong)1L << j) - 1); L[2+_1] = bits[0]; break; } if (i == 0) { - L[_0] = bits[2] & 0xfffff | 33 << 20; + L[_0] = (bits[2] & 0xfffff) | (33 << 20); L[_1] = bits[1]; L[2+_0] = 0; L[2+_1] = bits[0]; break; } j = 32 - i; - L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff - | j + 1 << 20; + L[_0] = (((bits[2] << i) | (bits[1] >> j)) & 0xfffff) + | ((j + 1) << 20); L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; L[2+_0] = 0; - L[2+_1] = bits[0] & (1L << j) - 1; + L[2+_1] = bits[0] & ((1L << j) - 1); break; hardly_normal: j = 11 - hi0bits(bits[1]); i = 32 - j; - L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + L[_0] = (bits[1] >> j & 0xfffff) | ((j + 1) << 20); L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; L[2+_0] = 0; - L[2+_1] = bits[0] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0] & (((ULong)1L << j) - 1); break; case STRTOG_Infinite: @@ -153,16 +155,17 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k) break; case STRTOG_NaN: - L[0] = L[2] = d_QNAN0; - L[1] = L[3] = d_QNAN1; + L[_0] = L[_0+2] = NanDflt_d_D2A[1]; + L[_1] = L[_1+2] = NanDflt_d_D2A[0]; break; case STRTOG_NaNbits: - L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; - L[_0] = bits[2] >> 21 | bits[3] << 11 - | (ULong)0x7ff00000L; - L[2+_1] = bits[0]; - L[2+_0] = bits[1] | (ULong)0x7ff00000L; + L[_1] = (bits[1] >> 20 | bits[2] << 12) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 20 | bits[3] << 12; + L[_0] |= (L[_1] | L[_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L; + L[2+_1] = bits[0] & (ULong)0xffffffffL; + L[2+_0] = bits[1] & 0xfffffL; + L[2+_0] |= (L[2+_1] | L[2+_0]) ? (ULong)0x7ff00000L : (ULong)0x7ff80000L; } if (k & STRTOG_Neg) { L[_0] |= 0x80000000L; @@ -178,12 +181,11 @@ strtordd(CONST char *s, char **sp, int rounding, double *dd) #endif { #ifdef Sudden_Underflow - static CONST FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; + static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; #else - static CONST FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; + static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; #endif - CONST FPI *fpi; - FPI fpi1; + FPI *fpi, fpi1; ULong bits[4]; Long exp; int k; diff --git a/gdtoa/strtorf.c b/gdtoa/strtorf.c index 3892d68d6..99b4ab710 100644 --- a/gdtoa/strtorf.c +++ b/gdtoa/strtorf.c @@ -31,6 +31,8 @@ THIS SOFTWARE. #include "gdtoaimp.h" + extern ULong NanDflt_f_D2A[1]; + void #ifdef KR_headers ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; @@ -46,7 +48,7 @@ ULtof(ULong *L, ULong *bits, Long exp, int k) case STRTOG_Normal: case STRTOG_NaNbits: - L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23); break; case STRTOG_Denormal: @@ -58,7 +60,7 @@ ULtof(ULong *L, ULong *bits, Long exp, int k) break; case STRTOG_NaN: - L[0] = f_QNAN; + L[0] = NanDflt_f_D2A[0]; } if (k & STRTOG_Neg) L[0] |= 0x80000000L; @@ -71,9 +73,8 @@ strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f; strtorf(CONST char *s, char **sp, int rounding, float *f) #endif { - static CONST FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; - CONST FPI *fpi; - FPI fpi1; + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + FPI *fpi, fpi1; ULong bits[1]; Long exp; int k; diff --git a/gdtoa/strtorx.c b/gdtoa/strtorx.c index cc3c0700f..994ce8e63 100644 --- a/gdtoa/strtorx.c +++ b/gdtoa/strtorx.c @@ -51,6 +51,8 @@ THIS SOFTWARE. #define _4 0 #endif + extern UShort NanDflt_ldus_D2A[5]; + void #ifdef KR_headers ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k; @@ -80,15 +82,16 @@ ULtox(UShort *L, ULong *bits, Long exp, int k) case STRTOG_Infinite: L[_0] = 0x7fff; - L[_1] = L[_2] = L[_3] = L[_4] = 0; + L[_1] = 0x8000; + L[_2] = L[_3] = L[_4] = 0; break; case STRTOG_NaN: - L[0] = ldus_QNAN0; - L[1] = ldus_QNAN1; - L[2] = ldus_QNAN2; - L[3] = ldus_QNAN3; - L[4] = ldus_QNAN4; + L[_4] = NanDflt_ldus_D2A[0]; + L[_3] = NanDflt_ldus_D2A[1]; + L[_2] = NanDflt_ldus_D2A[2]; + L[_1] = NanDflt_ldus_D2A[3]; + L[_0] = NanDflt_ldus_D2A[4]; } if (k & STRTOG_Neg) L[_0] |= 0x8000; @@ -101,9 +104,8 @@ strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; strtorx(CONST char *s, char **sp, int rounding, void *L) #endif { - static CONST FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; - CONST FPI *fpi; - FPI fpi1; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; ULong bits[2]; Long exp; int k; diff --git a/gdtoa/strtorxL.c b/gdtoa/strtorxL.c index ffcafa907..bac4a0bb1 100644 --- a/gdtoa/strtorxL.c +++ b/gdtoa/strtorxL.c @@ -47,6 +47,8 @@ THIS SOFTWARE. #define _2 0 #endif + extern ULong NanDflt_xL_D2A[3]; + void #ifdef KR_headers ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; @@ -69,14 +71,15 @@ ULtoxL(ULong *L, ULong *bits, Long exp, int k) break; case STRTOG_Infinite: - L[_0] = 0x7fff << 16; - L[_1] = L[_2] = 0; + L[_0] = 0x7fff0000; + L[_1] = 0x80000000; + L[_2] = 0; break; case STRTOG_NaN: - L[0] = ld_QNAN0; - L[1] = ld_QNAN1; - L[2] = ld_QNAN2; + L[_0] = NanDflt_xL_D2A[2]; + L[_1] = NanDflt_xL_D2A[1]; + L[_2] = NanDflt_xL_D2A[0]; } if (k & STRTOG_Neg) L[_0] |= 0x80000000L; @@ -89,9 +92,8 @@ strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; strtorxL(CONST char *s, char **sp, int rounding, void *L) #endif { - static CONST FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; - CONST FPI *fpi; - FPI fpi1; + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; ULong bits[2]; Long exp; int k; diff --git a/gdtoa/ulp.c b/gdtoa/ulp.c index 27639d19e..17e9f862c 100644 --- a/gdtoa/ulp.c +++ b/gdtoa/ulp.c @@ -34,15 +34,14 @@ THIS SOFTWARE. double ulp #ifdef KR_headers - (x) double x; + (x) U *x; #else - (double _x) + (U *x) #endif { Long L; - U x, a; + U a; - dval(x) = _x; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Sudden_Underflow if (L > 0) { @@ -50,22 +49,22 @@ ulp #ifdef IBM L |= Exp_msk1 >> 4; #endif - word0(a) = L; - word1(a) = 0; + word0(&a) = L; + word1(&a) = 0; #ifndef Sudden_Underflow } else { L = -L >> Exp_shift; if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; + word0(&a) = 0x80000 >> L; + word1(&a) = 0; } else { - word0(a) = 0; + word0(&a) = 0; L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; + word1(&a) = L >= 31 ? 1 : 1 << (31 - L); } } #endif - return dval(a); + return dval(&a); } From b3f5de356f14e2026cc9e5738e8b58e22e7daa44 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 5 Jan 2014 15:46:11 -0500 Subject: [PATCH 083/311] - Fixed: SBarInfo's gamemode command used to ignore unknowns (for cross compatibility). On top of restoring the old behavior, generate a warning for only the first ignored instance. --- src/g_shared/sbarinfo_commands.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index febf32b80..5a0718f18 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -1639,10 +1639,20 @@ class CommandGameMode : public SBarInfoCommandFlowControl void Parse(FScanner &sc, bool fullScreenOffsets) { + static bool warnUnknown = true; do { sc.MustGetToken(TK_Identifier); - modes |= static_cast (1<= 0) + modes |= static_cast (1< Date: Sun, 5 Jan 2014 19:50:09 -0500 Subject: [PATCH 084/311] =?UTF-8?q?-=20Fixed:=20All=20clang=205.0=20warnin?= =?UTF-8?q?gs.=20-=20Renamed=20autostart/autozend=20since=20Xcode=E2=80=99?= =?UTF-8?q?s=20build=20process=20links=20in=20strictly=20alphabetical=20or?= =?UTF-8?q?der.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jpeg-6b/CMakeLists.txt | 2 +- src/CMakeLists.txt | 8 +++--- src/{autostart.cpp => __autostart.cpp} | 0 src/c_console.cpp | 2 -- src/files.cpp | 4 +-- src/fragglescript/t_fspic.cpp | 1 + src/g_shared/sbarinfo.cpp | 2 ++ src/menu/joystickmenu.cpp | 12 ++++----- src/menu/menu.h | 1 - src/menu/optionmenu.cpp | 5 ---- src/menu/optionmenuitems.h | 22 ++++++++--------- src/nodebuild.cpp | 4 --- src/oplsynth/music_opldumper_mididevice.cpp | 2 +- src/oplsynth/muslib.h | 2 +- src/oplsynth/opl.h | 1 - src/p_acs.cpp | 6 ++++- src/p_interaction.cpp | 2 -- src/p_sectors.cpp | 2 -- src/r_main.cpp | 4 --- src/r_plane.cpp | 2 +- src/sdl/crashcatcher.c | 2 +- src/sdl/i_system.cpp | 2 +- src/sdl/iwadpicker_cocoa.mm | 27 ++++++++++++--------- src/sound/i_musicinterns.h | 2 +- src/sound/music_mus_opl.cpp | 2 +- src/v_video.cpp | 2 +- src/v_video.h | 5 ++-- src/win32/fb_d3d9.cpp | 5 ---- src/win32/fb_ddraw.cpp | 5 ---- src/win32/win32iface.h | 2 -- src/{autozend.cpp => zzautozend.cpp} | 0 31 files changed, 57 insertions(+), 81 deletions(-) rename src/{autostart.cpp => __autostart.cpp} (100%) rename src/{autozend.cpp => zzautozend.cpp} (100%) diff --git a/jpeg-6b/CMakeLists.txt b/jpeg-6b/CMakeLists.txt index 21096465e..dd5055f9b 100644 --- a/jpeg-6b/CMakeLists.txt +++ b/jpeg-6b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required( VERSION 2.4 ) make_release_only() if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) add_library( jpeg diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2bf5a5a8c..4f27c70e2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -412,7 +412,7 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE set( CMAKE_CXX_FLAGS_MINSIZEREL "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_MINSIZEREL}" ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" ) - set( CMAKE_CXX_FLAGS "-Wall -Wno-unused -Wextra -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS}" ) + set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS}" ) # Remove extra warnings when using the official DirectX headers. # Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, @@ -748,7 +748,7 @@ set( NOT_COMPILED_SOURCE_FILES add_executable( zdoom WIN32 ${HEADER_FILES} ${NOT_COMPILED_SOURCE_FILES} - autostart.cpp + __autostart.cpp ${ASM_SOURCES} ${SYSTEM_SOURCES} ${X86_SOURCES} @@ -1052,7 +1052,7 @@ add_executable( zdoom WIN32 r_data/renderstyle.cpp r_data/r_interpolate.cpp r_data/r_translate.cpp - autozend.cpp + zzautozend.cpp ) set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) @@ -1160,7 +1160,7 @@ source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sdl/.+") -source_group("SFML" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+") +source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+") source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+") source_group("Versioning" FILES version.h win32/zdoom.rc) source_group("Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+") diff --git a/src/autostart.cpp b/src/__autostart.cpp similarity index 100% rename from src/autostart.cpp rename to src/__autostart.cpp diff --git a/src/c_console.cpp b/src/c_console.cpp index 0c02d0489..c25a460fe 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -610,8 +610,6 @@ static int FlushLines (const char *start, const char *stop) break; } } - if (i != TopLine) - i = i; return i; } diff --git a/src/files.cpp b/src/files.cpp index 80f0f8303..d7dfc2cbe 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -370,8 +370,8 @@ extern "C" void bz_internal_error (int errcode) // //========================================================================== -static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } -static void SzFree(void *p, void *address) { p = p; free(address); } +static void *SzAlloc(void *, size_t size) { return malloc(size); } +static void SzFree(void *, void *address) { free(address); } ISzAlloc g_Alloc = { SzAlloc, SzFree }; FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip) diff --git a/src/fragglescript/t_fspic.cpp b/src/fragglescript/t_fspic.cpp index d5e6e5aec..9da3cf15c 100644 --- a/src/fragglescript/t_fspic.cpp +++ b/src/fragglescript/t_fspic.cpp @@ -73,6 +73,7 @@ public: ~DHUDPicManager() {} void Serialize(FArchive & ar); virtual void DoDraw (int linenum, int x, int y, int hudheight, float translucent); + void DoDraw (int, int, int, bool, int) { assert(false); } } ; IMPLEMENT_CLASS(DHUDPicManager) diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 3e1c364e2..a738a5aad 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -303,6 +303,8 @@ class SBarInfoMainBlock : public SBarInfoCommandFlowControl int Alpha() const { return currentAlpha; } // Same as Draw but takes into account ForceScaled and temporarily sets the scaling if needed. void DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statusBar, int xOffset, int yOffset, int alpha); + // Silence hidden overload warning since this is a special use class. + using SBarInfoCommandFlowControl::Draw; void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, int xOffset, int yOffset, int alpha) { this->xOffset = xOffset; diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 6be728865..a7d950ed5 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -74,12 +74,12 @@ public: { } - double GetValue() + double GetSliderValue() { return SELECTED_JOYSTICK->GetSensitivity(); } - void SetValue(double val) + void SetSliderValue(double val) { SELECTED_JOYSTICK->SetSensitivity(float(val)); } @@ -104,14 +104,14 @@ public: mNeg = 1; } - double GetValue() + double GetSliderValue() { double d = SELECTED_JOYSTICK->GetAxisScale(mAxis); mNeg = d < 0? -1:1; return d; } - void SetValue(double val) + void SetSliderValue(double val) { SELECTED_JOYSTICK->SetAxisScale(mAxis, float(val * mNeg)); } @@ -136,14 +136,14 @@ public: mNeg = 1; } - double GetValue() + double GetSliderValue() { double d = SELECTED_JOYSTICK->GetAxisDeadZone(mAxis); mNeg = d < 0? -1:1; return d; } - void SetValue(double val) + void SetSliderValue(double val) { SELECTED_JOYSTICK->SetAxisDeadZone(mAxis, float(val * mNeg)); } diff --git a/src/menu/menu.h b/src/menu/menu.h index 1388a33bb..3712c9065 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -553,7 +553,6 @@ public: } ~FOptionMenuItem(); - virtual bool CheckCoordinate(FOptionMenuDescriptor *desc, int x, int y); virtual int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected); virtual bool Selectable(); virtual int GetIndent(); diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 08489fe23..eff53fc49 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -468,11 +468,6 @@ FOptionMenuItem::~FOptionMenuItem() if (mLabel != NULL) delete [] mLabel; } -bool FOptionMenuItem::CheckCoordinate(FOptionMenuDescriptor *desc, int x, int y) -{ - return false; -} - int FOptionMenuItem::Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) { return indent; diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index ff3eb016a..439ed7ffc 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -560,8 +560,8 @@ public: mSliderShort = 0; } - virtual double GetValue() = 0; - virtual void SetValue(double val) = 0; + virtual double GetSliderValue() = 0; + virtual void SetSliderValue(double val) = 0; //============================================================================= // @@ -614,14 +614,14 @@ public: { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); mDrawX = indent + CURSORSPACE; - DrawSlider (mDrawX, y, mMin, mMax, GetValue(), mShowValue, indent); + DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent); return indent; } //============================================================================= bool MenuEvent (int mkey, bool fromcontroller) { - double value = GetValue(); + double value = GetSliderValue(); if (mkey == MKEY_Left) { @@ -635,7 +635,7 @@ public: { return FOptionMenuItem::MenuEvent(mkey, fromcontroller); } - SetValue(clamp(value, mMin, mMax)); + SetSliderValue(clamp(value, mMin, mMax)); S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); return true; } @@ -662,9 +662,9 @@ public: x = clamp(x, slide_left, slide_right); double v = mMin + ((x - slide_left) * (mMax - mMin)) / (slide_right - slide_left); - if (v != GetValue()) + if (v != GetSliderValue()) { - SetValue(v); + SetSliderValue(v); //S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); } if (type == DMenu::MOUSE_Click) @@ -692,7 +692,7 @@ public: mCVar = FindCVar(menu, NULL); } - double GetValue() + double GetSliderValue() { if (mCVar != NULL) { @@ -704,7 +704,7 @@ public: } } - void SetValue(double val) + void SetSliderValue(double val) { if (mCVar != NULL) { @@ -732,12 +732,12 @@ public: mPVal = pVal; } - double GetValue() + double GetSliderValue() { return *mPVal; } - void SetValue(double val) + void SetSliderValue(double val) { *mPVal = (float)val; } diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index c13527d87..be5d0591d 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -504,10 +504,6 @@ int FNodeBuilder::SelectSplitter (DWORD set, node_t &node, DWORD &splitseg, int nosplitters = true; } } - else - { - pseg = pseg; - } } seg = pseg->next; diff --git a/src/oplsynth/music_opldumper_mididevice.cpp b/src/oplsynth/music_opldumper_mididevice.cpp index 0bb9ac14d..74bef0677 100644 --- a/src/oplsynth/music_opldumper_mididevice.cpp +++ b/src/oplsynth/music_opldumper_mididevice.cpp @@ -139,7 +139,7 @@ DiskWriterIO::~DiskWriterIO() // //========================================================================== -int DiskWriterIO::OPLinit(uint numchips, bool dontcare) +int DiskWriterIO::OPLinit(uint numchips, bool, bool) { // If the file extension is unknown or not present, the default format // is RAW. Otherwise, you can use DRO. diff --git a/src/oplsynth/muslib.h b/src/oplsynth/muslib.h index 404ce1e63..6cfb5bd55 100644 --- a/src/oplsynth/muslib.h +++ b/src/oplsynth/muslib.h @@ -195,7 +195,7 @@ struct DiskWriterIO : public OPLio DiskWriterIO(const char *filename); ~DiskWriterIO(); - int OPLinit(uint numchips, bool notused=false); + int OPLinit(uint numchips, bool notused=false, bool notused2=false); void OPLdeinit(); void OPLwriteReg(int which, uint reg, uchar data); void SetClockRate(double samples_per_tick); diff --git a/src/oplsynth/opl.h b/src/oplsynth/opl.h index eb46c9955..661258a26 100644 --- a/src/oplsynth/opl.h +++ b/src/oplsynth/opl.h @@ -15,7 +15,6 @@ public: virtual void WriteReg(int reg, int v) = 0; virtual void Update(float *buffer, int length) = 0; virtual void SetPanning(int c, float left, float right) = 0; - virtual FString GetVoiceString() { return FString(); } }; OPLEmul *YM3812Create(bool stereo); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fa9e6d9c9..fd168f9ba 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6807,12 +6807,16 @@ scriptwait: break; case PCD_PRINTBINARY: -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))) +#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6)))) || defined(__clang__) #define HAS_DIAGNOSTIC_PRAGMA #endif #ifdef HAS_DIAGNOSTIC_PRAGMA #pragma GCC diagnostic push +#ifdef __clang__ +#pragma GCC diagnostic ignored "-Wformat-invalid-specifier" +#else #pragma GCC diagnostic ignored "-Wformat=" +#endif #pragma GCC diagnostic ignored "-Wformat-extra-args" #endif work.AppendFormat ("%B", STACK(1)); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 47ed87888..4be8ed627 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -364,8 +364,6 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) { static int dieticks[MAXPLAYERS]; int pnum = int(this->player-players); - if (dieticks[pnum] == gametic) - gametic=gametic; dieticks[pnum] = gametic; fprintf (debugfile, "died (%d) on tic %d (%s)\n", pnum, gametic, this->player->cheats&CF_PREDICTING?"predicting":"real"); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index d90466fec..699350839 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -230,8 +230,6 @@ fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const check = lines[i]; if (NULL != (other = getNextSector (check, this))) { - if (other - sectors == 6) - other = other; ofloor = other->floorplane.ZatPoint (check->v1); floor = floorplane.ZatPoint (check->v1); if (ofloor < floor && floor - ofloor < heightdiff && !IsLinked(other, false)) diff --git a/src/r_main.cpp b/src/r_main.cpp index edb13d326..a726bc714 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -706,10 +706,6 @@ void R_EnterMirror (drawseg_t *ds, int depth) R_EnterMirror (drawsegs + WallMirrors[mirrorsAtStart], depth + 1); } } - else - { - depth = depth; - } viewangle = startang; viewx = startx; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 986d99203..07bbbbe6a 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -560,7 +560,7 @@ static visplane_t *new_visplane (unsigned hash) { check = (visplane_t *)M_Malloc (sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); memset(check, 0, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); - check->bottom = &check->top[MAXWIDTH+2]; + check->bottom = check->top + MAXWIDTH+2; } else if (NULL == (freetail = freetail->next)) { diff --git a/src/sdl/crashcatcher.c b/src/sdl/crashcatcher.c index 37511f63a..a4f68d9a3 100644 --- a/src/sdl/crashcatcher.c +++ b/src/sdl/crashcatcher.c @@ -192,7 +192,7 @@ static size_t safe_write(int fd, const void *buf, size_t len) static void crash_catcher(int signum, siginfo_t *siginfo, void *context) { - ucontext_t *ucontext = (ucontext_t*)context; + //ucontext_t *ucontext = (ucontext_t*)context; pid_t dbg_pid; int fd[2]; diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 03cbd74bf..6bd95d6e7 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -719,7 +719,7 @@ bool I_WriteIniFailed () static const char *pattern; -#if defined(__APPLE__) && !defined(__llvm__) +#if defined(__APPLE__) && !defined(__MAC_10_8) static int matchfile (struct dirent *ent) #else static int matchfile (const struct dirent *ent) diff --git a/src/sdl/iwadpicker_cocoa.mm b/src/sdl/iwadpicker_cocoa.mm index a0469ac7a..06f84098a 100644 --- a/src/sdl/iwadpicker_cocoa.mm +++ b/src/sdl/iwadpicker_cocoa.mm @@ -48,13 +48,16 @@ enum static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; // Class to convert the IWAD data into a form that Cocoa can use. -@interface IWADTableData : NSObject// +@interface IWADTableData : NSObject +#ifdef __MAC_10_6 + +#endif { NSMutableArray *data; } - (void)dealloc; -- (IWADTableData *)init:(WadStuff *) wads:(int) numwads; +- (IWADTableData *)init:(WadStuff *) wads num:(int) numwads; - (int)numberOfRowsInTableView:(NSTableView *)aTableView; - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; @@ -69,7 +72,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [super dealloc]; } -- (IWADTableData *)init:(WadStuff *) wads:(int) numwads +- (IWADTableData *)init:(WadStuff *) wads num:(int) numwads { data = [[NSMutableArray alloc] initWithCapacity:numwads]; @@ -116,13 +119,13 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; - (void)buttonPressed:(id) sender; - (void)doubleClicked:(id) sender; -- (void)makeLabel:(NSTextField *)label:(const char*) str; -- (int)pickIWad:(WadStuff *)wads:(int) numwads:(bool) showwin:(int) defaultiwad; +- (void)makeLabel:(NSTextField *)label withString:(const char*) str; +- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad; @end @implementation IWADPicker -- (void)buttonPressed:(id) sender; +- (void)buttonPressed:(id) sender { if(sender == cancelButton) cancelled = true; @@ -131,7 +134,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [app stopModal]; } -- (void)doubleClicked:(id) sender; +- (void)doubleClicked:(id) sender { if ([sender clickedRow] >= 0) { @@ -142,7 +145,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; // Apparently labels in Cocoa are uneditable text fields, so lets make this a // little more automated. -- (void)makeLabel:(NSTextField *)label:(const char*) str +- (void)makeLabel:(NSTextField *)label withString:(const char*) str { [label setStringValue:[NSString stringWithUTF8String:str]]; [label setBezeled:NO]; @@ -151,7 +154,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [label setSelectable:NO]; } -- (int)pickIWad:(WadStuff *)wads:(int) numwads:(bool) showwin:(int) defaultiwad +- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad { cancelled = false; @@ -163,7 +166,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; [window setTitle:windowTitle]; NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(22, 379, 412, 50)]; - [self makeLabel:description:"ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"]; + [self makeLabel:description withString:"ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"]; [[window contentView] addSubview:description]; [description release]; @@ -171,7 +174,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; //NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 103, 412, 288)]; NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 50, 412, 341)]; NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]]; - IWADTableData *tableData = [[IWADTableData alloc] init:wads:numwads]; + IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads]; for(int i = 0;i < NUM_COLUMNS;i++) { NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithUTF8String:tableHeaders[i]]]; @@ -242,7 +245,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad) { IWADPicker *picker = [IWADPicker alloc]; - int ret = [picker pickIWad:wads:numwads:showwin:defaultiwad]; + int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad]; [picker release]; return ret; } diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 3c1134c63..fa04cfa51 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -709,7 +709,7 @@ class OPLMUSDumper : public OPLMUSSong { public: OPLMUSDumper(const OPLMUSSong *original, const char *filename); - void Play(bool looping); + void Play(bool looping, int); }; // CD track/disk played through the multimedia system ----------------------- diff --git a/src/sound/music_mus_opl.cpp b/src/sound/music_mus_opl.cpp index 156094e1b..fb0d78df5 100644 --- a/src/sound/music_mus_opl.cpp +++ b/src/sound/music_mus_opl.cpp @@ -100,7 +100,7 @@ OPLMUSDumper::OPLMUSDumper(const OPLMUSSong *original, const char *filename) { } -void OPLMUSDumper::Play(bool looping) +void OPLMUSDumper::Play(bool looping, int) { Music->Dump(); } diff --git a/src/v_video.cpp b/src/v_video.cpp index 855b9fda3..fa94cd49f 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -795,7 +795,7 @@ bool DSimpleCanvas::IsValid () // //========================================================================== -bool DSimpleCanvas::Lock () +bool DSimpleCanvas::Lock (bool) { if (LockCount == 0) { diff --git a/src/v_video.h b/src/v_video.h index 09022d9ff..b0885f360 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -157,8 +157,7 @@ public: virtual bool IsValid (); // Access control - virtual bool Lock () = 0; // Returns true if the surface was lost since last time - virtual bool Lock (bool usesimplecanvas) { return Lock(); } + virtual bool Lock (bool buffered=true) = 0; // Returns true if the surface was lost since last time virtual void Unlock () = 0; virtual bool IsLocked () { return Buffer != NULL; } // Returns true if the surface is locked @@ -287,7 +286,7 @@ public: ~DSimpleCanvas (); bool IsValid (); - bool Lock (); + bool Lock (bool buffered=true); void Unlock (); protected: diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 648104271..ac8102cd2 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1033,11 +1033,6 @@ bool D3DFB::IsFullscreen () // //========================================================================== -bool D3DFB::Lock () -{ - return Lock(true); -} - bool D3DFB::Lock (bool buffered) { if (LockCount++ > 0) diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index 9fb65c2a7..71d37d564 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -815,11 +815,6 @@ HRESULT DDrawFB::GetHR () return LastHR; } -bool DDrawFB::Lock () -{ - return Lock (false); -} - bool DDrawFB::Lock (bool useSimpleCanvas) { static int lock_num; diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 07151fb02..2704de0fa 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -148,7 +148,6 @@ public: ~DDrawFB (); bool IsValid (); - bool Lock (); bool Lock (bool buffer); void Unlock (); void ForceBuffering (bool force); @@ -231,7 +230,6 @@ public: ~D3DFB (); bool IsValid (); - bool Lock (); bool Lock (bool buffered); void Unlock (); void Update (); diff --git a/src/autozend.cpp b/src/zzautozend.cpp similarity index 100% rename from src/autozend.cpp rename to src/zzautozend.cpp From fa516c5ee6a1d13ee65484e309a8b3d8a492f1b5 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 7 Jan 2014 00:55:32 -0500 Subject: [PATCH 085/311] - For some reason __MAC_10_6 is defined in the 10.5 SDK so use MAC_OS_X_VERSION_MAX to check SDK version instead. --- src/sdl/i_system.cpp | 2 +- src/sdl/iwadpicker_cocoa.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 6bd95d6e7..465735103 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -719,7 +719,7 @@ bool I_WriteIniFailed () static const char *pattern; -#if defined(__APPLE__) && !defined(__MAC_10_8) +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED < 1080 static int matchfile (struct dirent *ent) #else static int matchfile (const struct dirent *ent) diff --git a/src/sdl/iwadpicker_cocoa.mm b/src/sdl/iwadpicker_cocoa.mm index 06f84098a..3b414d5e8 100644 --- a/src/sdl/iwadpicker_cocoa.mm +++ b/src/sdl/iwadpicker_cocoa.mm @@ -49,7 +49,7 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; // Class to convert the IWAD data into a form that Cocoa can use. @interface IWADTableData : NSObject -#ifdef __MAC_10_6 +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 #endif { From 44c4736de3d49dd0c451504c5544d5692d30828a Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 10 Jan 2014 02:16:41 -0500 Subject: [PATCH 086/311] - Ignore unknown properties in the GAMEINFO lump instead of throwing an error. --- src/d_main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index f0e7e7676..86a9fad11 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1861,6 +1861,15 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char sc.MustGetString(); DoomStartupInfo.Song = sc.String; } + else + { + // Silently ignore unknown properties + do + { + sc.MustGetAnyToken(); + } + while(sc.CheckToken(',')); + } } return iwad; } From 6db974918a67fafd081954714b922e7b2e1d4d30 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 12 Jan 2014 18:39:19 +1300 Subject: [PATCH 087/311] Treat packets from unknown nodes differently Instead of trying to decompress packets from unknown connections (and failing them anyway), they are now reported and discarded without doing anything else. --- src/i_net.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i_net.cpp b/src/i_net.cpp index 2c01f407d..889688b48 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -293,7 +293,7 @@ void PacketGet (void) return; } } - else if (c > 0) + else if (node >= 0 && c > 0) { doomcom.data[0] = TransmitBuffer[0] & ~NCMD_COMPRESSED; if (TransmitBuffer[0] & NCMD_COMPRESSED) @@ -316,6 +316,12 @@ void PacketGet (void) memcpy(doomcom.data + 1, TransmitBuffer + 1, c - 1); } } + else if (c > 0) + { //The packet is not from any in-game node, so we might as well discard it. + Printf("Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port); + doomcom.remotenode = -1; + return; + } doomcom.remotenode = node; doomcom.datalength = (short)c; From 812f2d92300f5f49701dd602fab605f0979ee2ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Jan 2014 12:02:02 +0100 Subject: [PATCH 088/311] - removed all unneeded files from gdtoa/CMakeLists.txt because some compilers seem to throw duplicate symbol errors when strtod gets included. --- gdtoa/CMakeLists.txt | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 7a1304d0f..72a365bbf 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -41,45 +41,8 @@ add_library( gdtoa ${GEN_FP_FILES} dmisc.c dtoa.c - g_Qfmt.c - g__fmt.c - g_ddfmt.c - g_dfmt.c - g_ffmt.c - g_xLfmt.c - g_xfmt.c - gdtoa.c - gethex.c - gmisc.c - hd_init.c - hexnan.c misc.c - smisc.c - strtoIQ.c - strtoId.c - strtoIdd.c - strtoIf.c - strtoIg.c - strtoIx.c - strtoIxL.c - strtod.c - strtodI.c - strtodg.c - strtof.c - strtopQ.c - strtopd.c - strtopdd.c - strtopf.c - strtopx.c - strtopxL.c - strtorQ.c - strtord.c - strtordd.c - strtorf.c - strtorx.c - strtorxL.c - sum.c - ulp.c) + ) target_link_libraries( gdtoa ) if( GEN_FP_DEPS ) add_dependencies( gdtoa ${GEN_FP_DEPS} ) From 2501dc6df68e749094b4517a48c81f9a7b4fe1d2 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Mon, 13 Jan 2014 01:48:31 +0100 Subject: [PATCH 089/311] Fixed signed overflow issue, which caused a non-intended aggressive optimization by GCC 4.8. Also, negative values of the 'limit' parameter in both ACS UniqueTID() and in 'utid' CCMD are ignored and replaced by 0. --- src/p_acs.cpp | 2 +- src/p_mobj.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 582385c48..962b70049 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4933,7 +4933,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const break; case ACSF_UniqueTID: - return P_FindUniqueTID(argCount > 0 ? args[0] : 0, argCount > 1 ? args[1] : 0); + return P_FindUniqueTID(argCount > 0 ? args[0] : 0, (argCount > 1 && args[1] >= 0) ? args[1] : 0); case ACSF_IsTIDUsed: return P_IsTIDUsed(args[0]); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 03bbb4d8d..6602a11a5 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2722,12 +2722,16 @@ int P_FindUniqueTID(int start_tid, int limit) if (start_tid != 0) { // Do a linear search. - limit = start_tid + limit - 1; - if (limit < start_tid) - { // If it overflowed, clamp to INT_MAX - limit = INT_MAX; + int end_tid = start_tid; + if (start_tid > 0 && limit > INT_MAX - start_tid + 1) + { // If 'limit+start_tid-1' overflows, clamp 'end_tid' to INT_MAX + end_tid = INT_MAX; } - for (tid = start_tid; tid <= limit; ++tid) + else + { + end_tid += limit-1; + } + for (tid = start_tid; tid <= end_tid; ++tid) { if (tid != 0 && !P_IsTIDUsed(tid)) { @@ -2765,7 +2769,7 @@ CCMD(utid) { Printf("%d\n", P_FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0, - argv.argc() > 2 ? atoi(argv[2]) : 0)); + (argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0)); } //========================================================================== From f51fcd90b3f08333fc9c2935cfedfc4c8026a7d9 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 17 Jan 2014 18:57:52 +0100 Subject: [PATCH 090/311] - Fixed scanf in IWAD picker without GTK If you try to kill the program with Ctrl-C, it would run the first IWAD available in the list instead of closing it. --- src/sdl/i_system.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index def35606a..b078e6507 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -684,8 +684,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) printf ("%d. %s (%s)\n", i+1, wads[i].Name.GetChars(), filepart); } printf ("Which one? "); - scanf ("%d", &i); - if (i > numwads) + if (scanf ("%d", &i) != 1 || i > numwads) return -1; return i-1; } From aafea851f0fa334efaaafe1271b15dbdb5330854 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 17 Jan 2014 19:11:29 +0100 Subject: [PATCH 091/311] - Remove clang check from GCC-related workaround It caused a clang warning/error regarding the non-existing flags '-fno-tree-dominator-opts' and '-fno-tree-fre'. --- src/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54a72aeae..f43a6a97c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -989,10 +989,11 @@ if( NOT WIN32 ) COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/link-make COMMAND /bin/sh -c ${CMAKE_CURRENT_BINARY_DIR}/link-make ) endif( NOT WIN32 ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) # GCC misoptimizes this file set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" ) - +endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) +if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) # Need to enable intrinsics for this file. if( SSE_MATTERS ) set_source_files_properties( x86.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" ) From 884928687dc12967bbb336ee27c09c5396c42896 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 17 Jan 2014 19:27:12 +0100 Subject: [PATCH 092/311] - Fixed overflow checking in some viewpitch code --- src/g_game.cpp | 4 ++-- src/r_utility.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 081ffdb53..4ba535a00 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -775,7 +775,7 @@ void G_AddViewPitch (int look) else if (look > 0) { // Avoid overflowing - if (LocalViewPitch + look <= LocalViewPitch) + if (LocalViewPitch > INT_MAX - look) { LocalViewPitch = 0x78000000; } @@ -787,7 +787,7 @@ void G_AddViewPitch (int look) else if (look < 0) { // Avoid overflowing - if (LocalViewPitch + look >= LocalViewPitch) + if (LocalViewPitch < INT_MIN - look) { LocalViewPitch = -0x78000000; } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 0b51578ed..19ddaa972 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -602,7 +602,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi if (delta > 0) { // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch + delta <= viewpitch) + if (viewpitch > INT_MAX - delta) { viewpitch = player->MaxPitch; } @@ -614,7 +614,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi else if (delta < 0) { // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch + delta >= viewpitch) + if (viewpitch < INT_MIN - delta) { viewpitch = player->MinPitch; } From b329a34a583933394788bd464ffaddfb0375f169 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 17 Jan 2014 23:36:59 +0100 Subject: [PATCH 093/311] - Fixed some cmake --warn-uninitialized messages --- CMakeLists.txt | 5 +++++ src/CMakeLists.txt | 25 +++++++++++++++++++++++++ tools/updaterevision/CMakeLists.txt | 2 ++ 3 files changed, 32 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0858ecab5..c30fd1b58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,11 @@ if( MSVC ) string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} ) string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} ) string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) +else( MSVC ) + set( REL_LINKER_FLAGS "" ) + set( ALL_C_FLAGS "" ) + set( REL_C_FLAGS "" ) + set( DEB_C_FLAGS "" ) endif( MSVC ) set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54a72aeae..b83b6dae6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,20 @@ set( MINOR_VERSIONS "50" "49" "48" "47" "46" "45" "44" "43" "42" "41" "15" "14" "13" "12" "11" "10" "09" "08" "07" "06" "05" "04" "03" "02" "01" "00" ) set( MAJOR_VERSIONS "44" "34" "28" "26" "24" "22" "20" ) + +if( NOT FMOD_DIR_VERSIONS ) + set( FMOD_DIR_VERSIONS "" ) +endif( NOT FMOD_DIR_VERSIONS ) +if( NOT FMOD_VERSIONS ) + set( FMOD_VERSIONS "" ) +endif( NOT FMOD_VERSIONS ) +if( NOT FMOD_LOCAL_INC_DIRS ) + set( FMOD_LOCAL_INC_DIRS "" ) +endif( NOT FMOD_LOCAL_INC_DIRS ) +if( NOT FMOD_LOCAL_LIB_DIRS ) + set( FMOD_LOCAL_LIB_DIRS "" ) +endif( NOT FMOD_LOCAL_LIB_DIRS ) + set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "../fmod" ) foreach( majver ${MAJOR_VERSIONS} ) foreach( minver ${MINOR_VERSIONS} ) @@ -62,6 +76,10 @@ foreach( majver ${MAJOR_VERSIONS} ) endforeach( dir ${FMOD_DIR_VERSIONS} ) endforeach( majver ${MAJOR_VERSIONS} ) +if( NOT ZDOOM_LIBS ) + set( ZDOOM_LIBS "" ) +endif( NOT ZDOOM_LIBS ) + if( WIN32 ) if( X64 ) set( WIN_TYPE Win64 ) @@ -346,12 +364,16 @@ if( NOT NO_ASM ) endif( UNIX ) if( WIN32 ) set( FIXRTEXT fixrtext ) + else( WIN32 ) + set( FIXRTEXT "" ) endif( WIN32 ) message( STATUS "Selected assembler: ${ASSEMBLER}" ) MACRO( ADD_ASM_FILE indir infile ) set( ASM_OUTPUT_${infile} "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir}/${infile}${ASM_OUTPUT_EXTENSION}" ) if( WIN32 ) set( FIXRTEXT_${infile} COMMAND ${FIXRTEXT} "${ASM_OUTPUT_${infile}}" ) + else( WIN32 ) + set( FIXRTEXT_${infile} COMMAND "" ) endif( WIN32 ) add_custom_command( OUTPUT ${ASM_OUTPUT_${infile}} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir} @@ -567,6 +589,9 @@ endif( WIN32 ) if( NO_ASM ) add_definitions( -DNOASM ) else( NO_ASM ) + if( NOT ASM_SOURCES ) + set( ASM_SOURCES "" ) + endif( NOT ASM_SOURCES ) if( X64 ) ADD_ASM_FILE( asm_x86_64 tmap3 ) else( X64 ) diff --git a/tools/updaterevision/CMakeLists.txt b/tools/updaterevision/CMakeLists.txt index d985b9e3f..be6167f94 100644 --- a/tools/updaterevision/CMakeLists.txt +++ b/tools/updaterevision/CMakeLists.txt @@ -15,6 +15,8 @@ if( WIN32 ) set( TRUSTINFO trustinfo.rc ) endif( MSVC_VERSION GREATER 1399 ) endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +else( WIN32 ) + set( TRUSTINFO "" ) endif( WIN32 ) add_executable( updaterevision updaterevision.c ${TRUSTINFO} ) From 70717cd2fab2183ce27e7eedfc03e77806d76d24 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 18 Jan 2014 02:21:49 +0100 Subject: [PATCH 094/311] - Cover the ASM_SOURCES fix for NO_ASM users too --- src/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b83b6dae6..badd2c3b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -586,12 +586,13 @@ else( WIN32 ) endif( APPLE ) endif( WIN32 ) +if( NOT ASM_SOURCES ) + set( ASM_SOURCES "" ) +endif( NOT ASM_SOURCES ) + if( NO_ASM ) add_definitions( -DNOASM ) else( NO_ASM ) - if( NOT ASM_SOURCES ) - set( ASM_SOURCES "" ) - endif( NOT ASM_SOURCES ) if( X64 ) ADD_ASM_FILE( asm_x86_64 tmap3 ) else( X64 ) From 6f7885210ba804d6f2ad6f5e8c03467ad983fc82 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 26 Nov 2013 17:58:55 -0500 Subject: [PATCH 095/311] - Fixed: Some setups require the dynamic linking library to be linked explicitly, so specify it when using DYN_FLUIDSYNTH --- src/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54a72aeae..4ced0062f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -506,12 +506,14 @@ message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" ) set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${FMOD_LIBRARY}" ) include_directories( "${ZLIB_INCLUDE_DIR}" "${FMOD_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" ) -if( FLUIDSYNTH_FOUND ) - if( NOT DYN_FLUIDSYNTH) - set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FLUIDSYNTH_LIBRARIES}" ) - include_directories( "${FLUIDSYNTH_INCLUDE_DIR}" ) - endif( NOT DYN_FLUIDSYNTH ) -endif( FLUIDSYNTH_FOUND ) +if( NOT DYN_FLUIDSYNTH) + if( FLUIDSYNTH_FOUND ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FLUIDSYNTH_LIBRARIES}" ) + include_directories( "${FLUIDSYNTH_INCLUDE_DIR}" ) + endif( FLUIDSYNTH_FOUND ) +else( NOT DYN_FLUIDSYNTH ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} ${CMAKE_DL_LIBS} ) +endif( NOT DYN_FLUIDSYNTH ) # Start defining source files for ZDoom From e5d7077d743073c5780087ee1d0b3082674f5f5d Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 15:09:12 -0500 Subject: [PATCH 096/311] - Fixed: Shareware games couldn't bother with the actor has no frames errors since we don't load mods. - Fixed: Heretic shareware used a different border for the statusbar. --- src/p_mobj.cpp | 6 ++++++ wadsrc/static/mapinfo/hereticsw.txt | 1 + 2 files changed, 7 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 03bbb4d8d..37110e388 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4639,6 +4639,12 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (defaults->SpawnState == NULL || sprites[defaults->SpawnState->sprite].numframes == 0) { + // We don't load mods for shareware games so we'll just ignore + // missing actors. Heretic needs this since the shareware includes + // the retail weapons in Deathmatch. + if (gameinfo.flags & GI_SHAREWARE) + return NULL; + Printf ("%s at (%i, %i) has no frames\n", i->TypeName.GetChars(), mthing->x>>FRACBITS, mthing->y>>FRACBITS); i = PClass::FindClass("Unknown"); diff --git a/wadsrc/static/mapinfo/hereticsw.txt b/wadsrc/static/mapinfo/hereticsw.txt index 89b6c0762..5a37ccbef 100644 --- a/wadsrc/static/mapinfo/hereticsw.txt +++ b/wadsrc/static/mapinfo/hereticsw.txt @@ -4,5 +4,6 @@ gameinfo { finalepage = "ORDER" infopage = "ORDER", "HELP1", "HELP2", "CREDIT" + borderflat = "FLOOR04" } From 7af8b78b9fa5ec066cc6ed7a01d041850e36b07f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 15:18:35 -0500 Subject: [PATCH 097/311] - Applied Chilly's patch to fix excessive name change notifications. --- src/d_netinfo.cpp | 2 +- src/menu/playermenu.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 12fb187ae..d2dbc862d 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -861,7 +861,7 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update) val.String = CleanseString(value.LockBuffer()); (*cvar_ptr)->SetGenericRep(val, CVAR_String); value.UnlockBuffer(); - if (keyname == NAME_Name && update && oldname != value) + if (keyname == NAME_Name && update && oldname.Compare (value)) { Printf("%s is now known as %s\n", oldname.GetChars(), value.GetChars()); } diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 641b0699f..58b08fc38 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -996,7 +996,10 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller) // item specific handling comes here case NAME_Playerbox: - PlayerNameChanged(li); + if (mkey == MKEY_Input) + { + PlayerNameChanged(li); + } break; case NAME_Team: From ebcd0e9c49fc7eb4b284e623244fffb5417c638b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 15:40:48 -0500 Subject: [PATCH 098/311] - Removed redundant expression in R_FindPlane. --- src/r_plane.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 986d99203..be650bf91 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -607,8 +607,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl // same visplane, then only the floor sky will be drawn. plane.c = height.c; plane.ic = height.ic; - isskybox = skybox != NULL && !skybox->bInSkybox && - (skybox->bAlways || picnum == skyflatnum); + isskybox = skybox != NULL && !skybox->bInSkybox; } else if (skybox != NULL && skybox->bAlways && !skybox->bInSkybox) { From 919b9283005a7431cc8c78aabaa1fe0181f6f275 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 15:45:11 -0500 Subject: [PATCH 099/311] - Fixed: Taking an item in a Strife dialog didn't account for items that have the keep depleted flag set. --- src/p_conversation.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 6493bca36..09f2d49d6 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -655,7 +655,14 @@ static void TakeStrifeItem (player_t *player, const PClass *itemtype, int amount item->Amount -= amount; if (item->Amount <= 0) { - item->Destroy (); + if (item->ItemFlags & IF_KEEPDEPLETED) + { + item->Amount = 0; + } + else + { + item->Destroy (); + } } } } From 75fd674d31c53aa68a2e84ad74c0b2310069d084 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 16:20:52 -0500 Subject: [PATCH 100/311] - If the player doesn't have ` bound to open the console, don't close it with that key. --- src/c_console.cpp | 7 +++++++ src/doomdef.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/c_console.cpp b/src/c_console.cpp index e5d3d97ab..e20229605 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -41,6 +41,7 @@ #include "version.h" #include "g_game.h" +#include "c_bind.h" #include "c_console.h" #include "c_cvars.h" #include "c_dispatch.h" @@ -1698,6 +1699,12 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) break; case '`': + // Check to see if we have ` bound to the console before accepting + // it as a way to close the console. + if (Bindings.GetBinding(KEY_GRAVE).CompareNoCase("toggleconsole")) + { + break; + } case GK_ESCAPE: // Close console and clear command line. But if we're in the // fullscreen console mode, there's nothing to fall back on diff --git a/src/doomdef.h b/src/doomdef.h index 675923b4a..e08c3044d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -130,6 +130,7 @@ enum ESkillLevels #define KEY_F10 0x44 // DIK_F10 #define KEY_F11 0x57 // DIK_F11 #define KEY_F12 0x58 // DIK_F12 +#define KEY_GRAVE 0x29 // DIK_GRAVE #define KEY_BACKSPACE 0x0e // DIK_BACK From 811a75ebf659fc81969126b8bd1ece82a3e23371 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 18 Jan 2014 17:54:46 -0500 Subject: [PATCH 101/311] - Minor adjustments to SDL joystick code so that all axes have at least a small deadzone so that button mapping works properly. --- src/sdl/i_joystick.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_joystick.cpp b/src/sdl/i_joystick.cpp index 48ae0e385..7a529861f 100644 --- a/src/sdl/i_joystick.cpp +++ b/src/sdl/i_joystick.cpp @@ -1,8 +1,12 @@ #include #include "doomdef.h" +#include "templates.h" #include "m_joy.h" +// Very small deadzone so that floating point magic doesn't happen +#define MIN_DEADZONE 0.000001f + class SDLInputJoystick: public IJoystickConfig { public: @@ -65,7 +69,7 @@ public: void SetAxisDeadZone(int axis, float zone) { - Axes[axis].DeadZone = zone; + Axes[axis].DeadZone = clamp(zone, MIN_DEADZONE, 1.f); } void SetAxisMap(int axis, EJoyAxis gameaxis) { @@ -83,7 +87,7 @@ public: } bool IsAxisDeadZoneDefault(int axis) { - return Axes[axis].DeadZone == 0.0f; + return Axes[axis].DeadZone <= MIN_DEADZONE; } bool IsAxisMapDefault(int axis) { @@ -105,7 +109,7 @@ public: info.Name.Format("Axis %d", i+1); else info.Name.Format("Hat %d (%c)", (i-NumAxes)/2 + 1, (i-NumAxes)%2 == 0 ? 'x' : 'y'); - info.DeadZone = 0.0f; + info.DeadZone = MIN_DEADZONE; info.Multiplier = 1.0f; info.Value = 0.0; info.ButtonValue = 0; @@ -141,7 +145,7 @@ public: { buttonstate = 0; - Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32768.0; + Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32767.0; Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, &buttonstate); // Map button to axis From 0442c51d54d351ef0f497191be91c7410cc96e2c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 21 Jan 2014 19:41:29 -0600 Subject: [PATCH 102/311] Fix building with old VC++ 2005 projects. - Also needed to comment out strtod declarations in gdtoaimp.h and gdtoa.h --- gdtoa/gdtoa.h | 4 +- gdtoa/gdtoa.vcproj | 1216 ++++++++++++++++++++++++++++++++++++++++++++ gdtoa/gdtoaimp.h | 2 +- zdoom.vcproj | 24 +- 4 files changed, 1231 insertions(+), 15 deletions(-) diff --git a/gdtoa/gdtoa.h b/gdtoa/gdtoa.h index 49c637beb..8b7390a28 100644 --- a/gdtoa/gdtoa.h +++ b/gdtoa/gdtoa.h @@ -142,8 +142,8 @@ extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)); extern void freedtoa ANSI((char*)); -extern float strtof ANSI((CONST char *, char **)); -extern double strtod ANSI((CONST char *, char **)); +//extern float strtof ANSI((CONST char *, char **)); +//extern double strtod ANSI((CONST char *, char **)); extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); extern char* g_ddfmt ANSI((char*, double*, int, size_t)); diff --git a/gdtoa/gdtoa.vcproj b/gdtoa/gdtoa.vcproj index 7195c1457..3ac6ce39d 100644 --- a/gdtoa/gdtoa.vcproj +++ b/gdtoa/gdtoa.vcproj @@ -293,50 +293,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -482,14 +486,6 @@ RelativePath=".\src\am_map.cpp" > - - - - @@ -1094,6 +1090,10 @@ RelativePath=".\src\zstring.cpp" > + + Date: Tue, 21 Jan 2014 19:48:46 -0600 Subject: [PATCH 103/311] Add more stuff to .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index e27cd5a59..cfa4882e6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ /release_gcc /dumb/vc6/dumb_static/release /dumb/vc6/dumb_static/debug +/dumb/vc6/dumb_static/x64 /DOOMSTATS.TXT /src/gitinfo.h /src/sc_man_scanner.h @@ -25,5 +26,14 @@ /tools/*/*.exe /tools/lemon/build /tools/re2c/build +/tools/updaterevision/x64/ +/tools/zipdir/x64 /wadsrc/*.pk3 /build_vc2013 +/bzip2/x64/ +/disasm.txt +/game-music-emu/x64/ +/gdtoa/x64/ +/jpeg-6b/x64/ +/lzma/x64/ +/zlib/x64/ From 4e53df8bca5e0dad98c6bdac9b1b5d9acf479d1d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 26 Jan 2014 14:32:44 +0100 Subject: [PATCH 104/311] - fixed: The 'load' command in GAMEINFO only worked if the filename contained a slash. --- src/d_main.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 5dd186cd0..6c938ef53 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1807,19 +1807,23 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char // Try looking for the wad in the same directory as the .wad // before looking for it in the current directory. + FString checkpath; if (lastSlash != NULL) { - FString checkpath(fn, (lastSlash - fn) + 1); + checkpath = FString(fn, (lastSlash - fn) + 1); checkpath += sc.String; - - if (!FileExists (checkpath)) - { - pos += D_AddFile(pwads, sc.String, true, pos); - } - else - { - pos += D_AddFile(pwads, checkpath, true, pos); - } + } + else + { + checkpath = sc.String; + } + if (!FileExists(checkpath)) + { + pos += D_AddFile(pwads, sc.String, true, pos); + } + else + { + pos += D_AddFile(pwads, checkpath, true, pos); } } while (sc.CheckToken(',')); From 8b02bb55aa3561eeb06bf4cc6320b609f7af26b4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 30 Jan 2014 20:30:40 -0600 Subject: [PATCH 105/311] Fix compiling with FMOD 4.36 - That stuff I thought that went poof in FMOD Ex 4.37 was apparently already gone in 4.36. --- src/sound/fmodsound.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 4bdc43081..18f4cbb8f 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -63,7 +63,7 @@ extern HWND Window; #include "cmdlib.h" #include "s_sound.h" -#if FMOD_VERSION > 0x42899 && FMOD_VERSION < 0x43800 +#if FMOD_VERSION > 0x42899 && FMOD_VERSION < 0x43600 #error You are trying to compile with an unsupported version of FMOD. #endif @@ -858,7 +858,7 @@ bool FMODSoundRenderer::Init() result = Sys->setDriver(driver); } result = Sys->getDriver(&driver); -#if FMOD_VERSION >= 0x43700 +#if FMOD_VERSION >= 0x43600 // We were built with an FMOD that only returns the control panel frequency result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &speakermode); Driver_MaxFrequency = Driver_MinFrequency; @@ -1043,7 +1043,7 @@ bool FMODSoundRenderer::Init() } // Create DSP units for underwater effect -#if FMOD_VERSION < 0x43701 +#if FMOD_VERSION < 0x43600 result = Sys->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &WaterLP); if (result != FMOD_OK) { @@ -1106,7 +1106,7 @@ bool FMODSoundRenderer::Init() WaterLP->setActive(false); WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); WaterLP->setParameter(FMOD_DSP_LOWPASS_RESONANCE, 2); -#if FMOD_VERSION < 0x43701 +#if FMOD_VERSION < 0x43600 if (WaterReverb != NULL) { FMOD::DSPConnection *dry; From 3cff307e7756aae6e0f8c255f5a8a6eaf28270ec Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 4 Feb 2014 19:36:29 -0600 Subject: [PATCH 106/311] Add Get/SetLineActivation ACS functions --- src/p_acs.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 26b62be70..1ed89f783 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4251,6 +4251,8 @@ enum EACSFunctions ACSF_CheckFont, ACSF_DropItem, ACSF_CheckFlag, + ACSF_SetLineActivation, + ACSF_GetLineActivation, // ZDaemon ACSF_GetTeamScore = 19620, // (int team) @@ -5296,6 +5298,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) break; } + case ACSF_SetLineActivation: + if (argCount >= 2) + { + int line = -1; + + while ((line = P_FindLineFromID(args[0], line)) >= 0) + { + lines[line].activation = args[1]; + } + } + break; + + case ACSF_GetLineActivation: + if (argCount > 0) + { + int line = P_FindLineFromID(args[0], -1); + return line >= 0 ? lines[line].activation : 0; + } + break; + default: break; } From 0db82f02cfb7bdd555a2a45d605bb7af600163a0 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Wed, 12 Feb 2014 20:30:37 +1300 Subject: [PATCH 107/311] P_HitWater ignore extra floors below real floor P_HitWater incorrectly assumed extra floors were always above the real floor. --- src/p_mobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d97a091ea..7dc8a3f46 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5169,7 +5169,7 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z } } planez = rover->bottom.plane->ZatPoint(x, y); - if (planez < z) return false; + if (planez < z && !(planez < thing->floorz)) return false; } #endif hsec = sec->GetHeightSec(); From dd5f2731282a27f811f1c8a5989028dd7922d52b Mon Sep 17 00:00:00 2001 From: Alex Qyoun-ae Date: Fri, 14 Feb 2014 05:10:48 +0400 Subject: [PATCH 108/311] Added possibly missing brackets --- src/g_strife/a_entityboss.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 58a88121e..fafb3b862 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) fixed_t SpawnX = spot->x; fixed_t SpawnY = spot->y; - fixed_t SpawnZ = spot->z + self->tracer? 70*FRACUNIT : 0; + fixed_t SpawnZ = spot->z + (self->tracer? 70*FRACUNIT : 0); an = self->angle >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), From 02cd6eebf443579bd9ade2e1396400ab49bd398d Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 16 Feb 2014 18:29:01 +0100 Subject: [PATCH 109/311] A_Log formatted text Make DECORATE version of Log consistent with ACS version. --- src/thingdef/thingdef_codeptr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d48b18a2a..f2c738fb9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2205,7 +2205,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log) ACTION_PARAM_STRING(text, 0); if (text[0] == '$') text = GStrings(text+1); - Printf("%s\n", text); + FString formatted = strbin1(text); + Printf("%s\n", formatted.GetChars()); ACTION_SET_RESULT(false); // Prints should never set the result for inventory state chains! } From d7478bcd683d609404ae664342de6e6b7ed94ac2 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 18 Feb 2014 00:40:14 +0100 Subject: [PATCH 110/311] New Freedoom names - Added freedoom2.wad as valid alias name (freedoom1.wad already existed). - Renamed titles to Freedoom: Phase 1 and Freedoom: Phase 2. - Reordered to put Phase 1 above Phase 2 in the IWAD picker. --- wadsrc/static/iwadinfo.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index e47951d31..a2f8ef6c0 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -189,7 +189,7 @@ IWad IWad { - Name = "Freedoom" + Name = "Freedoom: Phase 2" Autoname = "Freedoom" Game = "Doom" Config = "Doom" @@ -200,7 +200,7 @@ IWad IWad { - Name = "Ultimate Freedoom" + Name = "Freedoom: Phase 1" Autoname = "Freedoom1" Game = "Doom" Config = "Doom" @@ -348,9 +348,10 @@ Names "strife1.wad" "strife0.wad" "strife.wad" - "freedoom.wad" "freedoom1.wad" + "freedoom2.wad" "freedoomu.wad" + "freedoom.wad" "freedm.wad" "blasphem.wad" "blasphemer.wad" From 5c23ffb7bc2b6f2c56dcb23a0caf19d3eb7c6f65 Mon Sep 17 00:00:00 2001 From: Alex Qyoun-ae Date: Fri, 14 Feb 2014 05:10:48 +0400 Subject: [PATCH 111/311] Added possibly missing brackets --- src/g_strife/a_entityboss.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 58a88121e..fafb3b862 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) fixed_t SpawnX = spot->x; fixed_t SpawnY = spot->y; - fixed_t SpawnZ = spot->z + self->tracer? 70*FRACUNIT : 0; + fixed_t SpawnZ = spot->z + (self->tracer? 70*FRACUNIT : 0); an = self->angle >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), From 18f2644162734b98b1aa83798eef9940deab32b8 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 16 Feb 2014 18:29:01 +0100 Subject: [PATCH 112/311] A_Log formatted text Make DECORATE version of Log consistent with ACS version. --- src/thingdef/thingdef_codeptr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d48b18a2a..f2c738fb9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2205,7 +2205,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log) ACTION_PARAM_STRING(text, 0); if (text[0] == '$') text = GStrings(text+1); - Printf("%s\n", text); + FString formatted = strbin1(text); + Printf("%s\n", formatted.GetChars()); ACTION_SET_RESULT(false); // Prints should never set the result for inventory state chains! } From 5c2620986ea67646a45bf1f0cc7f5e8fee0aa251 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 18 Feb 2014 00:40:14 +0100 Subject: [PATCH 113/311] New Freedoom names - Added freedoom2.wad as valid alias name (freedoom1.wad already existed). - Renamed titles to Freedoom: Phase 1 and Freedoom: Phase 2. - Reordered to put Phase 1 above Phase 2 in the IWAD picker. --- wadsrc/static/iwadinfo.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index e47951d31..a2f8ef6c0 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -189,7 +189,7 @@ IWad IWad { - Name = "Freedoom" + Name = "Freedoom: Phase 2" Autoname = "Freedoom" Game = "Doom" Config = "Doom" @@ -200,7 +200,7 @@ IWad IWad { - Name = "Ultimate Freedoom" + Name = "Freedoom: Phase 1" Autoname = "Freedoom1" Game = "Doom" Config = "Doom" @@ -348,9 +348,10 @@ Names "strife1.wad" "strife0.wad" "strife.wad" - "freedoom.wad" "freedoom1.wad" + "freedoom2.wad" "freedoomu.wad" + "freedoom.wad" "freedm.wad" "blasphem.wad" "blasphemer.wad" From 732ee11da1a539fdf68074c2e748d84873728a83 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 23 Feb 2014 23:07:10 +0100 Subject: [PATCH 114/311] Some DOSBox Raw OPL v2 indices were off by one. This caused access violation errors on perfectly fine DRO files. For reference, scoredata[20] is the hardware type (OPL2, dual OPL2, or OPL3). --- src/oplsynth/opl_mus_player.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 335e6d66e..43a129b14 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -104,16 +104,19 @@ fail: delete[] scoredata; } else if (((DWORD *)scoredata)[2] == MAKE_ID(2,0,0,0)) { - if (scoredata[20] != 0) - { - Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); - goto fail; - } + bool okay = true; if (scoredata[21] != 0) { - Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); - goto fail; + Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); + okay = false; } + if (scoredata[22] != 0) + { + Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); + okay = false; + } + if (!okay) + goto fail; RawPlayer = DosBox2; SamplesPerTick = OPL_SAMPLE_RATE / 1000; int headersize = 0x1A + scoredata[0x19]; From 9dacc9cc8d466e53d3f946dffc1e3601d1cac120 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Mon, 24 Feb 2014 05:07:37 +0100 Subject: [PATCH 115/311] The wrong value was used here. This caused crashes on some files (notably MBELLS from Cosmo and NUBC from Body Count) in my port of this code to SLADE 3. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 43a129b14..319eb8319 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -267,7 +267,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { for (i = 0; i < io->NumChips; ++i) { - io->chips[i]->Update(samples1, samplesleft); + io->chips[i]->Update(samples1, numsamples); } OffsetSamples(samples1, numsamples << stereoshift); } From c7301a0fbbb738b84f4281308bdb06380ab256b8 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 23 Feb 2014 23:07:10 +0100 Subject: [PATCH 116/311] Some DOSBox Raw OPL v2 indices were off by one. This caused access violation errors on perfectly fine DRO files. For reference, scoredata[20] is the hardware type (OPL2, dual OPL2, or OPL3). --- src/oplsynth/opl_mus_player.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 335e6d66e..43a129b14 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -104,16 +104,19 @@ fail: delete[] scoredata; } else if (((DWORD *)scoredata)[2] == MAKE_ID(2,0,0,0)) { - if (scoredata[20] != 0) - { - Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); - goto fail; - } + bool okay = true; if (scoredata[21] != 0) { - Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); - goto fail; + Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); + okay = false; } + if (scoredata[22] != 0) + { + Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); + okay = false; + } + if (!okay) + goto fail; RawPlayer = DosBox2; SamplesPerTick = OPL_SAMPLE_RATE / 1000; int headersize = 0x1A + scoredata[0x19]; From d430c18574fd6d72c751f869c4b3cd3312990b46 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Mon, 24 Feb 2014 05:07:37 +0100 Subject: [PATCH 117/311] The wrong value was used here. This caused crashes on some files (notably MBELLS from Cosmo and NUBC from Body Count) in my port of this code to SLADE 3. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 43a129b14..319eb8319 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -267,7 +267,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { for (i = 0; i < io->NumChips; ++i) { - io->chips[i]->Update(samples1, samplesleft); + io->chips[i]->Update(samples1, numsamples); } OffsetSamples(samples1, numsamples << stereoshift); } From 0f7ad00d9a0ab45b75840f98df059712b48ac394 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 15:48:41 -0600 Subject: [PATCH 118/311] Ignore the minor version number when checking for DRO v1 files - There exist files where the first word of the version number for DRO v1 files is not 0 but something else completely. (Maybe it's not actually a version number?) Assume they are valid v1 files as long as the second word is a 1. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 319eb8319..a528c10e2 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -96,7 +96,7 @@ fail: delete[] scoredata; else if (((DWORD *)scoredata)[0] == MAKE_ID('D','B','R','A') && ((DWORD *)scoredata)[1] == MAKE_ID('W','O','P','L')) { - if (((DWORD *)scoredata)[2] == MAKE_ID(0,0,1,0)) + if (LittleShort(((WORD *)scoredata)[5]) == 1) { RawPlayer = DosBox1; SamplesPerTick = OPL_SAMPLE_RATE / 1000; From 7052d4e14e31328b5f14803b3aca20860f9a7e45 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 16:18:10 -0600 Subject: [PATCH 119/311] Fixed: userinfo_t::SkinChanged() was unaware of player classes --- src/d_netinfo.cpp | 10 +++++----- src/d_player.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index d2dbc862d..41ad683fe 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -387,7 +387,7 @@ void D_SetupUserInfo () { // Some cvars don't copy their original value directly. case NAME_Team: coninfo->TeamChanged(team); break; - case NAME_Skin: coninfo->SkinChanged(skin); break; + case NAME_Skin: coninfo->SkinChanged(skin, players[consoleplayer].CurrentPlayerClass); break; case NAME_Gender: coninfo->GenderChanged(gender); break; case NAME_PlayerClass: coninfo->PlayerClassChanged(playerclass); break; // The rest do. @@ -447,9 +447,9 @@ int userinfo_t::TeamChanged(int team) return team; } -int userinfo_t::SkinChanged(const char *skinname) +int userinfo_t::SkinChanged(const char *skinname, int playerclass) { - int skinnum = R_FindSkin(skinname, 0); + int skinnum = R_FindSkin(skinname, playerclass); *static_cast((*this)[NAME_Skin]) = skinnum; return skinnum; } @@ -821,7 +821,7 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update) break; case NAME_Skin: - info->SkinChanged(value); + info->SkinChanged(value, players[pnum].CurrentPlayerClass); if (players[pnum].mo != NULL) { if (players[pnum].cls != NULL && @@ -958,7 +958,7 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) switch (name) { case NAME_Team: info.TeamChanged(atoi(str)); break; - case NAME_Skin: info.SkinChanged(str); break; + case NAME_Skin: info.SkinChanged(str, 0); break; case NAME_PlayerClass: info.PlayerClassChanged(str); break; default: val.String = str; diff --git a/src/d_player.h b/src/d_player.h index f6f7674d7..e104a55b6 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,7 +332,7 @@ struct userinfo_t : TMap void Reset(); int TeamChanged(int team); - int SkinChanged(const char *skinname); + int SkinChanged(const char *skinname, int playerclass); int SkinNumChanged(int skinnum); int GenderChanged(const char *gendername); int PlayerClassChanged(const char *classname); From db4763b14a0bfa0196ce41a96e96f5e724927291 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 16:27:57 -0600 Subject: [PATCH 120/311] Delay skin setting on save load until player class is known. - Fixed: Loading players from savegames set the skin before their current class was retrieved, so they could not validate their skins with the correct class. --- src/d_netinfo.cpp | 28 +++++++++------------------- src/d_player.h | 4 ++-- src/p_user.cpp | 18 +++++++++++++++--- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 41ad683fe..ae2da8018 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -941,14 +941,21 @@ void WriteUserInfo(FArchive &arc, userinfo_t &info) arc << name; } -void ReadUserInfo(FArchive &arc, userinfo_t &info) +void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin) { FName name; FBaseCVar **cvar; char *str = NULL; UCVarValue val; + if (SaveVersion < 4253) + { + ReadCompatibleUserInfo(arc, info); + return; + } + info.Reset(); + skin = NULL; for (arc << name; name != NAME_None; arc << name) { cvar = info.CheckKey(name); @@ -958,7 +965,7 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) switch (name) { case NAME_Team: info.TeamChanged(atoi(str)); break; - case NAME_Skin: info.SkinChanged(str, 0); break; + case NAME_Skin: skin = str; break; // Caller must call SkinChanged() once current calss is known case NAME_PlayerClass: info.PlayerClassChanged(str); break; default: val.String = str; @@ -973,23 +980,6 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) } } -FArchive &operator<< (FArchive &arc, userinfo_t &info) -{ - if (SaveVersion < 4253) - { - ReadCompatibleUserInfo(arc, info); - } - else if (arc.IsStoring()) - { - WriteUserInfo(arc, info); - } - else - { - ReadUserInfo(arc, info); - } - return arc; -} - CCMD (playerinfo) { if (argv.argc() < 2) diff --git a/src/d_player.h b/src/d_player.h index e104a55b6..122ab20f0 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -342,8 +342,8 @@ struct userinfo_t : TMap int ColorSetChanged(int setnum); }; -FArchive &operator<< (FArchive &arc, userinfo_t &info); - +void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin); +void WriteUserInfo(FArchive &arc, userinfo_t &info); // // Extended player object info: player_t diff --git a/src/p_user.cpp b/src/p_user.cpp index 901f6cfaa..80b175802 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2742,14 +2742,22 @@ void P_UnPredictPlayer () void player_t::Serialize (FArchive &arc) { int i; + FString skinname; arc << cls << mo << camera << playerstate - << cmd - << userinfo - << DesiredFOV << FOV + << cmd; + if (arc.IsLoading()) + { + ReadUserInfo(arc, userinfo, skinname); + } + else + { + WriteUserInfo(arc, userinfo); + } + arc << DesiredFOV << FOV << viewz << viewheight << deltaviewheight @@ -2900,6 +2908,10 @@ void player_t::Serialize (FArchive &arc) oldbuttons = ~0; original_oldbuttons = ~0; } + if (skinname.IsNotEmpty()) + { + userinfo.SkinChanged(skinname, CurrentPlayerClass); + } } From a60918f601aa6bd094568340b26906f0f03772ae Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 17:43:28 -0600 Subject: [PATCH 121/311] Add NoPushWindowCheck compatibility flag - For maps like xtheateriii that expect non-blocking push lines to activate when you are standing on them and run into a completely different line, there is now this compatiblity.txt-only flag. --- src/compatibility.cpp | 1 + src/doomdef.h | 1 + src/p_map.cpp | 2 +- wadsrc/static/compatibility.txt | 7 ++++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index dca0d3485..7339a0f19 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -106,6 +106,7 @@ static FCompatOption Options[] = { "ignoreteleporttags", BCOMPATF_BADTELEPORTERS, SLOT_BCOMPAT }, { "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT }, { "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT }, + { "disablepushwindowcheck", BCOMPATF_NOWINDOWCHECK, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, diff --git a/src/doomdef.h b/src/doomdef.h index e08c3044d..6ef9fcd04 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -351,6 +351,7 @@ enum BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other + BCOMPATF_NOWINDOWCHECK = 1 << 7, // Disable the window check in CheckForPushSpecial() }; // phares 3/20/98: diff --git a/src/p_map.cpp b/src/p_map.cpp index 8b0b605c6..02ab1a1ab 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1640,7 +1640,7 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj, bool wind { if (line->special && !(mobj->flags6 & MF6_NOTRIGGER)) { - if (windowcheck && line->backsector != NULL) + if (windowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) { // Make sure this line actually blocks us and is not a window // or similar construct we are standing inside of. fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(mobj->x, mobj->y); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 4b75dfaba..e2516a30d 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -375,4 +375,9 @@ D62DCA9EC226DE49108D5DD9271F7631 // Cheogsh 2 map04 setthingz 1647 528 setthingz 1648 528 setthingz 1649 528 -} \ No newline at end of file +} + +B9DFF13207EACAC675C71D82624D0007 // XtheaterIII map01 +{ + DisablePushWindowCheck +} From 5a5fb9b3d19372d9323ba31fa5689fc95f94250b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 18:16:18 -0600 Subject: [PATCH 122/311] Clamp xy angle range in P_SetSlope() - This function just assumed that every xy angle passed to it was within the range [0,360). This is obviously bad, since anything outside that range can result in accessing data outside the range of the finecosine and finesine tables. --- src/p_slopes.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 07ddf2e0d..af0ad7a20 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -178,6 +178,12 @@ void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi, } zang >>= ANGLETOFINESHIFT; + // Sanitize xyangi to [0,360) range + xyangi = xyangi % 360; + if (xyangi < 0) + { + xyangi = 360 + xyangi; + } xyang = (angle_t)Scale (xyangi, ANGLE_90, 90 << ANGLETOFINESHIFT); FVector3 norm; @@ -446,11 +452,11 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); } else if (mt->type <= THING_SlopeCeilingPointLine) - { + { // THING_SlopeFloorPointLine and THING_SlopCeilingPointLine P_SlopeLineToPoint (mt->args[0], x, y, z, mt->type & 1); } else - { + { // THING_SetFloorSlope and THING_SetCeilingSlope P_SetSlope (refplane, mt->type & 1, mt->angle, mt->args[0], x, y, z); } mt->type = 0; From 1d4f4b25d74fccc8f4c5e42811707e0606ce7adb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 19:01:36 -0600 Subject: [PATCH 123/311] Don't free replaced textures that are used as patches. - Fixed: If a part of a multipatch texture is replaced by a HIRESTEX version, the original patch must not be deleted, since the multipatch texture still needs it for compositing. --- src/textures/multipatchtexture.cpp | 6 ++++-- src/textures/texture.cpp | 2 +- src/textures/texturemanager.cpp | 2 +- src/textures/textures.h | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index fd2b59fb1..4f327309d 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -244,7 +244,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl Height = SAFESHORT(mtexture.d->height); strncpy (Name, (const char *)mtexture.d->name, 8); Name[8] = 0; - CalcBitSize (); xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; @@ -280,6 +279,10 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl NumParts--; i--; } + else + { + Parts[i].Texture->bKeepAround = true; + } if (strife) mpatch.s++; else @@ -859,7 +862,6 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d { pnames.Read (patchlookup[i].Name, 8); patchlookup[i].Name[8] = 0; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); if (j.isValid()) { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 093bf303b..0434aaaa4 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -146,7 +146,7 @@ FTexture::FTexture (const char *name, int lumpnum) : LeftOffset(0), TopOffset(0), WidthBits(0), HeightBits(0), xScale(FRACUNIT), yScale(FRACUNIT), SourceLump(lumpnum), UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), - bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), + bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0), Native(NULL) { id.SetInvalid(); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index f28026f19..48f3ff9e0 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -428,7 +428,7 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b Textures[index].Texture = newtexture; newtexture->id = oldtexture->id; - if (free) + if (free && !oldtexture->bKeepAround) { delete oldtexture; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 100ba31e9..837c62689 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -177,6 +177,7 @@ public: // fully composited before subjected to any kind of postprocessing instead of // doing it per patch. BYTE bMultiPatch:1; // This is a multipatch texture (we really could use real type info for textures...) + BYTE bKeepAround:1; // This texture was used as part of a multi-patch texture. Do not free it. WORD Rotations; SWORD SkyOffset; From 1fb757f6f120e2b7d09213b5da3f4976e1443868 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 1 Mar 2014 22:27:40 +0100 Subject: [PATCH 124/311] - Fixed useless 'array != NULL' check. - 'notranslate != NULL' is completely useless, because 'notranslate' is an array, hence removed. - I interpreted 'SbarInfoScript != NULL' as a typo, since 1)in the next expression inside the condition there's a dereference to 'SBarInfoScript[SCRIPT_CUSTOM]' and 2)'SBarInfoScript[SCRIPT_CUSTOM]' is checked against 'NULL', in line 352, and then dereferenced when introducing 'cstype'. --- src/g_level.cpp | 2 +- src/v_font.cpp | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 0b07ae2b5..cf40b5099 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -387,7 +387,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) StatusBar->NewGame (); setsizeneeded = true; - if (gameinfo.gametype == GAME_Strife || (SBarInfoScript != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) + if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) { // Set the initial quest log text for Strife. for (i = 0; i < MAXPLAYERS; ++i) diff --git a/src/v_font.cpp b/src/v_font.cpp index d34b08be5..abd7f494c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -2009,26 +2009,20 @@ void FSpecialFont::LoadTranslations() } // exclude the non-translated colors from the translation calculation - if (notranslate != NULL) - { - for (i = 0; i < 256; i++) - if (notranslate[i]) - usedcolors[i] = false; - } + for (i = 0; i < 256; i++) + if (notranslate[i]) + usedcolors[i] = false; TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); // Map all untranslated colors into the table of used colors - if (notranslate != NULL) + for (i = 0; i < 256; i++) { - for (i = 0; i < 256; i++) + if (notranslate[i]) { - if (notranslate[i]) - { - PatchRemap[i] = TotalColors; - identity[TotalColors] = i; - TotalColors++; - } + PatchRemap[i] = TotalColors; + identity[TotalColors] = i; + TotalColors++; } } From 79abe2d4e9e4b913c43a05c84396dbbc496441b1 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 3 Mar 2014 01:00:47 +1300 Subject: [PATCH 125/311] Made onground a player property "onground" was a global, despite being treated as a player property and crossed with instances from other players or prediction. --- src/d_player.h | 1 + src/p_user.cpp | 26 +++++++++++++++++--------- src/version.h | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 4da0e9d10..f50db97b1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -434,6 +434,7 @@ public: TObjPtr PremorphWeapon; // ready weapon before morphing int chickenPeck; // chicken peck countdown int jumpTics; // delay the next jump for a moment + bool onground; // Identifies if this player is on the ground or other object int respawn_time; // [RH] delay respawning until this tic TObjPtr camera; // [RH] Whose eyes this player sees through diff --git a/src/p_user.cpp b/src/p_user.cpp index e1b0210ef..90d0dd6cf 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -210,8 +210,6 @@ CCMD (playerclasses) // 16 pixels of bob #define MAXBOB 0x100000 -bool onground; - FArchive &operator<< (FArchive &arc, player_t *&p) { return arc.SerializePointer (players, (BYTE **)&p, sizeof(*players)); @@ -268,6 +266,7 @@ player_t::player_t() PremorphWeapon(0), chickenPeck(0), jumpTics(0), + onground(0), respawn_time(0), camera(0), air_finished(0), @@ -375,6 +374,7 @@ player_t &player_t::operator=(const player_t &p) PremorphWeapon = p.PremorphWeapon; chickenPeck = p.chickenPeck; jumpTics = p.jumpTics; + onground = p.onground; respawn_time = p.respawn_time; camera = p.camera; air_finished = p.air_finished; @@ -1747,7 +1747,7 @@ void P_CalcHeight (player_t *player) { player->bob = 0; } - else if ((player->mo->flags & MF_NOGRAVITY) && !onground) + else if ((player->mo->flags & MF_NOGRAVITY) && !player->onground) { player->bob = FRACUNIT / 2; } @@ -1872,7 +1872,7 @@ void P_MovePlayer (player_t *player) mo->angle += cmd->ucmd.yaw << 16; } - onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); + player->onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); // killough 10/98: // @@ -1890,7 +1890,7 @@ void P_MovePlayer (player_t *player) movefactor = P_GetMoveFactor (mo, &friction); bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; - if (!onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) + if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) { // [RH] allow very limited movement if not on ground. movefactor = FixedMul (movefactor, level.aircontrol); @@ -2061,12 +2061,12 @@ void P_DeathThink (player_t *player) P_MovePsprites (player); - onground = (player->mo->z <= player->mo->floorz); + player->onground = (player->mo->z <= player->mo->floorz); if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk))) { // Flying bloody skull or flying ice chunk player->viewheight = 6 * FRACUNIT; player->deltaviewheight = 0; - if (onground) + if (player->onground) { if (player->mo->pitch > -(int)ANGLE_1*19) { @@ -2365,7 +2365,7 @@ void P_PlayerThink (player_t *player) if (player->jumpTics != 0) { player->jumpTics--; - if (onground && player->jumpTics < -18) + if (player->onground && player->jumpTics < -18) { player->jumpTics = 0; } @@ -2465,7 +2465,7 @@ void P_PlayerThink (player_t *player) { player->mo->velz = 3*FRACUNIT; } - else if (level.IsJumpingAllowed() && onground && player->jumpTics == 0) + else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0) { fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE; @@ -2877,6 +2877,14 @@ void player_t::Serialize (FArchive &arc) { settings_controller = (this - players == Net_Arbitrator); } + if (SaveVersion >= 4505) + { + arc << onground; + } + else + { + onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2); + } if (isbot) { diff --git a/src/version.h b/src/version.h index 66e2f8938..1e328b312 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4504 +#define SAVEVER 4505 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From f44dc926e6880777f96f884b42e4dd95f665b097 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Mar 2014 10:02:07 +0100 Subject: [PATCH 126/311] - fixed uniqueTid logic - patch by Edward-San. --- src/p_mobj.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7dc8a3f46..168d686fe 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2726,16 +2726,15 @@ int P_FindUniqueTID(int start_tid, int limit) if (start_tid != 0) { // Do a linear search. - int end_tid = start_tid; - if (start_tid > 0 && limit > INT_MAX - start_tid + 1) - { // If 'limit+start_tid-1' overflows, clamp 'end_tid' to INT_MAX - end_tid = INT_MAX; + if (start_tid > INT_MAX-limit+1) + { // If 'limit+start_tid-1' overflows, clamp 'limit' to INT_MAX + limit = INT_MAX; } else { - end_tid += limit-1; + limit += start_tid-1; } - for (tid = start_tid; tid <= end_tid; ++tid) + for (tid = start_tid; tid <= limit; ++tid) { if (tid != 0 && !P_IsTIDUsed(tid)) { From 9dad8bdbbed9a7d8c0779b926613825ec8a92374 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Thu, 13 Mar 2014 18:27:39 +1300 Subject: [PATCH 127/311] Clear old camera from previous level The sound code could accidentally reference an old invalid camera during level spawn --- src/g_level.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_level.cpp b/src/g_level.cpp index cf40b5099..65bde08d8 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1084,6 +1084,7 @@ void G_StartTravel () { AActor *pawn = players[i].mo; AInventory *inv; + players[i].camera = NULL; // Only living players travel. Dead ones get a new body on the new level. if (players[i].health > 0) From 40771d22a53dec3f023eae8252f3aaa204267fb1 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 15 Mar 2014 04:15:30 +1300 Subject: [PATCH 128/311] Player prediction fixes in PIT_CheckThing Player prediction could end up executing functions for TOUCHY things or modify velocities when BLASTED, among other things. --- src/p_map.cpp | 66 +++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index d900c2a46..45eb0d95c 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -914,34 +914,34 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } } - // touchy object is alive, toucher is solid - if (thing->flags6 & MF6_TOUCHY && tm.thing->flags & MF_SOLID && thing->health > 0 && - // Thing is an armed mine or a sentient thing - (thing->flags6 & MF6_ARMED || thing->IsSentient()) && - // either different classes or players - (thing->player || thing->GetClass() != tm.thing->GetClass()) && - // or different species if DONTHARMSPECIES - (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && - // touches vertically - thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z && - // prevents lost souls from exploding when fired by pain elementals - (thing->master != tm.thing && tm.thing->master != thing)) - // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species - // but different classes trigger the touchiness, but that seems less straightforwards. + if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)) { - thing->flags6 &= ~MF6_ARMED; // Disarm - P_DamageMobj (thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object - return true; - } + // touchy object is alive, toucher is solid + if (thing->flags6 & MF6_TOUCHY && tm.thing->flags & MF_SOLID && thing->health > 0 && + // Thing is an armed mine or a sentient thing + (thing->flags6 & MF6_ARMED || thing->IsSentient()) && + // either different classes or players + (thing->player || thing->GetClass() != tm.thing->GetClass()) && + // or different species if DONTHARMSPECIES + (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && + // touches vertically + thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z && + // prevents lost souls from exploding when fired by pain elementals + (thing->master != tm.thing && tm.thing->master != thing)) + // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species + // but different classes trigger the touchiness, but that seems less straightforwards. + { + thing->flags6 &= ~MF6_ARMED; // Disarm + P_DamageMobj(thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object + return true; + } - // Check for MF6_BUMPSPECIAL - // By default, only players can activate things by bumping into them - if ((thing->flags6 & MF6_BUMPSPECIAL) && ((tm.thing->player != NULL) - || ((thing->activationtype & THINGSPEC_MonsterTrigger) && (tm.thing->flags3 & MF3_ISMONSTER)) - || ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE)) - ) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away - { - if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)) + // Check for MF6_BUMPSPECIAL + // By default, only players can activate things by bumping into them + if ((thing->flags6 & MF6_BUMPSPECIAL) && ((tm.thing->player != NULL) + || ((thing->activationtype & THINGSPEC_MonsterTrigger) && (tm.thing->flags3 & MF3_ISMONSTER)) + || ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE)) + ) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away { if (P_ActivateThingSpecial(thing, tm.thing)) thing->lastbump = level.maptime + TICRATE; @@ -955,6 +955,17 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) tm.thing->BlockingMobj = NULL; return res; } + + // [ED850] Player Prediction ends here. There is nothing else they could/should do. + if (tm.thing->player != NULL && (tm.thing->player->cheats & CF_PREDICTING)) + { + solid = (thing->flags & MF_SOLID) && + !(thing->flags & MF_NOCLIP) && + ((tm.thing->flags & MF_SOLID) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS)); + + return !solid || unblocking; + } + // Check for blasted thing running into another if ((tm.thing->flags2 & MF2_BLASTED) && (thing->flags & MF_SHOOTABLE)) { @@ -1203,8 +1214,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } return false; // don't traverse any more } - if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH) && - (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING))) + if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) { // Push thing if (thing->lastpush != tm.PushTime) { From 6aa56202b635c7928c1d7601ac43a8d6340d7e6b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 15 Mar 2014 13:17:22 +0200 Subject: [PATCH 129/311] Fix two issues with GL nodes handling Fix inability to load GL nodes for maps with names longer than 5 characters. Fix inability to load GL nodes from external GWA files. --- src/p_glnodes.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index b07d50aed..a8fa04c34 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -724,9 +724,10 @@ static bool DoLoadGLNodes(FileReader ** lumps) static bool MatchHeader(const char * label, const char * hdata) { - if (!memcmp(hdata, "LEVEL=", 6) == 0) + if (memcmp(hdata, "LEVEL=", 6) == 0) { size_t labellen = strlen(label); + labellen = MIN(size_t(8), labellen); if (strnicmp(hdata+6, label, labellen)==0 && (hdata[6+labellen]==0xa || hdata[6+labellen]==0xd)) @@ -771,7 +772,7 @@ static int FindGLNodesInWAD(int labellump) if (Wads.GetLumpFile(lump)==wadfile) { FMemLump mem = Wads.ReadLump(lump); - if (MatchHeader(Wads.GetLumpFullName(labellump), (const char *)mem.GetMem())) return true; + if (MatchHeader(Wads.GetLumpFullName(labellump), (const char *)mem.GetMem())) return lump; } } } @@ -781,7 +782,7 @@ static int FindGLNodesInWAD(int labellump) //=========================================================================== // -// FindGLNodesInWAD +// FindGLNodesInFile // // Looks for GL nodes in the same WAD as the level itself // Function returns the lump number within the file. Returns -1 if the input @@ -929,13 +930,13 @@ bool P_LoadGLNodes(MapData * map) result=true; for(unsigned i=0; i<4;i++) { - if (strnicmp(f_gwa->GetLump(i)->Name, check[i], 8)) + if (strnicmp(f_gwa->GetLump(i+1)->Name, check[i], 8)) { result=false; break; } else - gwalumps[i] = f_gwa->GetLump(i)->NewReader(); + gwalumps[i] = f_gwa->GetLump(i+1)->NewReader(); } if (result) result = DoLoadGLNodes(gwalumps); } From 3c8e9b6dc06cc0fbd2cfeed77e48f58c5438d327 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 16 Mar 2014 12:29:04 +0200 Subject: [PATCH 130/311] Fix incorrect Maulotaur melee attack sound It was STFHIT instead of STFPOW --- wadsrc/static/sndinfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/sndinfo.txt b/wadsrc/static/sndinfo.txt index 49c6279b0..5508cd89b 100644 --- a/wadsrc/static/sndinfo.txt +++ b/wadsrc/static/sndinfo.txt @@ -634,7 +634,7 @@ $limit misc/spawn 1 // minotaur/sight minsit -minotaur/melee stfhit +minotaur/melee stfpow minotaur/attack1 minat1 minotaur/attack2 minat2 minotaur/attack3 minat3 From 5789ac624549907a7ff4c86edce5142083290876 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sun, 16 Mar 2014 13:21:08 +0100 Subject: [PATCH 131/311] - Fixed new[]/delete mismatch in FNodeBuilder Found with address sanitizer. --- src/nodebuild.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index be5d0591d..f3ceec17d 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -90,7 +90,7 @@ FNodeBuilder::~FNodeBuilder() } if (OldVertexTable != NULL) { - delete OldVertexTable; + delete[] OldVertexTable; } } From 6a958b032c2d060bf07530aa314c1173a457c9f6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 18 Mar 2014 12:29:14 +0200 Subject: [PATCH 132/311] Add NOBLOOD flag to Heresiarch actor Heresiarch entity in vanilla Hexen doesn't spawn blood when hit --- wadsrc/static/actors/hexen/heresiarch.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/actors/hexen/heresiarch.txt b/wadsrc/static/actors/hexen/heresiarch.txt index 999f50540..5a77240fc 100644 --- a/wadsrc/static/actors/hexen/heresiarch.txt +++ b/wadsrc/static/actors/hexen/heresiarch.txt @@ -18,6 +18,7 @@ ACTOR Heresiarch 10080 native +NOTARGET +NOICEDEATH +DEFLECT + +NOBLOOD SeeSound "SorcererSight" PainSound "SorcererPain" DeathSound "SorcererDeathScream" From 697ef02871d10c8cd01be7f445eb6f46681fd73f Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Fri, 28 Mar 2014 00:17:32 +1300 Subject: [PATCH 133/311] Added StencilColor to Set/GetActorProperty --- src/p_acs.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 1ed89f783..0a29f48e8 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3529,7 +3529,8 @@ enum APROP_ReactionTime = 37, APROP_MeleeRange = 38, APROP_ViewHeight = 39, - APROP_AttackZOffset = 40 + APROP_AttackZOffset = 40, + APROP_StencilColor = 41 }; // These are needed for ACS's APROP_RenderStyle @@ -3755,6 +3756,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) static_cast(actor)->AttackZOffset = value; break; + case APROP_StencilColor: + actor->SetShade(value); + break; + default: // do nothing. break; @@ -3852,6 +3857,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound, stack, stackdepth); case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); + case APROP_StencilColor:return actor->fillcolor; default: return 0; } From d7a2435703f56ce36c00892f31c3a582bb947b7d Mon Sep 17 00:00:00 2001 From: crimsondusk Date: Thu, 27 Mar 2014 16:34:32 +0200 Subject: [PATCH 134/311] - the ACS functions GetSectorFloorZ and GetSectorCeilingZ now interpret tag=0 as 'any sector' and return the z height of whatever sector is at those coordinates. --- src/p_acs.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 1ed89f783..10aa79bec 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -7874,14 +7874,22 @@ scriptwait: case PCD_GETSECTORCEILINGZ: // Arguments are (tag, x, y). If you don't use slopes, then (x, y) don't // really matter and can be left as (0, 0) if you like. + // [Dusk] If tag = 0, then this returns the z height at whatever sector + // is in x, y. { - int secnum = P_FindSectorFromTag (STACK(3), -1); + int tag = STACK(3); + int secnum; + fixed_t x = STACK(2) << FRACBITS; + fixed_t y = STACK(1) << FRACBITS; fixed_t z = 0; + if (tag != 0) + secnum = P_FindSectorFromTag (tag, -1); + else + secnum = P_PointInSector (x, y) - sectors; + if (secnum >= 0) { - fixed_t x = STACK(2) << FRACBITS; - fixed_t y = STACK(1) << FRACBITS; if (pcd == PCD_GETSECTORFLOORZ) { z = sectors[secnum].floorplane.ZatPoint (x, y); From a97b068ed7df7ff0f04d521b69f5d81392a3e8ee Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 30 Mar 2014 13:27:27 +0300 Subject: [PATCH 135/311] Enable fighting between different types of gargoyles and golems In vanilla Heretic: - Gargoyles are able to fight with Fire Gargoyles - Golems are able to fight with Nitro Golems, both regular and ghosted versions --- wadsrc/static/actors/heretic/hereticimp.txt | 1 + wadsrc/static/actors/heretic/mummy.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/wadsrc/static/actors/heretic/hereticimp.txt b/wadsrc/static/actors/heretic/hereticimp.txt index 25f64a2ea..2659d248a 100644 --- a/wadsrc/static/actors/heretic/hereticimp.txt +++ b/wadsrc/static/actors/heretic/hereticimp.txt @@ -82,6 +82,7 @@ ACTOR HereticImpLeader : HereticImp 5 { Game Heretic SpawnID 7 + Species "HereticImpLeader" Health 80 -MISSILEMORE AttackSound "himp/leaderattack" diff --git a/wadsrc/static/actors/heretic/mummy.txt b/wadsrc/static/actors/heretic/mummy.txt index c6cc2389b..af4ff0c23 100644 --- a/wadsrc/static/actors/heretic/mummy.txt +++ b/wadsrc/static/actors/heretic/mummy.txt @@ -55,6 +55,7 @@ ACTOR MummyLeader : Mummy 45 { Game Heretic SpawnID 2 + Species "MummyLeader" Health 100 Painchance 64 Obituary "$OB_MUMMYLEADER" @@ -89,6 +90,7 @@ ACTOR MummyLeaderGhost : MummyLeader 46 { Game Heretic SpawnID 9 + Species "MummyLeaderGhost" +SHADOW +GHOST RenderStyle Translucent From c47d77228d08840503aeeb7c4acd9e431193b9e1 Mon Sep 17 00:00:00 2001 From: crimsondusk Date: Sun, 30 Mar 2014 21:27:05 +0300 Subject: [PATCH 136/311] - increased updaterevision's buffer sizes to prevent GIT_BRANCH from cut short --- tools/updaterevision/updaterevision.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/updaterevision/updaterevision.c b/tools/updaterevision/updaterevision.c index 90127130a..6ccf174d0 100644 --- a/tools/updaterevision/updaterevision.c +++ b/tools/updaterevision/updaterevision.c @@ -34,7 +34,7 @@ void stripnl(char *str) int main(int argc, char **argv) { - char vertag[64], lastlog[64], lasthash[64], *hash = NULL; + char vertag[128], lastlog[128], lasthash[128], *hash = NULL; FILE *stream = NULL; int gotrev = 0, needupdate = 1; From 79f6e77e2ba617e3496f7178a94811dbabad3092 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 31 Mar 2014 23:49:21 +1300 Subject: [PATCH 137/311] Remove garbage characters from info CCMD --- src/p_mobj.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 168d686fe..545052af8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6167,25 +6167,25 @@ void PrintMiscActorInfo(AActor *query) static const char * renderstyles[]= {"None", "Normal", "Fuzzy", "SoulTrans", "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil"}; - Printf("%s @ %p has the following flags:\n\tflags: %x", query->GetTag(), query, query->flags); + Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags); for (flagi = 0; flagi <= 31; flagi++) if (query->flags & 1<flags2); + Printf("\n flags2: %x", query->flags2); for (flagi = 0; flagi <= 31; flagi++) if (query->flags2 & 1<flags3); + Printf("\n flags3: %x", query->flags3); for (flagi = 0; flagi <= 31; flagi++) if (query->flags3 & 1<flags4); + Printf("\n flags4: %x", query->flags4); for (flagi = 0; flagi <= 31; flagi++) if (query->flags4 & 1<flags5); + Printf("\n flags5: %x", query->flags5); for (flagi = 0; flagi <= 31; flagi++) if (query->flags5 & 1<flags6); + Printf("\n flags6: %x", query->flags6); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + Printf("\nflags7: %x", query->flags7); for (flagi = 0; flagi <= 31; flagi++) if (query->flags7 & 1< Date: Mon, 31 Mar 2014 23:57:43 +1300 Subject: [PATCH 138/311] Missed space in flags7 line. --- src/p_mobj.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 545052af8..75df3bb3e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2936,7 +2936,7 @@ bool AActor::IsOkayToAttack (AActor *link) if (P_CheckSight (this, link)) { // AMageStaffFX2::IsOkayToAttack had an extra check here, generalized with a flag, - // to only allow the check to succeed if the enemy was in a ~84° FOV of the player + // to only allow the check to succeed if the enemy was in a ~84� FOV of the player if (flags3 & MF3_SCREENSEEKER) { angle_t angle = R_PointToAngle2(Friend->x, @@ -6185,7 +6185,7 @@ void PrintMiscActorInfo(AActor *query) Printf("\n flags6: %x", query->flags6); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + Printf("\n flags7: %x", query->flags7); for (flagi = 0; flagi <= 31; flagi++) if (query->flags7 & 1< Date: Mon, 31 Mar 2014 16:39:34 +0200 Subject: [PATCH 139/311] fixed: APROP_StencilColor was not implemented for CheckActorProperty. --- src/p_acs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 0a29f48e8..5f6af9408 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3904,6 +3904,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_MeleeRange: case APROP_ViewHeight: case APROP_AttackZOffset: + case APROP_StencilColor: return (GetActorProperty(tid, property, NULL, 0) == value); // Boolean values need to compare to a binary version of value From be33d2894ac59be3d8424f145113cb8248645b2f Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 1 Apr 2014 23:05:08 +1300 Subject: [PATCH 140/311] Fixed prediction thinglist order restoration Prediction didn't take sector_thinglist and thinglist order into account. This notably broke the order in which things were damaged. --- src/p_user.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 90d0dd6cf..f792cf1d1 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -65,6 +65,8 @@ CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) static player_t PredictionPlayerBackup; static BYTE PredictionActorBackup[sizeof(AActor)]; static TArray PredictionTouchingSectorsBackup; +static TArray PredictionSectorListBackup; +static TArray PredictionSector_sprev_Backup; // [GRB] Custom player classes TArray PlayerClasses; @@ -2661,15 +2663,41 @@ void P_PredictPlayer (player_t *player) player->cheats |= CF_PREDICTING; // The ordering of the touching_sectorlist needs to remain unchanged + // Also store a copy of all previous sector_thinglist nodes msecnode_t *mnode = act->touching_sectorlist; + msecnode_t *snode; + PredictionSector_sprev_Backup.Clear(); PredictionTouchingSectorsBackup.Clear (); while (mnode != NULL) { PredictionTouchingSectorsBackup.Push (mnode->m_sector); + + for (snode = mnode->m_sector->touching_thinglist; snode; snode = snode->m_snext) + { + if (snode->m_thing == act) + { + PredictionSector_sprev_Backup.Push(snode->m_sprev); + break; + } + } + mnode = mnode->m_tnext; } + // Keep an ordered list off all actors in the linked sector. + PredictionSectorListBackup.Clear(); + if (!(act->flags & MF_NOSECTOR)) + { + AActor *link = act->Sector->thinglist; + + while (link != NULL) + { + PredictionSectorListBackup.Push(link); + link = link->snext; + } + } + // Blockmap ordering also needs to stay the same, so unlink the block nodes // without releasing them. (They will be used again in P_UnpredictPlayer). FBlockNode *block = act->BlockNode; @@ -2701,6 +2729,7 @@ void P_UnPredictPlayer () if (player->cheats & CF_PREDICTING) { + unsigned int i; AActor *act = player->mo; AActor *savedcamera = player->camera; @@ -2710,23 +2739,93 @@ void P_UnPredictPlayer () // could cause it to change during prediction. player->camera = savedcamera; - act->UnlinkFromWorld (); - memcpy (&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x-(BYTE *)act)); + act->UnlinkFromWorld(); + memcpy(&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x - (BYTE *)act)); // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist (sector_list); + P_DelSeclist(sector_list); sector_list = NULL; - for (unsigned int i = PredictionTouchingSectorsBackup.Size (); i-- > 0; ) + for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - sector_list = P_AddSecnode (PredictionTouchingSectorsBackup[i], act, sector_list); + sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); } // The blockmap ordering needs to remain unchanged, too. Right now, act has the right // pointers, so temporarily set its MF_NOBLOCKMAP flag so that LinkToWorld() does not // mess with them. - act->flags |= MF_NOBLOCKMAP; - act->LinkToWorld (); - act->flags &= ~MF_NOBLOCKMAP; + { + DWORD keepflags = act->flags; + act->flags |= MF_NOBLOCKMAP; + act->LinkToWorld(); + act->flags = keepflags; + } + + // Restore sector links. + if (!(act->flags & MF_NOSECTOR)) + { + sector_t *sec = act->Sector; + AActor *me, *next; + AActor **link;// , **prev; + + // The thinglist is just a pointer chain. We are restoring the exact same things, so we can NULL the head safely + sec->thinglist = NULL; + + // [ED850] It doesn't look like I need this method. I'll keep it just incase something crops up, however. + /*for (i = PredictionSectorListBackup.Size(); i-- > 0;) + { + me = PredictionSectorListBackup[i]; + prev = me->sprev; + next = me->snext; + + if (prev != NULL) // prev will be NULL if this actor gets deleted due to cleaning up from a broken savegame + { + if ((*prev = next)) // unlink from sector list + next->sprev = prev; + me->snext = NULL; + me->sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! + } + }*/ + + for (i = PredictionSectorListBackup.Size(); i-- > 0;) + { + me = PredictionSectorListBackup[i]; + link = &sec->thinglist; + next = *link; + if ((me->snext = next)) + next->sprev = &me->snext; + me->sprev = link; + *link = me; + } + + // Restore sector thinglist order + for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) + { + msecnode_t *snode; + + for (snode = PredictionTouchingSectorsBackup[i]->touching_thinglist; snode; snode = snode->m_snext) + { + // If we were already the head, none of this is needed + if (snode->m_thing == act && PredictionSector_sprev_Backup[i]) + { + if (snode->m_sprev) + snode->m_sprev->m_snext = snode->m_snext; + else + snode->m_sector->touching_thinglist = snode->m_snext; + if (snode->m_snext) + snode->m_snext->m_sprev = snode->m_sprev; + + snode->m_sprev = PredictionSector_sprev_Backup[i]; + + // At the moment, we don't exist in the list anymore, but we do know what our previous node is, so we set its current m_snext->m_sprev to us. + if (snode->m_sprev->m_snext) + snode->m_sprev->m_snext->m_sprev = snode; + snode->m_snext = snode->m_sprev->m_snext; + snode->m_sprev->m_snext = snode; + break; + } + } + } + } // Now fix the pointers in the blocknode chain FBlockNode *block = act->BlockNode; From 546ae759fdf3abb27f01f0b70ff550e703d917b0 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Wed, 2 Apr 2014 21:12:10 +1300 Subject: [PATCH 141/311] Cleanup old prediction fix development code --- src/p_user.cpp | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index f792cf1d1..ea7b315d8 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2770,22 +2770,6 @@ void P_UnPredictPlayer () // The thinglist is just a pointer chain. We are restoring the exact same things, so we can NULL the head safely sec->thinglist = NULL; - // [ED850] It doesn't look like I need this method. I'll keep it just incase something crops up, however. - /*for (i = PredictionSectorListBackup.Size(); i-- > 0;) - { - me = PredictionSectorListBackup[i]; - prev = me->sprev; - next = me->snext; - - if (prev != NULL) // prev will be NULL if this actor gets deleted due to cleaning up from a broken savegame - { - if ((*prev = next)) // unlink from sector list - next->sprev = prev; - me->snext = NULL; - me->sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! - } - }*/ - for (i = PredictionSectorListBackup.Size(); i-- > 0;) { me = PredictionSectorListBackup[i]; @@ -2797,15 +2781,18 @@ void P_UnPredictPlayer () *link = me; } + msecnode_t *snode; + // Restore sector thinglist order for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - msecnode_t *snode; + // If we were already the head node, then nothing needs to change + if (PredictionSector_sprev_Backup[i] == NULL) + continue; for (snode = PredictionTouchingSectorsBackup[i]->touching_thinglist; snode; snode = snode->m_snext) { - // If we were already the head, none of this is needed - if (snode->m_thing == act && PredictionSector_sprev_Backup[i]) + if (snode->m_thing == act) { if (snode->m_sprev) snode->m_sprev->m_snext = snode->m_snext; From 3670acbe63f07583d03c165055303f3e76ddc398 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 08:44:33 -0500 Subject: [PATCH 142/311] Don't compile some unused DUMB tables spotted by Clang --- dumb/src/it/itrender.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dumb/src/it/itrender.c b/dumb/src/it/itrender.c index 4f3d50dfa..d4678ab4f 100644 --- a/dumb/src/it/itrender.c +++ b/dumb/src/it/itrender.c @@ -3950,6 +3950,7 @@ static int delta_to_note(float delta, int base) return (int)note; } +#if 0 // Period table for Protracker octaves 0-5: static const unsigned short ProTrackerPeriodTable[6*12] = { @@ -3981,6 +3982,7 @@ static const unsigned short ProTrackerTunedPeriods[16*12] = 1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920, 1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914 }; +#endif static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer) { @@ -4400,6 +4402,7 @@ static int process_tick(DUMB_IT_SIGRENDERER *sigrenderer) int dumb_it_max_to_mix = 64; +#if 0 static const int aiMODVol[] = { 0, @@ -4425,6 +4428,7 @@ static const int aiPTMVolScaled[] = 836, 847, 859, 870, 881, 897, 908, 916, 927, 939, 950, 962, 969, 983, 1005, 1024 }; +#endif static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, double volume) { From 4406578522f991e7f1edcc54a38aa788993edec7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 08:46:47 -0500 Subject: [PATCH 143/311] Fixed: DSMF loader wrote outside filename array's bounds --- dumb/src/it/readdsmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dumb/src/it/readdsmf.c b/dumb/src/it/readdsmf.c index 5db09a75c..be545a678 100644 --- a/dumb/src/it/readdsmf.c +++ b/dumb/src/it/readdsmf.c @@ -31,8 +31,8 @@ static int it_riff_dsmf_process_sample( IT_SAMPLE * sample, const unsigned char int flags; memcpy( sample->filename, data, 13 ); - sample->filename[ 14 ] = 0; - + sample->filename[ 13 ] = 0; + flags = data[ 13 ] | ( data[ 14 ] << 8 ); sample->default_volume = data[ 15 ]; sample->length = data[ 16 ] | ( data[ 17 ] << 8 ) | ( data[ 18 ] << 16 ) | ( data[ 19 ] << 24 ); From 1d1289722f14bea9f32fbaad3a0c7a151f838c66 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 08:50:09 -0500 Subject: [PATCH 144/311] Change , to && in 2 for loops in Oktalyzer loader - For something like i < n_chnnels, j < 4 , the first condition is completely unused, so why put it in the for loop at all? I assume these are supposed to be binary-and and not sequences. --- dumb/src/it/readokt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dumb/src/it/readokt.c b/dumb/src/it/readokt.c index 078929c5c..b662e55c4 100644 --- a/dumb/src/it/readokt.c +++ b/dumb/src/it/readokt.c @@ -486,7 +486,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f) /* And finally, the sample data */ k = get_chunk_count(mod, DUMB_ID('S','B','O','D')); - for (i = 0, j = 0; i < (unsigned)sigdata->n_samples, j < k; i++) { + for (i = 0, j = 0; i < (unsigned)sigdata->n_samples && j < k; i++) { if (sigdata->sample[i].flags & IT_SAMPLE_EXISTS) { chunk = get_chunk_by_type(mod, DUMB_ID('S','B','O','D'), j); if (it_okt_read_sample_data(&sigdata->sample[i], (const char *)chunk->data, chunk->size)) { @@ -503,7 +503,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f) chunk = get_chunk_by_type(mod, DUMB_ID('C','M','O','D'), 0); - for (i = 0, j = 0; i < n_channels, j < 4; j++) { + for (i = 0, j = 0; i < n_channels && j < 4; j++) { k = (chunk->data[j * 2] << 8) | chunk->data[j * 2 + 1]; l = (j == 1 || j == 2) ? 48 : 16; if (k == 0) { From fbddfbe57658cc3d94d32dc86ecc3b3903ce1858 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 09:18:00 -0500 Subject: [PATCH 145/311] Upgrade game-music-emu to version 0.6.0 --- game-music-emu/CMakeLists.txt | 139 ++++++++++++++--------- game-music-emu/changes.txt | 44 ++++++++ game-music-emu/design.txt | 2 +- game-music-emu/gme.txt | 118 +++----------------- game-music-emu/gme/Ay_Apu.cpp | 12 +- game-music-emu/gme/Ay_Apu.h | 3 +- game-music-emu/gme/Ay_Cpu.cpp | 17 +-- game-music-emu/gme/Ay_Cpu.h | 2 +- game-music-emu/gme/Ay_Emu.cpp | 18 +-- game-music-emu/gme/Ay_Emu.h | 3 +- game-music-emu/gme/Blip_Buffer.cpp | 34 ++++-- game-music-emu/gme/CMakeLists.txt | 153 ++++++++++++++++++++++++++ game-music-emu/gme/Classic_Emu.cpp | 10 +- game-music-emu/gme/Classic_Emu.h | 2 +- game-music-emu/gme/Data_Reader.cpp | 17 ++- game-music-emu/gme/Data_Reader.h | 3 +- game-music-emu/gme/Dual_Resampler.cpp | 14 ++- game-music-emu/gme/Dual_Resampler.h | 2 +- game-music-emu/gme/Effects_Buffer.cpp | 2 +- game-music-emu/gme/Effects_Buffer.h | 2 +- game-music-emu/gme/Fir_Resampler.cpp | 6 +- game-music-emu/gme/Fir_Resampler.h | 12 +- game-music-emu/gme/Gb_Apu.cpp | 2 +- game-music-emu/gme/Gb_Cpu.cpp | 7 +- game-music-emu/gme/Gb_Cpu.h | 2 +- game-music-emu/gme/Gbs_Emu.cpp | 23 ++-- game-music-emu/gme/Gbs_Emu.h | 2 +- game-music-emu/gme/Gme_File.cpp | 6 +- game-music-emu/gme/Gme_File.h | 2 +- game-music-emu/gme/Gym_Emu.cpp | 2 +- game-music-emu/gme/Gym_Emu.h | 2 +- game-music-emu/gme/Hes_Apu.cpp | 10 +- game-music-emu/gme/Hes_Apu.h | 2 +- game-music-emu/gme/Hes_Cpu.cpp | 16 +-- game-music-emu/gme/Hes_Cpu.h | 2 +- game-music-emu/gme/Hes_Emu.cpp | 16 +-- game-music-emu/gme/Hes_Emu.h | 2 +- game-music-emu/gme/Kss_Cpu.cpp | 17 +-- game-music-emu/gme/Kss_Cpu.h | 2 +- game-music-emu/gme/Kss_Emu.cpp | 14 +-- game-music-emu/gme/Kss_Emu.h | 3 +- game-music-emu/gme/Kss_Scc_Apu.cpp | 2 +- game-music-emu/gme/Kss_Scc_Apu.h | 2 +- game-music-emu/gme/M3u_Playlist.cpp | 10 +- game-music-emu/gme/M3u_Playlist.h | 4 +- game-music-emu/gme/Multi_Buffer.cpp | 2 +- game-music-emu/gme/Music_Emu.cpp | 12 +- game-music-emu/gme/Music_Emu.h | 23 +++- game-music-emu/gme/Nes_Apu.cpp | 2 +- game-music-emu/gme/Nes_Cpu.cpp | 8 +- game-music-emu/gme/Nes_Cpu.h | 2 +- game-music-emu/gme/Nes_Fme7_Apu.cpp | 4 +- game-music-emu/gme/Nes_Fme7_Apu.h | 6 +- game-music-emu/gme/Nsf_Emu.cpp | 10 +- game-music-emu/gme/Nsf_Emu.h | 2 +- game-music-emu/gme/Nsfe_Emu.cpp | 12 +- game-music-emu/gme/Nsfe_Emu.h | 2 +- game-music-emu/gme/Sap_Apu.cpp | 8 +- game-music-emu/gme/Sap_Apu.h | 2 +- game-music-emu/gme/Sap_Cpu.cpp | 8 +- game-music-emu/gme/Sap_Cpu.h | 2 +- game-music-emu/gme/Sap_Emu.cpp | 14 +-- game-music-emu/gme/Sap_Emu.h | 2 +- game-music-emu/gme/Sms_Apu.cpp | 2 +- game-music-emu/gme/Snes_Spc.cpp | 4 +- game-music-emu/gme/Snes_Spc.h | 35 +++--- game-music-emu/gme/Spc_Cpu.cpp | 15 +-- game-music-emu/gme/Spc_Cpu.h | 18 +-- game-music-emu/gme/Spc_Dsp.cpp | 9 +- game-music-emu/gme/Spc_Dsp.h | 14 +-- game-music-emu/gme/Spc_Emu.cpp | 44 ++++++-- game-music-emu/gme/Spc_Emu.h | 7 +- game-music-emu/gme/Spc_Filter.cpp | 83 ++++++++++++++ game-music-emu/gme/Spc_Filter.h | 53 +++++++++ game-music-emu/gme/Vgm_Emu.cpp | 15 ++- game-music-emu/gme/Vgm_Emu.h | 2 +- game-music-emu/gme/Vgm_Emu_Impl.cpp | 4 +- game-music-emu/gme/Vgm_Emu_Impl.h | 2 +- game-music-emu/gme/Ym2413_Emu.cpp | 2 +- game-music-emu/gme/Ym2413_Emu.h | 2 +- game-music-emu/gme/Ym2612_Emu.cpp | 2 +- game-music-emu/gme/Ym2612_Emu.h | 2 +- game-music-emu/gme/blargg_common.h | 41 +++++-- game-music-emu/gme/blargg_config.h | 20 +++- game-music-emu/gme/blargg_endian.h | 114 +++++++++++-------- game-music-emu/gme/blargg_source.h | 44 +++++++- game-music-emu/gme/gb_cpu_io.h | 10 +- game-music-emu/gme/gme.cpp | 144 ++++++++++++++---------- game-music-emu/gme/gme.h | 112 ++++++++----------- game-music-emu/gme/gme_types.h | 21 ++++ game-music-emu/gme/gme_types.h.in | 23 ++++ game-music-emu/gme/hes_cpu_io.h | 2 +- game-music-emu/gme/nes_cpu_io.h | 2 +- game-music-emu/gme/sap_cpu_io.h | 2 +- game-music-emu/readme.txt | 53 +++++---- 95 files changed, 1139 insertions(+), 650 deletions(-) create mode 100644 game-music-emu/gme/CMakeLists.txt create mode 100644 game-music-emu/gme/Spc_Filter.cpp create mode 100644 game-music-emu/gme/Spc_Filter.h create mode 100644 game-music-emu/gme/gme_types.h create mode 100644 game-music-emu/gme/gme_types.h.in diff --git a/game-music-emu/CMakeLists.txt b/game-music-emu/CMakeLists.txt index f880023ab..d0cc7af5f 100644 --- a/game-music-emu/CMakeLists.txt +++ b/game-music-emu/CMakeLists.txt @@ -1,5 +1,15 @@ -cmake_minimum_required( VERSION 2.4 ) -include( CheckCXXCompilerFlag ) +# CMake project definition file. +project(libgme) + +include (CheckCXXCompilerFlag) + +# When version is changed, also change the one in gme/gme.h to match +set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version") + +# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't. +# Of course, 2.4 might work, in which case you're welcome to drop +# down the requirement, but I can't test that. +cmake_minimum_required(VERSION 2.6 FATAL_ERROR) make_release_only() @@ -19,51 +29,80 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE endif( HAVE_NO_ARRAY_BOUNDS ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) -add_library( gme - gme/Blip_Buffer.cpp - gme/Classic_Emu.cpp - gme/Data_Reader.cpp - gme/Dual_Resampler.cpp - gme/Effects_Buffer.cpp - gme/Fir_Resampler.cpp - gme/gme.cpp - gme/Gme_File.cpp - gme/M3u_Playlist.cpp - gme/Multi_Buffer.cpp - gme/Music_Emu.cpp - - gme/Ay_Apu.cpp - gme/Ay_Cpu.cpp - gme/Ay_Emu.cpp - gme/Gb_Apu.cpp - gme/Gb_Cpu.cpp - gme/Gb_Oscs.cpp - gme/Gbs_Emu.cpp - gme/Gym_Emu.cpp - gme/Hes_Apu.cpp - gme/Hes_Cpu.cpp - gme/Hes_Emu.cpp - gme/Kss_Cpu.cpp - gme/Kss_Emu.cpp - gme/Kss_Scc_Apu.cpp - gme/Nes_Apu.cpp - gme/Nes_Cpu.cpp - gme/Nes_Fme7_Apu.cpp - gme/Nes_Namco_Apu.cpp - gme/Nes_Oscs.cpp - gme/Nes_Vrc6_Apu.cpp - gme/Nsf_Emu.cpp - gme/Nsfe_Emu.cpp - gme/Sap_Apu.cpp - gme/Sap_Cpu.cpp - gme/Sap_Emu.cpp - gme/Sms_Apu.cpp - gme/Snes_Spc.cpp - gme/Spc_Cpu.cpp - gme/Spc_Dsp.cpp - gme/Spc_Emu.cpp - gme/Vgm_Emu.cpp - gme/Vgm_Emu_Impl.cpp - gme/Ym2413_Emu.cpp - gme/Ym2612_Emu.cpp ) -target_link_libraries( gme ) + + +# Default emulators to build (all of them! ;) +if (NOT DEFINED USE_GME_AY) + SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation") +endif() + +if (NOT DEFINED USE_GME_GBS) + SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation") +endif() + +if (NOT DEFINED USE_GME_GYM) + SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation") +endif() + +if (NOT DEFINED USE_GME_HES) + SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation") +endif() + +if (NOT DEFINED USE_GME_KSS) + SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation") +endif() + +if (NOT DEFINED USE_GME_NSF) + SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation") +endif() + +if (NOT DEFINED USE_GME_NSFE) + SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation") +endif() + +if (NOT DEFINED USE_GME_SAP) + SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation") +endif() + +if (NOT DEFINED USE_GME_SPC) + SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation") +endif() + +if (NOT DEFINED USE_GME_VGM) + SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation") +endif() + +if (USE_GME_NSFE AND NOT USE_GME_NSF) + MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --") + SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE) +endif() + +# Check for GCC "visibility" support. +if (CMAKE_COMPILER_IS_GNUCXX) + check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY) + set (ENABLE_VISIBILITY OFF) + if (__LIBGME_TEST_VISIBILITY) + # get the gcc version + exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info) + string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}") + + # gcc <4.1 had poor support for symbol visibility + if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1")) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + set (ENABLE_VISIBILITY ON) + add_definitions (-DLIBGME_VISIBILITY) + + # GCC >= 4.2 also correctly supports making inline members have hidden + # visibility by default. + if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2")) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") + endif() + endif() + endif() # test visibility +endif (CMAKE_COMPILER_IS_GNUCXX) + +# Cache this result +set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility") + +# Shared library defined here +add_subdirectory(gme) diff --git a/game-music-emu/changes.txt b/game-music-emu/changes.txt index 0405b5904..3e422988c 100644 --- a/game-music-emu/changes.txt +++ b/game-music-emu/changes.txt @@ -1,6 +1,50 @@ Game_Music_Emu Change Log ------------------------- +Game_Music_Emu 0.6.0 +-------------------- + +- Note: A 0.5.6 release was referenced but never tagged or packaged. + +- SPC improvements: + - Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP. + - Fixed Spc_Emu::gain(). + - Fixed support for files <0x10200 bytes. + +- Other bugfixes: + - Fixed a couple of GBS bugs, one involving access of memory after + realloc. + - Blip_Buffer works on systems where 'double' is a single-precision + floating-point type. + - Fix uninitialized buffer size in dual_resampler. + - Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2. + +- API changes/additions: + - Removed documentation of C++ interface, as the C interface in gme.h is + the only supported one. + - Added gme_enable_accuracy() for enabling more accurate sound emulation + options (currently affects SPC only). + +- Build system improvements: + - Add pkg_config support. + - Fix build on case-insensitive systems. + - Allow for install on Cygwin. + - Fix install on multilib systems, such as many 64-bit distros (CMake must + be able to figure out your system's libsuffix, if any). + - C++ implementation symbols are not leaked into the resultant library + file (requires symbol visibility support). + +- Sample player improvements: + - Can toggle fast/accurate emulation (with the 'A' key). + +Game_Music_Emu 0.5.5 +-------------------- +- CMake build support has been added. You can build Game_Music_Emu as +a shared library and install it so that you do not have to include your +own copy if you know libgme will be present on your target system. +Requires CMake 2.6 or higher. + + Game_Music_Emu 0.5.2 -------------------- - *TONS* of changes and improvements. You should re-read the new header diff --git a/game-music-emu/design.txt b/game-music-emu/design.txt index 8c8c65b14..d42cadb12 100644 --- a/game-music-emu/design.txt +++ b/game-music-emu/design.txt @@ -1,4 +1,4 @@ -Game_Music_Emu 0.5.2 Design +Game_Music_Emu 0.6.0 Design --------------------------- This might be slightly out-of-date at times, but will be a big help in understanding the library implementation. diff --git a/game-music-emu/gme.txt b/game-music-emu/gme.txt index 2c963d8e3..98971f787 100644 --- a/game-music-emu/gme.txt +++ b/game-music-emu/gme.txt @@ -1,15 +1,14 @@ -Game_Music_Emu 0.5.2 +Game_Music_Emu 0.6.0 -------------------- Author : Shay Green Website: http://www.slack.net/~ant/libs/ Forum : http://groups.google.com/group/blargg-sound-libs +Source : https://code.google.com/p/game-music-emu/ License: GNU Lesser General Public License (LGPL) Contents -------- * Overview -* C and C++ interfaces -* Function reference * Error handling * Emulator types * M3U playlist support @@ -21,7 +20,6 @@ Contents * Modular construction * Obscure features * Solving problems -* Deprecated features * Thanks @@ -62,56 +60,15 @@ deleted with gme_set_user_cleanup() Refer to gme.h for a comprehensive summary of features. -C and C++ interfaces --------------------- -While the library is written in C++, an extensive C interface is -provided in gme.h. This C interface will be referred to throughout this -documentation unless a feature is only available in the full C++ -interface. All C interface functions and other names have the gme_ -prefix, so you can recognize a C++-only feature by the lack of gme_ in -the names used (contact me if you'd like a feature added to the C -interface). If you're building a shared library, I highly recommend -sticking to the C interface only, because it will be more stable between -releases of the library than the C++ interface. Finally, the C and C++ -interfaces can be freely mixed without problems. Compare demo/basics.c -with demo/cpp_basics.cpp to see how the C and C++ interfaces translate -between each other. - - -Function reference ------------------- -Read the following header files for a complete reference to functions -and features. The second group of header files can only be used in C++. - -blargg_config.h Library configuration -gme.h C interface (also usable from C++) - -Gme_File.h File loading and track information -Music_Emu.h Track playback and adjustments -Data_Reader.h Custom data readers -Effects_Buffer.h Sound buffer with adjustable stereo echo and panning -M3u_Playlist.h M3U playlist support -Gbs_Emu.h GBS equalizer settings -Nsf_Emu.h NSF equalizer settings -Spc_Emu.h SPC surround disable -Vgm_Emu.h VGM oversampling disable and custom buffer query - - Error handling -------------- -Functions which can fail have a return type of gme_err_t (blargg_err_t -in the C++ interfaces), which is a pointer to an error string (const -char*). If a function is successful it returns NULL. Errors that you can -easily avoid are checked with debug assertions; gme_err_t return values -are only used for genuine run-time errors that can't be easily predicted -in advance (out of memory, I/O errors, incompatible file data). Your -code should check all error values. - -To improve usability for C programmers, C++ programmers unfamiliar with -exceptions, and compatibility with older C++ compilers, the library does -*not* throw any C++ exceptions and uses malloc() instead of the standard -operator new. This means that you *must* check for NULL when creating a -library object with the new operator. +Functions which can fail have a return type of gme_err_t, which is a +pointer to an error string (const char*). If a function is successful it +returns NULL. Errors that you can easily avoid are checked with debug +assertions; gme_err_t return values are only used for genuine run-time +errors that can't be easily predicted in advance (out of memory, I/O +errors, incompatible file data). Your code should check all error +values. When loading a music file in the wrong emulator or trying to load a non-music file, gme_wrong_file_type is returned. You can check for this @@ -154,7 +111,9 @@ If you want to remove support for some music types to reduce your executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to support just NSF and GBS, use this: - #define GME_TYPE_LIST gme_nsf_type, gme_gbs_type + #define GME_TYPE_LIST \ + gme_nsf_type,\ + gme_gbs_type M3U playlist support @@ -271,40 +230,6 @@ create an emulator, you can use the following methods of loading: error = gme_load_custom( emu, my_read, file_size, my_data ); -* If you must load the file data into memory yourself, you can have the -library use your data directly *without* making a copy. If you do this, -you must not free the data until you're done playing the file. - - error = emu->load_mem( pointer, size ); - -* If you've already read the first bytes of a file (perhaps to determine -the file type) and want to avoid seeking back to the beginning for -performance reasons, use Remaining_Reader: - - Std_File_Reader in; - error = in.open( file_path ); - - char header [4]; - error = in.read( &header, sizeof header ); - ... - - Remaining_Reader rem( &header, sizeof header, &in ); - error = emu->load( rem ); - -If you merely need access to a file's header after loading, use the -emulator-specific header() functions, after casting the Music_Emu -pointer to the specific emulator's type. This example examines the -chip_flags field of the header if it's an NSF file: - - if ( music_emu->type() == gme_nsf_type ) - { - Nsf_Emu* nsf_emu = (Nsf_Emu*) music_emu; - if ( nsf_emu->header().chip_flags & 0x01 ) - ... - } - -Contact me if you want more information about loading files. - Sound parameters ---------------- @@ -437,21 +362,6 @@ separate threads. * If all else fails, see if the demos work. -Deprecated features -------------------- -The following functions and other features have been deprecated and will -be removed in a future release of the library. Alternatives to the -deprecated features are listed to the right. - -Music_Emu::error_count() warning() -load( header, reader ) see "Loading file data" above -Spc_Emu::trailer() track_info() -Spc_Emu::trailer_size() -Gym_Emu::track_length() track_info() -Vgm_Emu::gd3_data() track_info() -Nsfe_Emu::disable_playlist() clear_playlist() - - Thanks ------ Big thanks to Chris Moeller (kode54) for help with library testing and @@ -461,4 +371,6 @@ Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz, nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using, and giving feedback for the library in their respective game music -players. +players. More recently, Lucas Paul and Michael Pyne have helped nudge the +library into a public repository and get its interface more stable for use +in shared libraries. diff --git a/game-music-emu/gme/Ay_Apu.cpp b/game-music-emu/gme/Ay_Apu.cpp index 8c1c43a0f..c1405231d 100644 --- a/game-music-emu/gme/Ay_Apu.cpp +++ b/game-music-emu/gme/Ay_Apu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Ay_Apu.h" @@ -123,8 +123,8 @@ void Ay_Apu::write_data_( int addr, int data ) if ( (unsigned) addr >= 14 ) { - #ifdef dprintf - dprintf( "Wrote to I/O port %02X\n", (int) addr ); + #ifdef debug_printf + debug_printf( "Wrote to I/O port %02X\n", (int) addr ); #endif } @@ -220,7 +220,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time ) end_time = final_end_time; //if ( !(regs [12] | regs [11]) ) - // dprintf( "Used envelope period 0\n" ); + // debug_printf( "Used envelope period 0\n" ); } else if ( !volume ) { @@ -250,7 +250,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time ) ntime = start_time + old_noise_delay; noise_lfsr = old_noise_lfsr; //if ( (regs [6] & 0x1F) == 0 ) - // dprintf( "Used noise period 0\n" ); + // debug_printf( "Used noise period 0\n" ); } // The following efficiently handles several cases (least demanding first): @@ -299,7 +299,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time ) while ( ntime <= end ) // must advance *past* time to avoid hang { int changed = noise_lfsr + 1; - noise_lfsr = ((blargg_ulong)-(blargg_long)(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1); + noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1); if ( changed & 2 ) { delta = -delta; diff --git a/game-music-emu/gme/Ay_Apu.h b/game-music-emu/gme/Ay_Apu.h index 31956939e..b031f0473 100644 --- a/game-music-emu/gme/Ay_Apu.h +++ b/game-music-emu/gme/Ay_Apu.h @@ -1,6 +1,6 @@ // AY-3-8910 sound chip emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef AY_APU_H #define AY_APU_H @@ -50,7 +50,6 @@ private: Blip_Buffer* output; } oscs [osc_count]; blip_time_t last_time; - byte latch; byte regs [reg_count]; struct { diff --git a/game-music-emu/gme/Ay_Cpu.cpp b/game-music-emu/gme/Ay_Cpu.cpp index b4487d9c9..825320d08 100644 --- a/game-music-emu/gme/Ay_Cpu.cpp +++ b/game-music-emu/gme/Ay_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ /* Last validated with zexall 2006.11.21 5:26 PM @@ -807,6 +807,7 @@ possibly_out_of_time: case 0xCB: unsigned data2; data2 = INSTR( 1 ); + (void) data2; // TODO is this the same as data in all cases? pc++; switch ( data ) { @@ -1047,7 +1048,7 @@ possibly_out_of_time: blargg_ulong sum = temp + (flags & C01); flags = ~data >> 2 & N02; if ( flags ) - sum = (blargg_ulong)-(blargg_long)sum; + sum = -sum; sum += rp.hl; temp ^= rp.hl; temp ^= sum; @@ -1252,7 +1253,7 @@ possibly_out_of_time: case 0x4F: // LD R,A SET_R( rg.a ); - dprintf( "LD R,A not supported\n" ); + debug_printf( "LD R,A not supported\n" ); warning = true; goto loop; @@ -1262,7 +1263,7 @@ possibly_out_of_time: case 0x5F: // LD A,R rg.a = GET_R(); - dprintf( "LD A,R not supported\n" ); + debug_printf( "LD A,R not supported\n" ); warning = true; ld_ai_common: flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04); @@ -1285,7 +1286,7 @@ possibly_out_of_time: goto loop; default: - dprintf( "Opcode $ED $%02X not supported\n", data ); + debug_printf( "Opcode $ED $%02X not supported\n", data ); warning = true; goto loop; } @@ -1545,7 +1546,7 @@ possibly_out_of_time: } default: - dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); + debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); warning = true; goto loop; } @@ -1634,7 +1635,7 @@ possibly_out_of_time: } default: - dprintf( "Unnecessary DD/FD prefix encountered\n" ); + debug_printf( "Unnecessary DD/FD prefix encountered\n" ); warning = true; pc--; goto loop; @@ -1643,7 +1644,7 @@ possibly_out_of_time: } } - dprintf( "Unhandled main opcode: $%02X\n", opcode ); + debug_printf( "Unhandled main opcode: $%02X\n", opcode ); assert( false ); halt: diff --git a/game-music-emu/gme/Ay_Cpu.h b/game-music-emu/gme/Ay_Cpu.h index 07241d5e6..cd3d66747 100644 --- a/game-music-emu/gme/Ay_Cpu.h +++ b/game-music-emu/gme/Ay_Cpu.h @@ -1,6 +1,6 @@ // Z80 CPU emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef AY_CPU_H #define AY_CPU_H diff --git a/game-music-emu/gme/Ay_Emu.cpp b/game-music-emu/gme/Ay_Emu.cpp index 090b5ef82..43670d1bd 100644 --- a/game-music-emu/gme/Ay_Emu.cpp +++ b/game-music-emu/gme/Ay_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Ay_Emu.h" @@ -47,8 +47,8 @@ Ay_Emu::~Ay_Emu() { } static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size ) { - long pos = long(ptr - (byte const*) file.header); - long file_size = long(file.end - (byte const*) file.header); + long pos = ptr - (byte const*) file.header; + long file_size = file.end - (byte const*) file.header; assert( (unsigned long) pos <= (unsigned long) file_size - 2 ); int offset = (BOOST::int16_t) get_be16( ptr ); if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) ) @@ -207,11 +207,11 @@ blargg_err_t Ay_Emu::start_track_( int track ) if ( len > blargg_ulong (file.end - in) ) { set_warning( "Missing file data" ); - len = unsigned(file.end - in); + len = file.end - in; } - //dprintf( "addr: $%04X, len: $%04X\n", addr, len ); + //debug_printf( "addr: $%04X, len: $%04X\n", addr, len ); if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data - dprintf( "Block addr in ROM\n" ); + debug_printf( "Block addr in ROM\n" ); memcpy( mem.ram + addr, in, len ); if ( file.end - blocks < 8 ) @@ -242,7 +242,7 @@ blargg_err_t Ay_Emu::start_track_( int track ) }; memcpy( mem.ram, passive, sizeof passive ); unsigned play_addr = get_be16( more_data + 4 ); - //dprintf( "Play: $%04X\n", play_addr ); + //debug_printf( "Play: $%04X\n", play_addr ); if ( play_addr ) { memcpy( mem.ram, active, sizeof active ); @@ -315,7 +315,7 @@ void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data ) } } - dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); + debug_printf( "Unmapped OUT: $%04X <- $%02X\n", addr, data ); return; enable_cpc: @@ -356,7 +356,7 @@ int ay_cpu_in( Ay_Cpu*, unsigned addr ) if ( (addr & 0xFF) == 0xFE ) return 0xFF; // other values break some beeper tunes - dprintf( "Unmapped IN : $%04X\n", addr ); + debug_printf( "Unmapped IN : $%04X\n", addr ); return 0xFF; } diff --git a/game-music-emu/gme/Ay_Emu.h b/game-music-emu/gme/Ay_Emu.h index ba8445d31..86b020487 100644 --- a/game-music-emu/gme/Ay_Emu.h +++ b/game-music-emu/gme/Ay_Emu.h @@ -1,6 +1,6 @@ // Sinclair Spectrum AY music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef AY_EMU_H #define AY_EMU_H @@ -46,7 +46,6 @@ protected: private: file_t file; - unsigned play_addr; cpu_time_t play_period; cpu_time_t next_play; Blip_Buffer* beeper_output; diff --git a/game-music-emu/gme/Blip_Buffer.cpp b/game-music-emu/gme/Blip_Buffer.cpp index 9dc89ea8d..2b88cd4f8 100644 --- a/game-music-emu/gme/Blip_Buffer.cpp +++ b/game-music-emu/gme/Blip_Buffer.cpp @@ -233,18 +233,32 @@ static void gen_sinc( float* out, int count, double oversample, double treble, d double const to_angle = PI / 2 / maxh / oversample; for ( int i = 0; i < count; i++ ) { - double angle = ((i - count) * 2 + 1) * to_angle; - double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle ); - double cos_nc_angle = cos( maxh * cutoff * angle ); - double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle ); - double cos_angle = cos( angle ); + double angle = ((i - count) * 2 + 1) * to_angle; + double angle_maxh = angle * maxh; + double angle_maxh_mid = angle_maxh * cutoff; - c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle; - double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle); - double b = 2.0 - cos_angle - cos_angle; - double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle; + double y = maxh; - out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d + // 0 to Fs/2*cutoff, flat + if ( angle_maxh_mid ) // unstable at t=0 + y *= sin( angle_maxh_mid ) / angle_maxh_mid; + + // Fs/2*cutoff to Fs/2, logarithmic rolloff + double cosa = cos( angle ); + double den = 1 + rolloff * (rolloff - cosa - cosa); + + // Becomes unstable when rolloff is near 1.0 and t is near 0, + // which is the only time den becomes small + if ( den > 1e-13 ) + { + double num = + (cos( angle_maxh - angle ) * rolloff - cos( angle_maxh )) * pow_a_n - + cos( angle_maxh_mid - angle ) * rolloff + cos( angle_maxh_mid ); + + y = y * cutoff + num / den; + } + + out [i] = (float) y; } } diff --git a/game-music-emu/gme/CMakeLists.txt b/game-music-emu/gme/CMakeLists.txt new file mode 100644 index 000000000..73a14befb --- /dev/null +++ b/game-music-emu/gme/CMakeLists.txt @@ -0,0 +1,153 @@ +# List of source files required by libgme and any emulators +# This is not 100% accurate (Fir_Resampler for instance) but +# you'll be OK. +set(libgme_SRCS Blip_Buffer.cpp + Classic_Emu.cpp + Data_Reader.cpp + Dual_Resampler.cpp + Effects_Buffer.cpp + Fir_Resampler.cpp + gme.cpp + Gme_File.cpp + M3u_Playlist.cpp + Multi_Buffer.cpp + Music_Emu.cpp + ) + +# Ay_Apu is very popular around here +if (USE_GME_AY OR USE_GME_KSS) + set(libgme_SRCS ${libgme_SRCS} + Ay_Apu.cpp + ) +endif() + +# so is Ym2612_Emu +if (USE_GME_VGM OR USE_GME_GYM) + set(libgme_SRCS ${libgme_SRCS} + Ym2612_Emu.cpp + ) +endif() + +# But none are as popular as Sms_Apu +if (USE_GME_VGM OR USE_GME_GYM OR USE_GME_KSS) + set(libgme_SRCS ${libgme_SRCS} + Sms_Apu.cpp + ) +endif() + +if (USE_GME_AY) + set(libgme_SRCS ${libgme_SRCS} + # Ay_Apu.cpp included earlier + Ay_Cpu.cpp + Ay_Emu.cpp + ) +endif() + +if (USE_GME_GBS) + set(libgme_SRCS ${libgme_SRCS} + Gb_Apu.cpp + Gb_Cpu.cpp + Gb_Oscs.cpp + Gbs_Emu.cpp + ) +endif() + +if (USE_GME_GYM) + set(libgme_SRCS ${libgme_SRCS} + # Sms_Apu.cpp included earlier + # Ym2612_Emu.cpp included earlier + Gym_Emu.cpp + ) +endif() + +if (USE_GME_HES) + set(libgme_SRCS ${libgme_SRCS} + Hes_Apu.cpp + Hes_Cpu.cpp + Hes_Emu.cpp + ) +endif() + +if (USE_GME_KSS) + set(libgme_SRCS ${libgme_SRCS} + # Ay_Apu.cpp included earlier + # Sms_Apu.cpp included earlier + Kss_Cpu.cpp + Kss_Emu.cpp + Kss_Scc_Apu.cpp + ) +endif() + +if (USE_GME_NSF OR USE_GME_NSFE) + set(libgme_SRCS ${libgme_SRCS} + Nes_Apu.cpp + Nes_Cpu.cpp + Nes_Fme7_Apu.cpp + Nes_Namco_Apu.cpp + Nes_Oscs.cpp + Nes_Vrc6_Apu.cpp + Nsf_Emu.cpp + ) +endif() + +if (USE_GME_NSFE) + set(libgme_SRCS ${libgme_SRCS} + Nsfe_Emu.cpp + ) +endif() + +if (USE_GME_SAP) + set(libgme_SRCS ${libgme_SRCS} + Sap_Apu.cpp + Sap_Cpu.cpp + Sap_Emu.cpp + ) +endif() + +if (USE_GME_SPC) + set(libgme_SRCS ${libgme_SRCS} + Snes_Spc.cpp + Spc_Cpu.cpp + Spc_Dsp.cpp + Spc_Emu.cpp + Spc_Filter.cpp + ) +endif() + +if (USE_GME_VGM) + set(libgme_SRCS ${libgme_SRCS} + # Sms_Apu.cpp included earlier + # Ym2612_Emu.cpp included earlier + Vgm_Emu.cpp + Vgm_Emu_Impl.cpp + Ym2413_Emu.cpp + ) +endif() + +# These headers are part of the generic gme interface. +set (EXPORTED_HEADERS gme.h) + +# Run during cmake phase, so this is available during make +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gme_types.h.in + ${CMAKE_CURRENT_BINARY_DIR}/gme_types.h) + +# On some platforms we may need to change headers or whatnot based on whether +# we're building the library or merely using the library. The following is +# only defined when building the library to allow us to tell which is which. +add_definitions(-DBLARGG_BUILD_DLL) + +# For the gme_types.h +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# Add library to be compiled. +add_library(gme ${libgme_SRCS}) + +# The version is the release. The "soversion" is the API version. As long +# as only build fixes are performed (i.e. no backwards-incompatible changes +# to the API), the SOVERSION should be the same even when bumping up VERSION. +# The way gme.h is designed, SOVERSION should very rarely be bumped, if ever. +# Hopefully the API can stay compatible with old versions. +#set_target_properties(gme +# PROPERTIES VERSION ${GME_VERSION} +# SOVERSION 0) +target_link_libraries(gme) diff --git a/game-music-emu/gme/Classic_Emu.cpp b/game-music-emu/gme/Classic_Emu.cpp index 622a5154f..42bb2fbe2 100644 --- a/game-music-emu/gme/Classic_Emu.cpp +++ b/game-music-emu/gme/Classic_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Classic_Emu.h" @@ -176,9 +176,9 @@ void Rom_Data_::set_addr_( long addr, int unit ) if ( 0 ) { - dprintf( "addr: %X\n", addr ); - dprintf( "file_size: %d\n", file_size_ ); - dprintf( "rounded: %d\n", rounded ); - dprintf( "mask: $%X\n", mask ); + debug_printf( "addr: %X\n", addr ); + debug_printf( "file_size: %d\n", file_size_ ); + debug_printf( "rounded: %d\n", rounded ); + debug_printf( "mask: $%X\n", mask ); } } diff --git a/game-music-emu/gme/Classic_Emu.h b/game-music-emu/gme/Classic_Emu.h index 8cd822ca2..99e99afbe 100644 --- a/game-music-emu/gme/Classic_Emu.h +++ b/game-music-emu/gme/Classic_Emu.h @@ -1,6 +1,6 @@ // Common aspects of emulators which use Blip_Buffer for sound output -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef CLASSIC_EMU_H #define CLASSIC_EMU_H diff --git a/game-music-emu/gme/Data_Reader.cpp b/game-music-emu/gme/Data_Reader.cpp index 8c4d8d0e1..5bbfbf551 100644 --- a/game-music-emu/gme/Data_Reader.cpp +++ b/game-music-emu/gme/Data_Reader.cpp @@ -1,15 +1,12 @@ // File_Extractor 0.4.0. http://www.slack.net/~ant/ -#define _CRT_SECURE_NO_WARNINGS -#define IN_GME 1 - -#include -#include -#include - #include "Data_Reader.h" #include "blargg_endian.h" +#include +#include +#include + /* Copyright (C) 2005-2006 Shay Green. This module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -92,11 +89,11 @@ Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r ) in = r; } -long Remaining_Reader::remain() const { return long(header_end - header + in->remain()); } +long Remaining_Reader::remain() const { return header_end - header + in->remain(); } long Remaining_Reader::read_first( void* out, long count ) { - long first = long(header_end - header); + long first = header_end - header; if ( first ) { if ( first > count ) @@ -213,7 +210,7 @@ long Std_File_Reader::size() const long Std_File_Reader::read_avail( void* p, long s ) { - return (long)fread( p, 1, s, (FILE*) file_ ); + return fread( p, 1, s, (FILE*) file_ ); } blargg_err_t Std_File_Reader::read( void* p, long s ) diff --git a/game-music-emu/gme/Data_Reader.h b/game-music-emu/gme/Data_Reader.h index e6321eb04..acf571f67 100644 --- a/game-music-emu/gme/Data_Reader.h +++ b/game-music-emu/gme/Data_Reader.h @@ -5,7 +5,6 @@ #define DATA_READER_H #include "blargg_common.h" -#include "gme.h" // Supports reading and finding out how many bytes are remaining class Data_Reader { @@ -117,7 +116,7 @@ private: // Invokes callback function to read data. Size of data must be specified in advance. class Callback_Reader : public Data_Reader { public: - typedef const char* (GMEAPI *callback_t)( void* data, void* out, int count ); + typedef const char* (*callback_t)( void* data, void* out, int count ); Callback_Reader( callback_t, long size, void* data = 0 ); public: long read_avail( void*, long ); diff --git a/game-music-emu/gme/Dual_Resampler.cpp b/game-music-emu/gme/Dual_Resampler.cpp index fe2085803..1c2cc36e2 100644 --- a/game-music-emu/gme/Dual_Resampler.cpp +++ b/game-music-emu/gme/Dual_Resampler.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Dual_Resampler.h" @@ -20,7 +20,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ unsigned const resampler_extra = 256; -Dual_Resampler::Dual_Resampler() { } +Dual_Resampler::Dual_Resampler() : + sample_buf_size(0), + oversamples_per_frame(-1), + buf_pos(-1), + resampler_size(0) +{ +} Dual_Resampler::~Dual_Resampler() { } @@ -62,10 +68,10 @@ void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out ) assert( blip_buf.samples_avail() == pair_count ); resampler.write( new_count ); - + long count = resampler.read( sample_buf.begin(), sample_buf_size ); assert( count == (long) sample_buf_size ); - + mix_samples( blip_buf, out ); blip_buf.remove_samples( pair_count ); } diff --git a/game-music-emu/gme/Dual_Resampler.h b/game-music-emu/gme/Dual_Resampler.h index 61beb8a08..6dc8dcfc2 100644 --- a/game-music-emu/gme/Dual_Resampler.h +++ b/game-music-emu/gme/Dual_Resampler.h @@ -1,6 +1,6 @@ // Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators. -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef DUAL_RESAMPLER_H #define DUAL_RESAMPLER_H diff --git a/game-music-emu/gme/Effects_Buffer.cpp b/game-music-emu/gme/Effects_Buffer.cpp index 730f8e94c..6af9c14be 100644 --- a/game-music-emu/gme/Effects_Buffer.cpp +++ b/game-music-emu/gme/Effects_Buffer.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Effects_Buffer.h" diff --git a/game-music-emu/gme/Effects_Buffer.h b/game-music-emu/gme/Effects_Buffer.h index eb0aa67a3..832c44b06 100644 --- a/game-music-emu/gme/Effects_Buffer.h +++ b/game-music-emu/gme/Effects_Buffer.h @@ -1,6 +1,6 @@ // Multi-channel effects buffer with panning, echo and reverb -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef EFFECTS_BUFFER_H #define EFFECTS_BUFFER_H diff --git a/game-music-emu/gme/Fir_Resampler.cpp b/game-music-emu/gme/Fir_Resampler.cpp index 56ca47801..7a6600be8 100644 --- a/game-music-emu/gme/Fir_Resampler.cpp +++ b/game-music-emu/gme/Fir_Resampler.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Fir_Resampler.h" @@ -156,7 +156,7 @@ int Fir_Resampler_::input_needed( blargg_long output_count ) const output_count -= 2; } - long input_extra = long(input_count - (write_pos - &buf [(width_ - 1) * stereo])); + long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]); if ( input_extra < 0 ) input_extra = 0; return input_extra; @@ -186,7 +186,7 @@ int Fir_Resampler_::avail_( blargg_long input_count ) const int Fir_Resampler_::skip_input( long count ) { - int remain = int(write_pos - buf.begin()); + int remain = write_pos - buf.begin(); int max_count = remain - width_ * stereo; if ( count > max_count ) count = max_count; diff --git a/game-music-emu/gme/Fir_Resampler.h b/game-music-emu/gme/Fir_Resampler.h index 36006de79..a1bb67781 100644 --- a/game-music-emu/gme/Fir_Resampler.h +++ b/game-music-emu/gme/Fir_Resampler.h @@ -1,6 +1,6 @@ // Finite impulse response (FIR) resampler with adjustable FIR size -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef FIR_RESAMPLER_H #define FIR_RESAMPLER_H @@ -31,7 +31,7 @@ public: void clear(); // Number of input samples that can be written - int max_write() const { return int(buf.end() - write_pos); } + int max_write() const { return buf.end() - write_pos; } // Pointer to place to write input samples sample_t* buffer() { return write_pos; } @@ -40,7 +40,7 @@ public: void write( long count ); // Number of input samples in buffer - int written() const { return int(write_pos - &buf [write_offset]); } + int written() const { return write_pos - &buf [write_offset]; } // Skip 'count' input samples. Returns number of samples actually skipped. int skip_input( long count ); @@ -51,7 +51,7 @@ public: int input_needed( blargg_long count ) const; // Number of output samples available - int avail() const { return avail_( blargg_long(write_pos - &buf [width_ * stereo]) ); } + int avail() const { return avail_( write_pos - &buf [width_ * stereo] ); } public: ~Fir_Resampler_(); @@ -161,11 +161,11 @@ int Fir_Resampler::read( sample_t* out_begin, blargg_long count ) imp_phase = res - remain; - int left = int(write_pos - in); + int left = write_pos - in; write_pos = &buf [left]; memmove( buf.begin(), in, left * sizeof *in ); - return int(out - out_begin); + return out - out_begin; } #endif diff --git a/game-music-emu/gme/Gb_Apu.cpp b/game-music-emu/gme/Gb_Apu.cpp index 932ebb838..866594ddf 100644 --- a/game-music-emu/gme/Gb_Apu.cpp +++ b/game-music-emu/gme/Gb_Apu.cpp @@ -271,7 +271,7 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data ) } else { - //dprintf( "APU powered on\n" ); + //debug_printf( "APU powered on\n" ); } } } diff --git a/game-music-emu/gme/Gb_Cpu.cpp b/game-music-emu/gme/Gb_Cpu.cpp index bc7ac1876..b0128ea4c 100644 --- a/game-music-emu/gme/Gb_Cpu.cpp +++ b/game-music-emu/gme/Gb_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Gb_Cpu.h" @@ -89,11 +89,6 @@ unsigned const n_flag = 0x40; unsigned const h_flag = 0x20; unsigned const c_flag = 0x10; -#ifdef _MSC_VER -// warning C4101: 'blargg_failed_' : unreferenced local variable -// -- produced by the BOOST_STATIC_ASSERT line below -#pragma warning(disable:4101) -#endif bool Gb_Cpu::run( blargg_long cycle_count ) { state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr; diff --git a/game-music-emu/gme/Gb_Cpu.h b/game-music-emu/gme/Gb_Cpu.h index 953fbaf50..0994cec29 100644 --- a/game-music-emu/gme/Gb_Cpu.h +++ b/game-music-emu/gme/Gb_Cpu.h @@ -1,7 +1,7 @@ // Nintendo Game Boy CPU emulator // Treats every instruction as taking 4 cycles -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef GB_CPU_H #define GB_CPU_H diff --git a/game-music-emu/gme/Gbs_Emu.cpp b/game-music-emu/gme/Gbs_Emu.cpp index 83aefb424..05a0b9935 100644 --- a/game-music-emu/gme/Gbs_Emu.cpp +++ b/game-music-emu/gme/Gbs_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Gbs_Emu.h" @@ -18,8 +18,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "blargg_source.h" -Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000, 0, 0, 0, 0, 0, 0, 0, 0 }; -Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300, 0, 0, 0, 0, 0, 0, 0, 0 }; +Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = + Music_Emu::make_equalizer( -47.0, 2000 ); +Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = + Music_Emu::make_equalizer( 0.0, 300 ); Gbs_Emu::Gbs_Emu() { @@ -39,8 +41,7 @@ Gbs_Emu::Gbs_Emu() set_max_initial_silence( 21 ); set_gain( 1.2 ); - static equalizer_t const eq = { -1.0, 120, 0, 0, 0, 0, 0, 0, 0, 0 }; - set_equalizer( eq ); + set_equalizer( make_equalizer( -1.0, 120 ) ); } Gbs_Emu::~Gbs_Emu() { } @@ -151,7 +152,7 @@ void Gbs_Emu::set_bank( int n ) { // TODO: what is the correct behavior? Current Game & Watch Gallery // rip requires that this have no effect or set to bank 1. - //dprintf( "Selected ROM bank 0\n" ); + //debug_printf( "Selected ROM bank 0\n" ); return; //n = 1; } @@ -212,11 +213,11 @@ blargg_err_t Gbs_Emu::start_track_( int track ) for ( int i = 0; i < (int) sizeof sound_data; i++ ) apu.write_register( 0, i + apu.start_addr, sound_data [i] ); - cpu::reset( rom.unmapped() ); - unsigned load_addr = get_le16( header_.load_addr ); - cpu::rst_base = load_addr; rom.set_addr( load_addr ); + cpu::rst_base = load_addr; + + cpu::reset( rom.unmapped() ); cpu::map_code( ram_addr, 0x10000 - ram_addr, ram ); cpu::map_code( 0, bank_size, rom.at_addr( 0 ) ); @@ -265,13 +266,13 @@ blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int ) } else if ( cpu::r.pc > 0xFFFF ) { - dprintf( "PC wrapped around\n" ); + debug_printf( "PC wrapped around\n" ); cpu::r.pc &= 0xFFFF; } else { set_warning( "Emulation error (illegal/unsupported instruction)" ); - dprintf( "Bad opcode $%.2x at $%.4x\n", + debug_printf( "Bad opcode $%.2x at $%.4x\n", (int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc ); cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF; cpu_time += 6; diff --git a/game-music-emu/gme/Gbs_Emu.h b/game-music-emu/gme/Gbs_Emu.h index 6cc6b474b..b233a2b4f 100644 --- a/game-music-emu/gme/Gbs_Emu.h +++ b/game-music-emu/gme/Gbs_Emu.h @@ -1,6 +1,6 @@ // Nintendo Game Boy GBS music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef GBS_EMU_H #define GBS_EMU_H diff --git a/game-music-emu/gme/Gme_File.cpp b/game-music-emu/gme/Gme_File.cpp index 2d3a140e0..995f56b1c 100644 --- a/game-music-emu/gme/Gme_File.cpp +++ b/game-music-emu/gme/Gme_File.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Gme_File.h" @@ -60,8 +60,8 @@ blargg_err_t Gme_File::load_mem_( byte const* data, long size ) blargg_err_t Gme_File::load_( Data_Reader& in ) { RETURN_ERR( file_data.resize( in.remain() ) ); - RETURN_ERR( in.read( file_data.begin(), (long)file_data.size() ) ); - return load_mem_( file_data.begin(), (long)file_data.size() ); + RETURN_ERR( in.read( file_data.begin(), file_data.size() ) ); + return load_mem_( file_data.begin(), file_data.size() ); } // public load functions call this at beginning diff --git a/game-music-emu/gme/Gme_File.h b/game-music-emu/gme/Gme_File.h index f0e94302c..2d0a57344 100644 --- a/game-music-emu/gme/Gme_File.h +++ b/game-music-emu/gme/Gme_File.h @@ -1,6 +1,6 @@ // Common interface to game music file loading and information -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef GME_FILE_H #define GME_FILE_H diff --git a/game-music-emu/gme/Gym_Emu.cpp b/game-music-emu/gme/Gym_Emu.cpp index de34f64eb..f149aebb5 100644 --- a/game-music-emu/gme/Gym_Emu.cpp +++ b/game-music-emu/gme/Gym_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Gym_Emu.h" diff --git a/game-music-emu/gme/Gym_Emu.h b/game-music-emu/gme/Gym_Emu.h index 0f7a0e39c..1e4ed8b3e 100644 --- a/game-music-emu/gme/Gym_Emu.h +++ b/game-music-emu/gme/Gym_Emu.h @@ -1,7 +1,7 @@ // Sega Genesis/Mega Drive GYM music file emulator // Includes with PCM timing recovery to improve sample quality. -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef GYM_EMU_H #define GYM_EMU_H diff --git a/game-music-emu/gme/Hes_Apu.cpp b/game-music-emu/gme/Hes_Apu.cpp index cfb171d5b..9c7f515d6 100644 --- a/game-music-emu/gme/Hes_Apu.cpp +++ b/game-music-emu/gme/Hes_Apu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Hes_Apu.h" @@ -106,10 +106,10 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time ) unsigned noise_lfsr = this->noise_lfsr; do { - int new_dac = 0x1F & (unsigned)-(signed)(noise_lfsr >> 1 & 1); + int new_dac = 0x1F & -(noise_lfsr >> 1 & 1); // Implemented using "Galios configuration" // TODO: find correct LFSR algorithm - noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & (unsigned)-(signed)(noise_lfsr & 1)); + noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1)); //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1)); int delta = new_dac - dac; if ( delta ) @@ -158,7 +158,7 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time ) //period = 0x1000 * 2; period = 1; //if ( !(volume_0 | volume_1) ) - // dprintf( "Used period 0\n" ); + // debug_printf( "Used period 0\n" ); } // maintain phase when silent @@ -295,7 +295,7 @@ void Hes_Apu::write_data( blip_time_t time, int addr, int data ) case 0x809: if ( !(data & 0x80) && (data & 0x03) != 0 ) - dprintf( "HES LFO not supported\n" ); + debug_printf( "HES LFO not supported\n" ); } } } diff --git a/game-music-emu/gme/Hes_Apu.h b/game-music-emu/gme/Hes_Apu.h index ca0c932fd..89dde02cd 100644 --- a/game-music-emu/gme/Hes_Apu.h +++ b/game-music-emu/gme/Hes_Apu.h @@ -1,6 +1,6 @@ // Turbo Grafx 16 (PC Engine) PSG sound chip emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef HES_APU_H #define HES_APU_H diff --git a/game-music-emu/gme/Hes_Cpu.cpp b/game-music-emu/gme/Hes_Cpu.cpp index 2615a0bb9..4bfe8faff 100644 --- a/game-music-emu/gme/Hes_Cpu.cpp +++ b/game-music-emu/gme/Hes_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Hes_Cpu.h" @@ -148,7 +148,7 @@ loop: /* static long count; if ( count == 1844 ) Debugger(); - if ( s.base != correct ) dprintf( "%ld\n", count ); + if ( s.base != correct ) debug_printf( "%ld\n", count ); count++; */ } @@ -741,7 +741,7 @@ possibly_out_of_time: ARITH_ADDR_MODES( 0x65 ) // ADC adc_imm: { if ( status & st_d ) - dprintf( "Decimal mode not supported\n" ); + debug_printf( "Decimal mode not supported\n" ); fint16 carry = c >> 8 & 1; fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend status &= ~st_v; @@ -1085,7 +1085,7 @@ possibly_out_of_time: goto loop; } delayed_cli: - dprintf( "Delayed CLI not supported\n" ); // TODO: implement + debug_printf( "Delayed CLI not supported\n" ); // TODO: implement goto loop; } @@ -1100,7 +1100,7 @@ possibly_out_of_time: s_time += delta; if ( s_time < 0 ) goto loop; - dprintf( "Delayed SEI not supported\n" ); // TODO: implement + debug_printf( "Delayed SEI not supported\n" ); // TODO: implement goto loop; } @@ -1145,7 +1145,7 @@ possibly_out_of_time: goto loop; case 0x54: // CSL - dprintf( "CSL not supported\n" ); + debug_printf( "CSL not supported\n" ); illegal_encountered = true; goto loop; @@ -1154,7 +1154,7 @@ possibly_out_of_time: case 0xF4: { // SET //fuint16 operand = GET_MSB(); - dprintf( "SET not handled\n" ); + debug_printf( "SET not handled\n" ); //switch ( data ) //{ //} @@ -1233,7 +1233,7 @@ possibly_out_of_time: default: assert( (unsigned) opcode <= 0xFF ); - dprintf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 ); + debug_printf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 ); illegal_encountered = true; goto loop; } diff --git a/game-music-emu/gme/Hes_Cpu.h b/game-music-emu/gme/Hes_Cpu.h index 536e732f8..d46a0b8a8 100644 --- a/game-music-emu/gme/Hes_Cpu.h +++ b/game-music-emu/gme/Hes_Cpu.h @@ -1,6 +1,6 @@ // PC Engine CPU emulator for use with HES music files -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef HES_CPU_H #define HES_CPU_H diff --git a/game-music-emu/gme/Hes_Emu.cpp b/game-music-emu/gme/Hes_Emu.cpp index 2306e705d..e3c700dbc 100644 --- a/game-music-emu/gme/Hes_Emu.cpp +++ b/game-music-emu/gme/Hes_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Hes_Emu.h" @@ -273,12 +273,12 @@ void Hes_Emu::cpu_write_vdp( int addr, int data ) } else { - dprintf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data ); + debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data ); } break; case 3: - dprintf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data ); + debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data ); break; } } @@ -325,7 +325,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data ) run_until( time ); irq.disables = data; if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values - dprintf( "Int mask: $%02X\n", data ); + debug_printf( "Int mask: $%02X\n", data ); break; case 0x1403: @@ -344,7 +344,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data ) return; default: - dprintf( "unmapped write $%04X <- $%02X\n", addr, data ); + debug_printf( "unmapped write $%04X <- $%02X\n", addr, data ); return; #endif } @@ -368,14 +368,14 @@ int Hes_Emu::cpu_read_( hes_addr_t addr ) case 0x0002: case 0x0003: - dprintf( "VDP read not supported: %d\n", addr ); + debug_printf( "VDP read not supported: %d\n", addr ); return 0; case 0x0C01: //return timer.enabled; // TODO: remove? case 0x0C00: run_until( time ); - dprintf( "Timer count read\n" ); + debug_printf( "Timer count read\n" ); return (unsigned) (timer.count - 1) / timer_base; case 0x1402: @@ -396,7 +396,7 @@ int Hes_Emu::cpu_read_( hes_addr_t addr ) break; default: - dprintf( "unmapped read $%04X\n", addr ); + debug_printf( "unmapped read $%04X\n", addr ); #endif } diff --git a/game-music-emu/gme/Hes_Emu.h b/game-music-emu/gme/Hes_Emu.h index 9951eb6a2..b4e20fd67 100644 --- a/game-music-emu/gme/Hes_Emu.h +++ b/game-music-emu/gme/Hes_Emu.h @@ -1,6 +1,6 @@ // TurboGrafx-16/PC Engine HES music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef HES_EMU_H #define HES_EMU_H diff --git a/game-music-emu/gme/Kss_Cpu.cpp b/game-music-emu/gme/Kss_Cpu.cpp index c943a01fe..a2068efc4 100644 --- a/game-music-emu/gme/Kss_Cpu.cpp +++ b/game-music-emu/gme/Kss_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ /* Last validated with zexall 2006.11.14 2:19 PM @@ -841,6 +841,7 @@ possibly_out_of_time: case 0xCB: unsigned data2; data2 = instr [1]; + (void) data2; // TODO is this the same as data in all cases? pc++; switch ( data ) { @@ -1084,7 +1085,7 @@ possibly_out_of_time: blargg_ulong sum = temp + (flags & C01); flags = ~data >> 2 & N02; if ( flags ) - sum = (blargg_ulong)-(blargg_long)sum; + sum = -sum; sum += rp.hl; temp ^= rp.hl; temp ^= sum; @@ -1289,7 +1290,7 @@ possibly_out_of_time: case 0x4F: // LD R,A SET_R( rg.a ); - dprintf( "LD R,A not supported\n" ); + debug_printf( "LD R,A not supported\n" ); warning = true; goto loop; @@ -1299,7 +1300,7 @@ possibly_out_of_time: case 0x5F: // LD A,R rg.a = GET_R(); - dprintf( "LD A,R not supported\n" ); + debug_printf( "LD A,R not supported\n" ); warning = true; ld_ai_common: flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04); @@ -1322,7 +1323,7 @@ possibly_out_of_time: goto loop; default: - dprintf( "Opcode $ED $%02X not supported\n", data ); + debug_printf( "Opcode $ED $%02X not supported\n", data ); warning = true; goto loop; } @@ -1583,7 +1584,7 @@ possibly_out_of_time: } default: - dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); + debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); warning = true; goto loop; } @@ -1672,7 +1673,7 @@ possibly_out_of_time: } default: - dprintf( "Unnecessary DD/FD prefix encountered\n" ); + debug_printf( "Unnecessary DD/FD prefix encountered\n" ); warning = true; pc--; goto loop; @@ -1681,7 +1682,7 @@ possibly_out_of_time: } } - dprintf( "Unhandled main opcode: $%02X\n", opcode ); + debug_printf( "Unhandled main opcode: $%02X\n", opcode ); assert( false ); hit_idle_addr: diff --git a/game-music-emu/gme/Kss_Cpu.h b/game-music-emu/gme/Kss_Cpu.h index 6297d1000..aec24e9d5 100644 --- a/game-music-emu/gme/Kss_Cpu.h +++ b/game-music-emu/gme/Kss_Cpu.h @@ -1,6 +1,6 @@ // Z80 CPU emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef KSS_CPU_H #define KSS_CPU_H diff --git a/game-music-emu/gme/Kss_Emu.cpp b/game-music-emu/gme/Kss_Emu.cpp index 3176aece7..def6ee199 100644 --- a/game-music-emu/gme/Kss_Emu.cpp +++ b/game-music-emu/gme/Kss_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Kss_Emu.h" @@ -230,9 +230,9 @@ blargg_err_t Kss_Emu::start_track_( int track ) bank_count = max_banks; set_warning( "Bank data missing" ); } - //dprintf( "load_size : $%X\n", load_size ); - //dprintf( "bank_size : $%X\n", bank_size ); - //dprintf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F ); + //debug_printf( "load_size : $%X\n", load_size ); + //debug_printf( "bank_size : $%X\n", bank_size ); + //debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F ); ram [idle_addr] = 0xFF; cpu::reset( unmapped_write, unmapped_read ); @@ -301,7 +301,7 @@ void Kss_Emu::cpu_write( unsigned addr, int data ) return; } - dprintf( "LD ($%04X),$%02X\n", addr, data ); + debug_printf( "LD ($%04X),$%02X\n", addr, data ); } void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data ) @@ -358,7 +358,7 @@ void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data ) #endif } - dprintf( "OUT $%04X,$%02X\n", addr, data ); + debug_printf( "OUT $%04X,$%02X\n", addr, data ); } int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr ) @@ -368,7 +368,7 @@ int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr ) //{ //} - dprintf( "IN $%04X\n", addr ); + debug_printf( "IN $%04X\n", addr ); return 0; } diff --git a/game-music-emu/gme/Kss_Emu.h b/game-music-emu/gme/Kss_Emu.h index 4d8463abd..e457f7311 100644 --- a/game-music-emu/gme/Kss_Emu.h +++ b/game-music-emu/gme/Kss_Emu.h @@ -1,6 +1,6 @@ // MSX computer KSS music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef KSS_EMU_H #define KSS_EMU_H @@ -68,7 +68,6 @@ private: void update_gain(); unsigned scc_enabled; // 0 or 0xC000 - byte const* bank_data; int bank_count; void set_bank( int logical, int physical ); blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); } diff --git a/game-music-emu/gme/Kss_Scc_Apu.cpp b/game-music-emu/gme/Kss_Scc_Apu.cpp index 1660ac3da..1ab14bd00 100644 --- a/game-music-emu/gme/Kss_Scc_Apu.cpp +++ b/game-music-emu/gme/Kss_Scc_Apu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Kss_Scc_Apu.h" diff --git a/game-music-emu/gme/Kss_Scc_Apu.h b/game-music-emu/gme/Kss_Scc_Apu.h index 03a6a1080..c8c69f118 100644 --- a/game-music-emu/gme/Kss_Scc_Apu.h +++ b/game-music-emu/gme/Kss_Scc_Apu.h @@ -1,6 +1,6 @@ // Konami SCC sound chip emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef KSS_SCC_APU_H #define KSS_SCC_APU_H diff --git a/game-music-emu/gme/M3u_Playlist.cpp b/game-music-emu/gme/M3u_Playlist.cpp index f5d38893a..bbe52b1a7 100644 --- a/game-music-emu/gme/M3u_Playlist.cpp +++ b/game-music-emu/gme/M3u_Playlist.cpp @@ -1,6 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ - -#define IN_GME 1 +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "M3u_Playlist.h" #include "Music_Emu.h" @@ -54,9 +52,9 @@ blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); } -gme_err_t GMEAPI gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); } +BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); } -gme_err_t GMEAPI gme_load_m3u_data( Music_Emu* me, const void* data, long size ) +BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size ) { Mem_File_Reader in( data, size ); return me->load_m3u( in ); @@ -409,7 +407,7 @@ blargg_err_t M3u_Playlist::parse() blargg_err_t M3u_Playlist::load( Data_Reader& in ) { RETURN_ERR( data.resize( in.remain() + 1 ) ); - RETURN_ERR( in.read( data.begin(), long(data.size() - 1) ) ); + RETURN_ERR( in.read( data.begin(), data.size() - 1 ) ); return parse(); } diff --git a/game-music-emu/gme/M3u_Playlist.h b/game-music-emu/gme/M3u_Playlist.h index a13387945..e764cb936 100644 --- a/game-music-emu/gme/M3u_Playlist.h +++ b/game-music-emu/gme/M3u_Playlist.h @@ -1,6 +1,6 @@ // M3U playlist file parser, with support for subtrack information -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef M3U_PLAYLIST_H #define M3U_PLAYLIST_H @@ -43,7 +43,7 @@ public: int repeat; // count }; entry_t const& operator [] ( int i ) const { return entries [i]; } - int size() const { return (int)entries.size(); } + int size() const { return entries.size(); } void clear(); diff --git a/game-music-emu/gme/Multi_Buffer.cpp b/game-music-emu/gme/Multi_Buffer.cpp index ecd8f8add..57f93b317 100644 --- a/game-music-emu/gme/Multi_Buffer.cpp +++ b/game-music-emu/gme/Multi_Buffer.cpp @@ -114,7 +114,7 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long count ) if ( count ) { int bufs_used = stereo_added | was_stereo; - //dprintf( "%X\n", bufs_used ); + //debug_printf( "%X\n", bufs_used ); if ( bufs_used <= 1 ) { mix_mono( out, count ); diff --git a/game-music-emu/gme/Music_Emu.cpp b/game-music-emu/gme/Music_Emu.cpp index b0f3f71d5..30b25dcfc 100644 --- a/game-music-emu/gme/Music_Emu.cpp +++ b/game-music-emu/gme/Music_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Music_Emu.h" @@ -24,7 +24,8 @@ int const silence_threshold = 0x10; long const fade_block_size = 512; int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift) -Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180, 0, 0, 0, 0, 0, 0, 0, 0 }; +Music_Emu::equalizer_t const Music_Emu::tv_eq = + Music_Emu::make_equalizer( -8.0, 180 ); void Music_Emu::clear_track_vars() { @@ -305,7 +306,7 @@ static long count_silence( Music_Emu::sample_t* begin, long size ) Music_Emu::sample_t* p = begin + size; while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { } *begin = first; - return size - long(p - begin); + return size - (p - begin); } // fill internal buffer and check it for silence @@ -340,14 +341,14 @@ blargg_err_t Music_Emu::play( long out_count, sample_t* out ) assert( emu_time >= out_time ); // prints nifty graph of how far ahead we are when searching for silence - //dprintf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" ); + //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" ); long pos = 0; if ( silence_count ) { // during a run of silence, run emulator at >=2x speed so it gets ahead long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time; - while ( emu_time < ahead_time && !(buf_remain || emu_track_ended_) ) + while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) ) fill_buf(); // fill with silence @@ -404,6 +405,7 @@ blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; } void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); } +void Gme_Info_::enable_accuracy_( bool ) { check( false ); } void Gme_Info_::mute_voices_( int ) { check( false ); } void Gme_Info_::set_tempo_( double ) { } blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; } diff --git a/game-music-emu/gme/Music_Emu.h b/game-music-emu/gme/Music_Emu.h index 6a2eaa110..b96f4b611 100644 --- a/game-music-emu/gme/Music_Emu.h +++ b/game-music-emu/gme/Music_Emu.h @@ -1,6 +1,6 @@ // Common interface to game music file emulators -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef MUSIC_EMU_H #define MUSIC_EMU_H @@ -82,6 +82,10 @@ public: // on others this has no effect. Should be called only once *before* set_sample_rate(). virtual void set_buffer( Multi_Buffer* ) { } + // Enables/disables accurate emulation options, if any are supported. Might change + // equalizer settings. + void enable_accuracy( bool enable = true ); + // Sound equalization (treble/bass) // Frequency equalizer parameters (see gme.txt) @@ -93,6 +97,14 @@ public: // Set frequency equalizer parameters void set_equalizer( equalizer_t const& ); + + // Construct equalizer of given treble/bass settings + static const equalizer_t make_equalizer( double treble, double bass ) + { + const Music_Emu::equalizer_t e = { treble, bass, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + return e; + } // Equalizer settings for TV speaker static equalizer_t const tv_eq; @@ -111,7 +123,8 @@ protected: void remute_voices(); virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0; - virtual void set_equalizer_( equalizer_t const& ) { }; + virtual void set_equalizer_( equalizer_t const& ) { } + virtual void enable_accuracy_( bool /* enable */ ) { } virtual void mute_voices_( int mask ) = 0; virtual void set_tempo_( double ) = 0; virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this @@ -160,8 +173,8 @@ private: void emu_play( long count, sample_t* out ); Multi_Buffer* effects_buffer; - friend GMEDLL Music_Emu* GMEAPI gme_new_emu( gme_type_t, int ); - friend GMEDLL void GMEAPI gme_set_stereo_depth( Music_Emu*, double ); + friend Music_Emu* gme_new_emu( gme_type_t, int ); + friend void gme_set_stereo_depth( Music_Emu*, double ); }; // base class for info-only derivations @@ -169,6 +182,7 @@ struct Gme_Info_ : Music_Emu { virtual blargg_err_t set_sample_rate_( long sample_rate ); virtual void set_equalizer_( equalizer_t const& ); + virtual void enable_accuracy_( bool ); virtual void mute_voices_( int mask ); virtual void set_tempo_( double ); virtual blargg_err_t start_track_( int ); @@ -189,6 +203,7 @@ inline int Music_Emu::current_track() const { return current_track_; } inline bool Music_Emu::track_ended() const { return track_ended_; } inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; } +inline void Music_Emu::enable_accuracy( bool b ) { enable_accuracy_( b ); } inline void Music_Emu::set_tempo_( double t ) { tempo_ = t; } inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); } inline void Music_Emu::ignore_silence( bool b ) { ignore_silence_ = b; } diff --git a/game-music-emu/gme/Nes_Apu.cpp b/game-music-emu/gme/Nes_Apu.cpp index 8daf5d0e1..68edb446d 100644 --- a/game-music-emu/gme/Nes_Apu.cpp +++ b/game-music-emu/gme/Nes_Apu.cpp @@ -385,7 +385,7 @@ int Nes_Apu::read_status( nes_time_t time ) irq_changed(); } - //dprintf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result ); + //debug_printf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result ); return result; } diff --git a/game-music-emu/gme/Nes_Cpu.cpp b/game-music-emu/gme/Nes_Cpu.cpp index 480b4aa48..ac548d0ff 100644 --- a/game-music-emu/gme/Nes_Cpu.cpp +++ b/game-music-emu/gme/Nes_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Nes_Cpu.h" @@ -921,7 +921,7 @@ imm##op: goto loop; status &= ~st_i; handle_cli: { - //dprintf( "CLI at %d\n", TIME ); + //debug_printf( "CLI at %d\n", TIME ); this->r.status = status; // update externally-visible I flag blargg_long delta = s.base - irq_time_; if ( delta <= 0 ) @@ -944,7 +944,7 @@ imm##op: // TODO: implement delayed_cli: - dprintf( "Delayed CLI not emulated\n" ); + debug_printf( "Delayed CLI not emulated\n" ); goto loop; } @@ -960,7 +960,7 @@ imm##op: if ( s_time < 0 ) goto loop; - dprintf( "Delayed SEI not emulated\n" ); + debug_printf( "Delayed SEI not emulated\n" ); goto loop; } diff --git a/game-music-emu/gme/Nes_Cpu.h b/game-music-emu/gme/Nes_Cpu.h index 94286708d..c139e069f 100644 --- a/game-music-emu/gme/Nes_Cpu.h +++ b/game-music-emu/gme/Nes_Cpu.h @@ -1,6 +1,6 @@ // NES 6502 CPU emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef NES_CPU_H #define NES_CPU_H diff --git a/game-music-emu/gme/Nes_Fme7_Apu.cpp b/game-music-emu/gme/Nes_Fme7_Apu.cpp index c058f6b1f..bc8ca7f48 100644 --- a/game-music-emu/gme/Nes_Fme7_Apu.cpp +++ b/game-music-emu/gme/Nes_Fme7_Apu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Nes_Fme7_Apu.h" @@ -56,7 +56,7 @@ void Nes_Fme7_Apu::run_until( blip_time_t end_time ) // check for unsupported mode #ifndef NDEBUG if ( (mode & 011) <= 001 && vol_mode & 0x1F ) - dprintf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n", + debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n", mode, vol_mode & 0x1F ); #endif diff --git a/game-music-emu/gme/Nes_Fme7_Apu.h b/game-music-emu/gme/Nes_Fme7_Apu.h index eb60af038..9069bd06a 100644 --- a/game-music-emu/gme/Nes_Fme7_Apu.h +++ b/game-music-emu/gme/Nes_Fme7_Apu.h @@ -1,6 +1,6 @@ // Sunsoft FME-7 sound emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef NES_FME7_APU_H #define NES_FME7_APU_H @@ -97,8 +97,8 @@ inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data ) { if ( (unsigned) latch >= reg_count ) { - #ifdef dprintf - dprintf( "FME7 write to %02X (past end of sound registers)\n", (int) latch ); + #ifdef debug_printf + debug_printf( "FME7 write to %02X (past end of sound registers)\n", (int) latch ); #endif return; } diff --git a/game-music-emu/gme/Nsf_Emu.cpp b/game-music-emu/gme/Nsf_Emu.cpp index 59d9b98cf..eab4bfbfd 100644 --- a/game-music-emu/gme/Nsf_Emu.cpp +++ b/game-music-emu/gme/Nsf_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Nsf_Emu.h" @@ -31,8 +31,10 @@ int const fme7_flag = 0x20; long const clock_divisor = 12; -Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; -Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; +Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = + Music_Emu::make_equalizer( -1.0, 80 ); +Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = + Music_Emu::make_equalizer( -15.0, 80 ); int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr ) { @@ -442,7 +444,7 @@ void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data ) // memory mapper? if ( addr == 0xFFF8 ) return; - dprintf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data ); + debug_printf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data ); } #endif } diff --git a/game-music-emu/gme/Nsf_Emu.h b/game-music-emu/gme/Nsf_Emu.h index fcce66a1e..0b001686c 100644 --- a/game-music-emu/gme/Nsf_Emu.h +++ b/game-music-emu/gme/Nsf_Emu.h @@ -1,6 +1,6 @@ // Nintendo NES/Famicom NSF music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef NSF_EMU_H #define NSF_EMU_H diff --git a/game-music-emu/gme/Nsfe_Emu.cpp b/game-music-emu/gme/Nsfe_Emu.cpp index a81b18865..824a1a240 100644 --- a/game-music-emu/gme/Nsfe_Emu.cpp +++ b/game-music-emu/gme/Nsfe_Emu.cpp @@ -1,6 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ - -#define _CRT_SECURE_NO_WARNINGS +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Nsfe_Emu.h" @@ -37,7 +35,7 @@ inline void Nsfe_Info::unload() void Nsfe_Info::disable_playlist( bool b ) { playlist_disabled = b; - info.track_count = (byte)playlist.size(); + info.track_count = playlist.size(); if ( !info.track_count || playlist_disabled ) info.track_count = actual_track_count_; } @@ -137,7 +135,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu ) blargg_long size = get_le32( block_header [0] ); blargg_long tag = get_le32( block_header [1] ); - //dprintf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) ); + //debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) ); switch ( tag ) { @@ -173,7 +171,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu ) blargg_vector chars; blargg_vector strs; RETURN_ERR( read_strs( in, size, chars, strs ) ); - int n = (int)strs.size(); + int n = strs.size(); if ( n > 3 ) copy_str( strs [3], info.dumper, sizeof info.dumper ); @@ -192,7 +190,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu ) case BLARGG_4CHAR('e','m','i','t'): RETURN_ERR( track_times.resize( size / 4 ) ); - RETURN_ERR( in.read( track_times.begin(), (long)track_times.size() * 4 ) ); + RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) ); break; case BLARGG_4CHAR('l','b','l','t'): diff --git a/game-music-emu/gme/Nsfe_Emu.h b/game-music-emu/gme/Nsfe_Emu.h index 00ac40399..32b05d55e 100644 --- a/game-music-emu/gme/Nsfe_Emu.h +++ b/game-music-emu/gme/Nsfe_Emu.h @@ -1,6 +1,6 @@ // Nintendo NES/Famicom NSFE music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef NSFE_EMU_H #define NSFE_EMU_H diff --git a/game-music-emu/gme/Sap_Apu.cpp b/game-music-emu/gme/Sap_Apu.cpp index 4ad7db11c..ecac3dafd 100644 --- a/game-music-emu/gme/Sap_Apu.cpp +++ b/game-music-emu/gme/Sap_Apu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Sap_Apu.h" @@ -30,7 +30,7 @@ static void gen_poly( blargg_ulong mask, int count, byte* out ) { // implemented using "Galios configuration" bits |= (n & 1) << b; - n = (n >> 1) ^ (mask & (blargg_ulong)-(blargg_long)(n & 1)); + n = (n >> 1) ^ (mask & -(n & 1)); } while ( b++ < 7 ); *out++ = bits; @@ -66,7 +66,7 @@ Sap_Apu_Impl::Sap_Apu_Impl() blargg_ulong rev = n & 1; for ( int i = 1; i < poly5_len; i++ ) rev |= (n >> i & 1) << (poly5_len - i); - dprintf( "poly5: 0x%08lX\n", rev ); + debug_printf( "poly5: 0x%08lX\n", rev ); } } @@ -114,7 +114,7 @@ inline void Sap_Apu::calc_periods() period = (period - 6) * divider; if ( (osc [-1].regs [1] & 0x1F) > 0x10 ) - dprintf( "Use of slave channel in 16-bit mode not supported\n" ); + debug_printf( "Use of slave channel in 16-bit mode not supported\n" ); } } osc->period = period; diff --git a/game-music-emu/gme/Sap_Apu.h b/game-music-emu/gme/Sap_Apu.h index c71ce31ed..8cdd7e50c 100644 --- a/game-music-emu/gme/Sap_Apu.h +++ b/game-music-emu/gme/Sap_Apu.h @@ -1,6 +1,6 @@ // Atari POKEY sound chip emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef SAP_APU_H #define SAP_APU_H diff --git a/game-music-emu/gme/Sap_Cpu.cpp b/game-music-emu/gme/Sap_Cpu.cpp index 10dc60618..fd9112769 100644 --- a/game-music-emu/gme/Sap_Cpu.cpp +++ b/game-music-emu/gme/Sap_Cpu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Sap_Cpu.h" @@ -889,7 +889,7 @@ imm##op: goto loop; } delayed_cli: - dprintf( "Delayed CLI not emulated\n" ); + debug_printf( "Delayed CLI not emulated\n" ); goto loop; } @@ -904,7 +904,7 @@ imm##op: s_time += delta; if ( s_time < 0 ) goto loop; - dprintf( "Delayed SEI not emulated\n" ); + debug_printf( "Delayed SEI not emulated\n" ); goto loop; } @@ -945,7 +945,7 @@ handle_brk: goto idle_done; pc++; result_ = 4; - dprintf( "BRK executed\n" ); + debug_printf( "BRK executed\n" ); interrupt: { diff --git a/game-music-emu/gme/Sap_Cpu.h b/game-music-emu/gme/Sap_Cpu.h index 433a4e3d3..ea42c7a80 100644 --- a/game-music-emu/gme/Sap_Cpu.h +++ b/game-music-emu/gme/Sap_Cpu.h @@ -1,6 +1,6 @@ // Atari 6502 CPU emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef SAP_CPU_H #define SAP_CPU_H diff --git a/game-music-emu/gme/Sap_Emu.cpp b/game-music-emu/gme/Sap_Emu.cpp index dfee3de72..cb52714f9 100644 --- a/game-music-emu/gme/Sap_Emu.cpp +++ b/game-music-emu/gme/Sap_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Sap_Emu.h" @@ -119,7 +119,7 @@ static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out char const* tag = (char const*) in; while ( in < line_end && *in > ' ' ) in++; - int tag_len = int((char const*) in - tag); + int tag_len = (char const*) in - tag; while ( in < line_end && *in <= ' ' ) in++; @@ -256,7 +256,7 @@ blargg_err_t Sap_Emu::load_mem_( byte const* in, long size ) set_warning( info.warning ); set_track_count( info.track_count ); - set_voice_count( Sap_Apu::osc_count << (int)info.stereo ); + set_voice_count( Sap_Apu::osc_count << info.stereo ); apu_impl.volume( gain() ); return setup_buffer( 1773447 ); @@ -315,8 +315,8 @@ inline void Sap_Emu::call_init( int track ) case 'C': r.a = 0x70; - r.x = (BOOST::uint8_t)(info.music_addr&0xFF); - r.y = (BOOST::uint8_t)(info.music_addr >> 8); + r.x = info.music_addr&0xFF; + r.y = info.music_addr >> 8; run_routine( info.play_addr + 3 ); r.a = 0; r.x = track; @@ -336,7 +336,7 @@ blargg_err_t Sap_Emu::start_track_( int track ) { unsigned start = get_le16( in ); unsigned end = get_le16( in + 2 ); - //dprintf( "Block $%04X-$%04X\n", start, end ); + //debug_printf( "Block $%04X-$%04X\n", start, end ); in += 4; if ( end < start ) { @@ -390,7 +390,7 @@ void Sap_Emu::cpu_write_( sap_addr_t addr, int data ) } if ( (addr & ~0x0010) != 0xD20F || data != 0x03 ) - dprintf( "Unmapped write $%04X <- $%02X\n", addr, data ); + debug_printf( "Unmapped write $%04X <- $%02X\n", addr, data ); } inline void Sap_Emu::call_play() diff --git a/game-music-emu/gme/Sap_Emu.h b/game-music-emu/gme/Sap_Emu.h index 4878faa66..5b0dc47df 100644 --- a/game-music-emu/gme/Sap_Emu.h +++ b/game-music-emu/gme/Sap_Emu.h @@ -1,6 +1,6 @@ // Atari XL/XE SAP music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef SAP_EMU_H #define SAP_EMU_H diff --git a/game-music-emu/gme/Sms_Apu.cpp b/game-music-emu/gme/Sms_Apu.cpp index be226f8f9..b41fdec41 100644 --- a/game-music-emu/gme/Sms_Apu.cpp +++ b/game-music-emu/gme/Sms_Apu.cpp @@ -141,7 +141,7 @@ void Sms_Noise::run( blip_time_t time, blip_time_t end_time ) do { int changed = shifter + 1; - shifter = (feedback & (unsigned)-(signed)(shifter & 1)) ^ (shifter >> 1); + shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1); if ( changed & 2 ) // true if bits 0 and 1 differ { delta = -delta; diff --git a/game-music-emu/gme/Snes_Spc.cpp b/game-music-emu/gme/Snes_Spc.cpp index d23e2bbe9..de5585ffc 100644 --- a/game-music-emu/gme/Snes_Spc.cpp +++ b/game-music-emu/gme/Snes_Spc.cpp @@ -1,6 +1,6 @@ // SPC emulation support: init, sample buffering, reset, SPC loading -// snes_spc 0.9.0. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Snes_Spc.h" @@ -303,7 +303,7 @@ void Snes_Spc::set_output( sample_t* out, int size ) assert( out <= out_end ); } - dsp.set_output( out, int(out_end - out) ); + dsp.set_output( out, out_end - out ); } else { diff --git a/game-music-emu/gme/Snes_Spc.h b/game-music-emu/gme/Snes_Spc.h index 93a593cc0..d6c4e8135 100644 --- a/game-music-emu/gme/Snes_Spc.h +++ b/game-music-emu/gme/Snes_Spc.h @@ -1,6 +1,6 @@ // SNES SPC-700 APU emulator -// snes_spc 0.9.0 +// Game_Music_Emu 0.6.0 #ifndef SNES_SPC_H #define SNES_SPC_H @@ -66,10 +66,7 @@ public: // Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc. enum { tempo_unit = 0x100 }; void set_tempo( int ); - - enum { gain_unit = Spc_Dsp::gain_unit }; - void set_gain( int gain ); - + // SPC music files // Loads SPC data into emulator @@ -107,6 +104,22 @@ public: bool check_kon(); #endif +public: + // TODO: document + struct regs_t + { + int pc; + int a; + int x; + int y; + int psw; + int sp; + }; + regs_t& smp_regs() { return m.cpu_regs; } + + uint8_t* smp_ram() { return m.ram.ram; } + + void run_until( time_t t ) { run_until_( t ); } public: BLARGG_DISABLE_NOTHROW @@ -146,15 +159,7 @@ private: uint8_t smp_regs [2] [reg_count]; - struct - { - int pc; - int a; - int x; - int y; - int psw; - int sp; - } cpu_regs; + regs_t cpu_regs; rel_time_t dsp_time; time_t spc_time; @@ -271,8 +276,6 @@ inline void Snes_Spc::write_port( time_t t, int port, int data ) run_until_( t ) [0x10 + port] = data; } -inline void Snes_Spc::set_gain( int gain ) { dsp.set_gain( gain ); } - inline void Snes_Spc::mute_voices( int mask ) { dsp.mute_voices( mask ); } inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); } diff --git a/game-music-emu/gme/Spc_Cpu.cpp b/game-music-emu/gme/Spc_Cpu.cpp index d59f778da..90f60ed29 100644 --- a/game-music-emu/gme/Spc_Cpu.cpp +++ b/game-music-emu/gme/Spc_Cpu.cpp @@ -1,6 +1,6 @@ // Core SPC emulation: CPU, timers, SMP registers, memory -// snes_spc 0.9.0. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Snes_Spc.h" @@ -176,7 +176,7 @@ inline void Snes_Spc::dsp_write( int data, rel_time_t time ) if ( REGS [r_dspaddr] <= 0x7F ) dsp.write( REGS [r_dspaddr], data ); else if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to DSP register > $7F\n" ); + debug_printf( "SPC wrote to DSP register > $7F\n" ); } @@ -277,8 +277,9 @@ static unsigned char const glitch_probs [3] [256] = }; #endif -// divided into multiple functions to keep rarely-used functionality separate -// so often-used functionality can be optimized better by compiler +// Read/write handlers are divided into multiple functions to keep rarely-used +// functionality separate so often-used functionality can be optimized better +// by compiler. // If write isn't preceded by read, data has this added to it int const no_read_before_write = 0x2000; @@ -302,7 +303,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr ) t->next_time == time + TIMER_MUL( t, 1 ) && ((period - 1) | ~0x0F) & period ) { - //dprintf( "SPC pathological timer target write\n" ); + //debug_printf( "SPC pathological timer target write\n" ); // If the period is 3, 5, or 9, there's a probability this behavior won't occur, // based on the previous period @@ -331,7 +332,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr ) case r_t1out: case r_t2out: if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to counter %d\n", (int) addr - r_t0out ); + debug_printf( "SPC wrote to counter %d\n", (int) addr - r_t0out ); if ( data < no_read_before_write / 2 ) run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0; @@ -345,7 +346,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr ) case r_test: if ( (uint8_t) data != 0x0A ) - dprintf( "SPC wrote to test register\n" ); + debug_printf( "SPC wrote to test register\n" ); break; case r_control: diff --git a/game-music-emu/gme/Spc_Cpu.h b/game-music-emu/gme/Spc_Cpu.h index e1b4b17b8..4742e0990 100644 --- a/game-music-emu/gme/Spc_Cpu.h +++ b/game-music-emu/gme/Spc_Cpu.h @@ -1,4 +1,4 @@ -// snes_spc 0.9.0. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ /* Copyright (C) 2004-2007 Shay Green. This module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser @@ -16,7 +16,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #if SPC_MORE_ACCURACY #define SUSPICIOUS_OPCODE( name ) ((void) 0) #else - #define SUSPICIOUS_OPCODE( name ) dprintf( "SPC: suspicious opcode: " name "\n" ) + #define SUSPICIOUS_OPCODE( name ) debug_printf( "SPC: suspicious opcode: " name "\n" ) #endif #define CPU_READ( time, offset, addr )\ @@ -69,7 +69,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define READ_PROG16( addr ) GET_LE16( ram + (addr) ) #define SET_PC( n ) (pc = ram + (n)) -#define GET_PC() (int(pc - ram)) +#define GET_PC() (pc - ram) #define READ_PC( pc ) (*(pc)) #define READ_PC16( pc ) GET_LE16( pc ) @@ -77,7 +77,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define SPC_NO_SP_WRAPAROUND 0 #define SET_SP( v ) (sp = ram + 0x101 + (v)) -#define GET_SP() (int(sp - 0x101 - ram)) +#define GET_SP() (sp - 0x101 - ram) #if SPC_NO_SP_WRAPAROUND #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v )) @@ -87,7 +87,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #else #define PUSH16( data )\ {\ - int addr = int((sp -= 2) - ram);\ + int addr = (sp -= 2) - ram;\ if ( addr > 0x100 )\ {\ SET_LE16( sp, data );\ @@ -242,7 +242,7 @@ loop: BRANCH( (uint8_t) nz ) case 0x3F:{// CALL - int old_addr = int(GET_PC() + 2); + int old_addr = GET_PC() + 2; SET_PC( READ_PC16( pc ) ); PUSH16( old_addr ); goto loop; @@ -256,7 +256,7 @@ loop: } #else { - int addr = int(sp - ram); + int addr = sp - ram; SET_PC( GET_LE16( sp ) ); sp += 2; if ( addr < 0x1FF ) @@ -1184,7 +1184,7 @@ loop: { addr &= 0xFFFF; SET_PC( addr ); - dprintf( "SPC: PC wrapped around\n" ); + debug_printf( "SPC: PC wrapped around\n" ); goto loop; } } @@ -1205,7 +1205,7 @@ stop: // Uncache registers if ( GET_PC() >= 0x10000 ) - dprintf( "SPC: PC wrapped around\n" ); + debug_printf( "SPC: PC wrapped around\n" ); m.cpu_regs.pc = (uint16_t) GET_PC(); m.cpu_regs.sp = ( uint8_t) GET_SP(); m.cpu_regs.a = ( uint8_t) a; diff --git a/game-music-emu/gme/Spc_Dsp.cpp b/game-music-emu/gme/Spc_Dsp.cpp index 41c79c152..0a84bfe16 100644 --- a/game-music-emu/gme/Spc_Dsp.cpp +++ b/game-music-emu/gme/Spc_Dsp.cpp @@ -1,4 +1,4 @@ -// snes_spc 0.9.0. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Spc_Dsp.h" @@ -155,7 +155,7 @@ inline void Spc_Dsp::init_counter() // counters start out with this synchronization m.counters [0] = 1; m.counters [1] = 0; - m.counters [2] = -0x20; + m.counters [2] = -0x20u; m.counters [3] = 0x0B; int n = 2; @@ -606,8 +606,8 @@ skip_brr: } // Sound out - int l = (((main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14) * m.gain) >> 8; - int r = (((main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14) * m.gain) >> 8; + int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14; + int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14; CLAMP16( l ); CLAMP16( r ); @@ -641,7 +641,6 @@ void Spc_Dsp::mute_voices( int mask ) void Spc_Dsp::init( void* ram_64k ) { m.ram = (uint8_t*) ram_64k; - set_gain( gain_unit ); mute_voices( 0 ); disable_surround( false ); set_output( 0, 0 ); diff --git a/game-music-emu/gme/Spc_Dsp.h b/game-music-emu/gme/Spc_Dsp.h index 14b131ac1..401af020a 100644 --- a/game-music-emu/gme/Spc_Dsp.h +++ b/game-music-emu/gme/Spc_Dsp.h @@ -1,12 +1,12 @@ // Fast SNES SPC-700 DSP emulator (about 3x speed of accurate one) -// snes_spc 0.9.0 +// Game_Music_Emu 0.6.0 #ifndef SPC_DSP_H #define SPC_DSP_H #include "blargg_common.h" -class Spc_Dsp { +struct Spc_Dsp { public: typedef BOOST::uint8_t uint8_t; @@ -51,10 +51,7 @@ public: // If true, prevents channels and global volumes from being phase-negated void disable_surround( bool disable = true ); - - enum { gain_unit = 0x100 }; - void set_gain( int gain ); - + // State // Resets DSP and uses supplied values to initialize registers @@ -140,7 +137,6 @@ private: // non-emulation state uint8_t* ram; // 64K shared RAM between DSP and SMP int mute_mask; - int gain; int surround_threshold; sample_t* out; sample_t* out_end; @@ -158,7 +154,7 @@ private: #include -inline int Spc_Dsp::sample_count() const { return int(m.out - m.out_begin); } +inline int Spc_Dsp::sample_count() const { return m.out - m.out_begin; } inline int Spc_Dsp::read( int addr ) const { @@ -204,8 +200,6 @@ inline void Spc_Dsp::write( int addr, int data ) } } -inline void Spc_Dsp::set_gain( int gain ) { m.gain = gain; } - inline void Spc_Dsp::disable_surround( bool disable ) { m.surround_threshold = disable ? 0 : -0x4000; diff --git a/game-music-emu/gme/Spc_Emu.cpp b/game-music-emu/gme/Spc_Emu.cpp index 7f6e72faf..b3c20f317 100644 --- a/game-music-emu/gme/Spc_Emu.cpp +++ b/game-music-emu/gme/Spc_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Spc_Emu.h" @@ -19,6 +19,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "blargg_source.h" +// TODO: support Spc_Filter's bass + Spc_Emu::Spc_Emu() { set_type( gme_spc_type ); @@ -54,7 +56,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out ) byte const* in = begin + 8; if ( end - in > info_size ) { - dprintf( "Extra data after SPC xid6 info\n" ); + debug_printf( "Extra data after SPC xid6 info\n" ); end = in + info_size; } @@ -114,7 +116,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out ) default: if ( id < 0x01 || (id > 0x07 && id < 0x10) || (id > 0x14 && id < 0x30) || id > 0x36 ) - dprintf( "Unknown SPC xid6 block: %X\n", (int) id ); + debug_printf( "Unknown SPC xid6 block: %X\n", (int) id ); break; } if ( field ) @@ -134,7 +136,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out ) { // ...but some files have no padding in = unaligned; - dprintf( "SPC info tag wasn't properly padded to align\n" ); + debug_printf( "SPC info tag wasn't properly padded to align\n" ); break; } } @@ -226,14 +228,14 @@ struct Spc_File : Gme_Info_ { RETURN_ERR( xid6.resize( xid6_size ) ); RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) ); - RETURN_ERR( in.read( xid6.begin(), (long)xid6.size() ) ); + RETURN_ERR( in.read( xid6.begin(), xid6.size() ) ); } return 0; } blargg_err_t track_info_( track_info_t* out, int ) const { - get_spc_info( header, xid6.begin(), (long)xid6.size(), out ); + get_spc_info( header, xid6.begin(), xid6.size(), out ); return 0; } }; @@ -244,12 +246,13 @@ static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; } static gme_type_t_ const gme_spc_type_ = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 }; gme_type_t const gme_spc_type = &gme_spc_type_; + // Setup blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate ) { RETURN_ERR( apu.init() ); - apu.set_gain( (int) (gain() * Snes_Spc::gain_unit) ); + enable_accuracy( false ); if ( sample_rate != native_sample_rate ) { RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) ); @@ -258,6 +261,12 @@ blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate ) return 0; } +void Spc_Emu::enable_accuracy_( bool b ) +{ + Music_Emu::enable_accuracy_( b ); + filter.enable( b ); +} + void Spc_Emu::mute_voices_( int m ) { Music_Emu::mute_voices_( m ); @@ -277,17 +286,29 @@ blargg_err_t Spc_Emu::load_mem_( byte const* in, long size ) // Emulation -void Spc_Emu::set_tempo_( double t ) { apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) ); } +void Spc_Emu::set_tempo_( double t ) +{ + apu.set_tempo( (int) (t * apu.tempo_unit) ); +} blargg_err_t Spc_Emu::start_track_( int track ) { RETURN_ERR( Music_Emu::start_track_( track ) ); resampler.clear(); + filter.clear(); RETURN_ERR( apu.load_spc( file_data, file_size ) ); + filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) ); apu.clear_echo(); return 0; } +blargg_err_t Spc_Emu::play_and_filter( long count, sample_t out [] ) +{ + RETURN_ERR( apu.play( count, out ) ); + filter.run( out, count ); + return 0; +} + blargg_err_t Spc_Emu::skip_( long count ) { if ( sample_rate() != native_sample_rate ) @@ -299,7 +320,10 @@ blargg_err_t Spc_Emu::skip_( long count ) // TODO: shouldn't skip be adjusted for the 64 samples read afterwards? if ( count > 0 ) + { RETURN_ERR( apu.skip( count ) ); + filter.clear(); + } // eliminate pop due to resampler const int resampler_latency = 64; @@ -310,7 +334,7 @@ blargg_err_t Spc_Emu::skip_( long count ) blargg_err_t Spc_Emu::play_( long count, sample_t* out ) { if ( sample_rate() == native_sample_rate ) - return apu.play( count, out ); + return play_and_filter( count, out ); long remain = count; while ( remain > 0 ) @@ -319,7 +343,7 @@ blargg_err_t Spc_Emu::play_( long count, sample_t* out ) if ( remain > 0 ) { long n = resampler.max_write(); - RETURN_ERR( apu.play( n, resampler.buffer() ) ); + RETURN_ERR( play_and_filter( n, resampler.buffer() ) ); resampler.write( n ); } } diff --git a/game-music-emu/gme/Spc_Emu.h b/game-music-emu/gme/Spc_Emu.h index 0c4a7fb27..09063f123 100644 --- a/game-music-emu/gme/Spc_Emu.h +++ b/game-music-emu/gme/Spc_Emu.h @@ -1,12 +1,13 @@ // Super Nintendo SPC music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef SPC_EMU_H #define SPC_EMU_H #include "Fir_Resampler.h" #include "Music_Emu.h" #include "Snes_Spc.h" +#include "Spc_Filter.h" class Spc_Emu : public Music_Emu { public: @@ -65,11 +66,15 @@ protected: blargg_err_t skip_( long ); void mute_voices_( int ); void set_tempo_( double ); + void enable_accuracy_( bool ); private: byte const* file_data; long file_size; Fir_Resampler<24> resampler; + SPC_Filter filter; Snes_Spc apu; + + blargg_err_t play_and_filter( long count, sample_t out [] ); }; inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); } diff --git a/game-music-emu/gme/Spc_Filter.cpp b/game-music-emu/gme/Spc_Filter.cpp new file mode 100644 index 000000000..0f2d18a83 --- /dev/null +++ b/game-music-emu/gme/Spc_Filter.cpp @@ -0,0 +1,83 @@ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ + +#include "Spc_Filter.h" + +#include + +/* Copyright (C) 2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); } + +SPC_Filter::SPC_Filter() +{ + enabled = true; + gain = gain_unit; + bass = bass_norm; + clear(); +} + +void SPC_Filter::run( short* io, int count ) +{ + require( (count & 1) == 0 ); // must be even + + int const gain = this->gain; + if ( enabled ) + { + int const bass = this->bass; + chan_t* c = &ch [2]; + do + { + // cache in registers + int sum = (--c)->sum; + int pp1 = c->pp1; + int p1 = c->p1; + + for ( int i = 0; i < count; i += 2 ) + { + // Low-pass filter (two point FIR with coeffs 0.25, 0.75) + int f = io [i] + p1; + p1 = io [i] * 3; + + // High-pass filter ("leaky integrator") + int delta = f - pp1; + pp1 = f; + int s = sum >> (gain_bits + 2); + sum += (delta * gain) - (sum >> bass); + + // Clamp to 16 bits + if ( (short) s != s ) + s = (s >> 31) ^ 0x7FFF; + + io [i] = (short) s; + } + + c->p1 = p1; + c->pp1 = pp1; + c->sum = sum; + ++io; + } + while ( c != ch ); + } + else if ( gain != gain_unit ) + { + short* const end = io + count; + while ( io < end ) + { + int s = (*io * gain) >> gain_bits; + if ( (short) s != s ) + s = (s >> 31) ^ 0x7FFF; + *io++ = (short) s; + } + } +} diff --git a/game-music-emu/gme/Spc_Filter.h b/game-music-emu/gme/Spc_Filter.h new file mode 100644 index 000000000..5cdcc3606 --- /dev/null +++ b/game-music-emu/gme/Spc_Filter.h @@ -0,0 +1,53 @@ +// Simple low-pass and high-pass filter to better match sound output of a SNES + +// Game_Music_Emu 0.6.0 +#ifndef SPC_FILTER_H +#define SPC_FILTER_H + +#include "blargg_common.h" + +struct SPC_Filter { +public: + + // Filters count samples of stereo sound in place. Count must be a multiple of 2. + typedef short sample_t; + void run( sample_t* io, int count ); + +// Optional features + + // Clears filter to silence + void clear(); + + // Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit + // are fine, since output is clamped to 16-bit sample range. + enum { gain_unit = 0x100 }; + void set_gain( int gain ); + + // Enables/disables filtering (when disabled, gain is still applied) + void enable( bool b ); + + // Sets amount of bass (logarithmic scale) + enum { bass_none = 0 }; + enum { bass_norm = 8 }; // normal amount + enum { bass_max = 31 }; + void set_bass( int bass ); + +public: + SPC_Filter(); + BLARGG_DISABLE_NOTHROW +private: + enum { gain_bits = 8 }; + int gain; + int bass; + bool enabled; + struct chan_t { int p1, pp1, sum; }; + chan_t ch [2]; +}; + +inline void SPC_Filter::enable( bool b ) { enabled = b; } + +inline void SPC_Filter::set_gain( int g ) { gain = g; } + +inline void SPC_Filter::set_bass( int b ) { bass = b; } + +#endif diff --git a/game-music-emu/gme/Vgm_Emu.cpp b/game-music-emu/gme/Vgm_Emu.cpp index fe4be10a5..5c6bc7cda 100644 --- a/game-music-emu/gme/Vgm_Emu.cpp +++ b/game-music-emu/gme/Vgm_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Vgm_Emu.h" @@ -36,8 +36,7 @@ Vgm_Emu::Vgm_Emu() set_silence_lookahead( 1 ); // tracks should already be trimmed - static equalizer_t const eq = { -14.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; - set_equalizer( eq ); + set_equalizer( make_equalizer( -14.0, 80 ) ); } Vgm_Emu::~Vgm_Emu() { } @@ -58,7 +57,7 @@ static byte const* skip_gd3_str( byte const* in, byte const* end ) static byte const* get_gd3_str( byte const* in, byte const* end, char* field ) { byte const* mid = skip_gd3_str( in, end ); - int len = int(mid - in) / 2 - 1; + int len = (mid - in) / 2 - 1; if ( len > 0 ) { len = min( len, (int) Gme_File::max_field_ ); @@ -109,7 +108,7 @@ byte const* Vgm_Emu::gd3_data( int* size ) const return 0; byte const* gd3 = data + header_size + gd3_offset; - long gd3_size = check_gd3_header( gd3, long(data_end - gd3) ); + long gd3_size = check_gd3_header( gd3, data_end - gd3 ); if ( !gd3_size ) return 0; @@ -185,7 +184,7 @@ struct Vgm_File : Gme_Info_ if ( gd3_size ) { RETURN_ERR( gd3.resize( gd3_size ) ); - RETURN_ERR( in.read( gd3.begin(), (long)gd3.size() ) ); + RETURN_ERR( in.read( gd3.begin(), gd3.size() ) ); } } return 0; @@ -218,8 +217,8 @@ void Vgm_Emu::set_tempo_( double t ) { vgm_rate = (long) (44100 * t + 0.5); blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 ); - //dprintf( "blip_time_factor: %ld\n", blip_time_factor ); - //dprintf( "vgm_rate: %ld\n", vgm_rate ); + //debug_printf( "blip_time_factor: %ld\n", blip_time_factor ); + //debug_printf( "vgm_rate: %ld\n", vgm_rate ); // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only) //blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 ); //vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 ); diff --git a/game-music-emu/gme/Vgm_Emu.h b/game-music-emu/gme/Vgm_Emu.h index 7a82fd109..65895afaa 100644 --- a/game-music-emu/gme/Vgm_Emu.h +++ b/game-music-emu/gme/Vgm_Emu.h @@ -1,6 +1,6 @@ // Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef VGM_EMU_H #define VGM_EMU_H diff --git a/game-music-emu/gme/Vgm_Emu_Impl.cpp b/game-music-emu/gme/Vgm_Emu_Impl.cpp index a2d7c93e5..60dc099fe 100644 --- a/game-music-emu/gme/Vgm_Emu_Impl.cpp +++ b/game-music-emu/gme/Vgm_Emu_Impl.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Vgm_Emu.h" @@ -244,7 +244,7 @@ int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t* int pairs = min_pairs; while ( (pairs = to_fm_time( vgm_time )) < min_pairs ) vgm_time++; - //dprintf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs ); + //debug_printf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs ); if ( ym2612.enabled() ) { diff --git a/game-music-emu/gme/Vgm_Emu_Impl.h b/game-music-emu/gme/Vgm_Emu_Impl.h index 4d387d090..b50094a01 100644 --- a/game-music-emu/gme/Vgm_Emu_Impl.h +++ b/game-music-emu/gme/Vgm_Emu_Impl.h @@ -1,6 +1,6 @@ // Low-level parts of Vgm_Emu -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef VGM_EMU_IMPL_H #define VGM_EMU_IMPL_H diff --git a/game-music-emu/gme/Ym2413_Emu.cpp b/game-music-emu/gme/Ym2413_Emu.cpp index ede673045..d1c7a71b1 100644 --- a/game-music-emu/gme/Ym2413_Emu.cpp +++ b/game-music-emu/gme/Ym2413_Emu.cpp @@ -1,7 +1,7 @@ // Use in place of Ym2413_Emu.cpp and ym2413.c to disable support for this chip -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Ym2413_Emu.h" diff --git a/game-music-emu/gme/Ym2413_Emu.h b/game-music-emu/gme/Ym2413_Emu.h index 98a2a48e1..53ce38a96 100644 --- a/game-music-emu/gme/Ym2413_Emu.h +++ b/game-music-emu/gme/Ym2413_Emu.h @@ -1,6 +1,6 @@ // YM2413 FM sound chip emulator interface -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef YM2413_EMU_H #define YM2413_EMU_H diff --git a/game-music-emu/gme/Ym2612_Emu.cpp b/game-music-emu/gme/Ym2612_Emu.cpp index 41ebb093d..5ea5c9a24 100644 --- a/game-music-emu/gme/Ym2612_Emu.cpp +++ b/game-music-emu/gme/Ym2612_Emu.cpp @@ -1,4 +1,4 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ // Based on Gens 2.10 ym2612.c diff --git a/game-music-emu/gme/Ym2612_Emu.h b/game-music-emu/gme/Ym2612_Emu.h index 383ac72d7..51cff6586 100644 --- a/game-music-emu/gme/Ym2612_Emu.h +++ b/game-music-emu/gme/Ym2612_Emu.h @@ -1,6 +1,6 @@ // YM2612 FM sound chip emulator interface -// Game_Music_Emu 0.5.2 +// Game_Music_Emu 0.6.0 #ifndef YM2612_EMU_H #define YM2612_EMU_H diff --git a/game-music-emu/gme/blargg_common.h b/game-music-emu/gme/blargg_common.h index e48d6469b..ed218a8da 100644 --- a/game-music-emu/gme/blargg_common.h +++ b/game-music-emu/gme/blargg_common.h @@ -15,6 +15,13 @@ #ifndef BLARGG_COMMON_H #define BLARGG_COMMON_H +// BLARGG_RESTRICT: equivalent to restrict, where supported +#if __GNUC__ >= 3 || _MSC_VER >= 1100 + #define BLARGG_RESTRICT __restrict +#else + #define BLARGG_RESTRICT +#endif + // STATIC_CAST(T,expr): Used in place of static_cast (expr) #ifndef STATIC_CAST #define STATIC_CAST(T,expr) ((T) (expr)) @@ -54,10 +61,11 @@ public: }; #ifndef BLARGG_DISABLE_NOTHROW - #if __cplusplus < 199711 - #define BLARGG_THROWS( spec ) - #else + // throw spec mandatory in ISO C++ if operator new can return NULL + #if __cplusplus >= 199711 || __GNUC__ >= 3 #define BLARGG_THROWS( spec ) throw spec + #else + #define BLARGG_THROWS( spec ) #endif #define BLARGG_DISABLE_NOTHROW \ void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\ @@ -68,6 +76,7 @@ public: #define BLARGG_NEW new (std::nothrow) #endif +// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant) #define BLARGG_4CHAR( a, b, c, d ) \ ((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF)) @@ -110,18 +119,17 @@ public: #endif // blargg_long/blargg_ulong = at least 32 bits, int if it's big enough -#include -#if INT_MAX >= 0x7FFFFFFF - typedef int blargg_long; -#else +#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF typedef long blargg_long; +#else + typedef int blargg_long; #endif -#if UINT_MAX >= 0xFFFFFFFF - typedef unsigned blargg_ulong; -#else +#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF typedef unsigned long blargg_ulong; +#else + typedef unsigned blargg_ulong; #endif // BOOST::int8_t etc. @@ -171,5 +179,18 @@ public: }; #endif +#if __GNUC__ >= 3 + #define BLARGG_DEPRECATED __attribute__ ((deprecated)) +#else + #define BLARGG_DEPRECATED +#endif + +// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib. +// During development, BLARGG_PURE( x ) expands to = 0; +// virtual int func() BLARGG_PURE( { return 0; } ) +#ifndef BLARGG_PURE + #define BLARGG_PURE( def ) def +#endif + #endif #endif diff --git a/game-music-emu/gme/blargg_config.h b/game-music-emu/gme/blargg_config.h index 5967b0fbe..377dd2d8c 100644 --- a/game-music-emu/gme/blargg_config.h +++ b/game-music-emu/gme/blargg_config.h @@ -6,9 +6,22 @@ // Uncomment to use zlib for transparent decompression of gzipped files //#define HAVE_ZLIB_H -// Uncomment to support only the listed game music types. See gme_type_list.cpp -// for a list of all types. -//#define GME_TYPE_LIST gme_nsf_type, gme_gbs_type +// Uncomment and edit list to support only the listed game music types, +// so that the others don't get linked in at all. +/* +#define GME_TYPE_LIST \ + gme_ay_type,\ + gme_gbs_type,\ + gme_gym_type,\ + gme_hes_type,\ + gme_kss_type,\ + gme_nsf_type,\ + gme_nsfe_type,\ + gme_sap_type,\ + gme_spc_type,\ + gme_vgm_type,\ + gme_vgz_type +*/ // Uncomment to enable platform-specific optimizations //#define BLARGG_NONPORTABLE 1 @@ -27,5 +40,4 @@ #include "config.h" #endif - #endif diff --git a/game-music-emu/gme/blargg_endian.h b/game-music-emu/gme/blargg_endian.h index 671655654..ba09e067e 100644 --- a/game-music-emu/gme/blargg_endian.h +++ b/game-music-emu/gme/blargg_endian.h @@ -1,20 +1,20 @@ // CPU Byte Order Utilities -// Game_Music_Emu 0.5.2 #ifndef BLARGG_ENDIAN #define BLARGG_ENDIAN #include "blargg_common.h" // BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16) -#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ - defined (__x86_64__) || defined (__ia64__) || defined (__i386__) +#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64) #define BLARGG_CPU_X86 1 #define BLARGG_CPU_CISC 1 #endif -#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc) +#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \ + defined (__POWERPC__) || defined (__powerc) #define BLARGG_CPU_POWERPC 1 + #define BLARGG_CPU_RISC 1 #endif // BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only @@ -36,10 +36,10 @@ #endif #if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \ - defined (__mips__) || defined (__sparc__) || BLARGG_CPU_POWERPC || \ + defined (__sparc__) || BLARGG_CPU_POWERPC || \ (defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321) #define BLARGG_BIG_ENDIAN 1 -#else +#elif !defined (__mips__) // No endian specified; assume little-endian, since it's most common #define BLARGG_LITTLE_ENDIAN 1 #endif @@ -64,45 +64,60 @@ inline void blargg_verify_byte_order() #endif } -inline unsigned get_le16( void const* p ) { - return ((unsigned char const*) p) [1] * 0x100u + - ((unsigned char const*) p) [0]; +inline unsigned get_le16( void const* p ) +{ + return (unsigned) ((unsigned char const*) p) [1] << 8 | + (unsigned) ((unsigned char const*) p) [0]; } -inline unsigned get_be16( void const* p ) { - return ((unsigned char const*) p) [0] * 0x100u + - ((unsigned char const*) p) [1]; + +inline unsigned get_be16( void const* p ) +{ + return (unsigned) ((unsigned char const*) p) [0] << 8 | + (unsigned) ((unsigned char const*) p) [1]; } -inline blargg_ulong get_le32( void const* p ) { - return ((unsigned char const*) p) [3] * 0x01000000u + - ((unsigned char const*) p) [2] * 0x00010000u + - ((unsigned char const*) p) [1] * 0x00000100u + - ((unsigned char const*) p) [0]; + +inline blargg_ulong get_le32( void const* p ) +{ + return (blargg_ulong) ((unsigned char const*) p) [3] << 24 | + (blargg_ulong) ((unsigned char const*) p) [2] << 16 | + (blargg_ulong) ((unsigned char const*) p) [1] << 8 | + (blargg_ulong) ((unsigned char const*) p) [0]; } -inline blargg_ulong get_be32( void const* p ) { - return ((unsigned char const*) p) [0] * 0x01000000u + - ((unsigned char const*) p) [1] * 0x00010000u + - ((unsigned char const*) p) [2] * 0x00000100u + - ((unsigned char const*) p) [3]; + +inline blargg_ulong get_be32( void const* p ) +{ + return (blargg_ulong) ((unsigned char const*) p) [0] << 24 | + (blargg_ulong) ((unsigned char const*) p) [1] << 16 | + (blargg_ulong) ((unsigned char const*) p) [2] << 8 | + (blargg_ulong) ((unsigned char const*) p) [3]; } -inline void set_le16( void* p, unsigned n ) { + +inline void set_le16( void* p, unsigned n ) +{ ((unsigned char*) p) [1] = (unsigned char) (n >> 8); ((unsigned char*) p) [0] = (unsigned char) n; } -inline void set_be16( void* p, unsigned n ) { + +inline void set_be16( void* p, unsigned n ) +{ ((unsigned char*) p) [0] = (unsigned char) (n >> 8); ((unsigned char*) p) [1] = (unsigned char) n; } -inline void set_le32( void* p, blargg_ulong n ) { - ((unsigned char*) p) [3] = (unsigned char) (n >> 24); - ((unsigned char*) p) [2] = (unsigned char) (n >> 16); - ((unsigned char*) p) [1] = (unsigned char) (n >> 8); + +inline void set_le32( void* p, blargg_ulong n ) +{ ((unsigned char*) p) [0] = (unsigned char) n; + ((unsigned char*) p) [1] = (unsigned char) (n >> 8); + ((unsigned char*) p) [2] = (unsigned char) (n >> 16); + ((unsigned char*) p) [3] = (unsigned char) (n >> 24); } -inline void set_be32( void* p, blargg_ulong n ) { - ((unsigned char*) p) [0] = (unsigned char) (n >> 24); - ((unsigned char*) p) [1] = (unsigned char) (n >> 16); - ((unsigned char*) p) [2] = (unsigned char) (n >> 8); + +inline void set_be32( void* p, blargg_ulong n ) +{ ((unsigned char*) p) [3] = (unsigned char) n; + ((unsigned char*) p) [2] = (unsigned char) (n >> 8); + ((unsigned char*) p) [1] = (unsigned char) (n >> 16); + ((unsigned char*) p) [0] = (unsigned char) (n >> 24); } #if BLARGG_NONPORTABLE @@ -117,30 +132,41 @@ inline void set_be32( void* p, blargg_ulong n ) { #define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr)) #define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data)) #define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data)) - #endif - - #if BLARGG_CPU_POWERPC && defined (__MWERKS__) - // PowerPC has special byte-reversed instructions - // to do: assumes that PowerPC is running in big-endian mode - // to do: implement for other compilers which don't support these macros - #define GET_LE16( addr ) (__lhbrx( (addr), 0 )) - #define GET_LE32( addr ) (__lwbrx( (addr), 0 )) - #define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 )) - #define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 )) + + #if BLARGG_CPU_POWERPC + // PowerPC has special byte-reversed instructions + #if defined (__MWERKS__) + #define GET_LE16( addr ) (__lhbrx( addr, 0 )) + #define GET_LE32( addr ) (__lwbrx( addr, 0 )) + #define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 )) + #define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 )) + #elif defined (__GNUC__) + #define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;}) + #define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;}) + #define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );}) + #define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );}) + #endif + #endif #endif #endif #ifndef GET_LE16 #define GET_LE16( addr ) get_le16( addr ) - #define GET_LE32( addr ) get_le32( addr ) #define SET_LE16( addr, data ) set_le16( addr, data ) +#endif + +#ifndef GET_LE32 + #define GET_LE32( addr ) get_le32( addr ) #define SET_LE32( addr, data ) set_le32( addr, data ) #endif #ifndef GET_BE16 #define GET_BE16( addr ) get_be16( addr ) - #define GET_BE32( addr ) get_be32( addr ) #define SET_BE16( addr, data ) set_be16( addr, data ) +#endif + +#ifndef GET_BE32 + #define GET_BE32( addr ) get_be32( addr ) #define SET_BE32( addr, data ) set_be32( addr, data ) #endif diff --git a/game-music-emu/gme/blargg_source.h b/game-music-emu/gme/blargg_source.h index 945bf3498..b011777ad 100644 --- a/game-music-emu/gme/blargg_source.h +++ b/game-music-emu/gme/blargg_source.h @@ -1,4 +1,8 @@ -// Included at the beginning of library source files, after all other #include lines +/* Included at the beginning of library source files, after all other #include lines. +Sets up helpful macros and services used in my source code. They don't need +module an annoying module prefix on their names since they are defined after +all other #include lines. */ + #ifndef BLARGG_SOURCE_H #define BLARGG_SOURCE_H @@ -16,10 +20,10 @@ // Like printf() except output goes to debug log file. Might be defined to do // nothing (not even evaluate its arguments). -// void dprintf( const char* format, ... ); -inline void blargg_dprintf_( const char*, ... ) { } -#undef dprintf -#define dprintf (1) ? (void) 0 : blargg_dprintf_ +// void debug_printf( const char* format, ... ); +static inline void blargg_dprintf_( const char*, ... ) { } +#undef debug_printf +#define debug_printf (1) ? (void) 0 : blargg_dprintf_ // If enabled, evaluate expr and if false, make debug log entry with source file // and line. Meant for finding situations that should be examined further, but that @@ -42,9 +46,25 @@ inline void blargg_dprintf_( const char*, ... ) { } #undef min #undef max +#define DEF_MIN_MAX( type ) \ + static inline type min( type x, type y ) { if ( x < y ) return x; return y; }\ + static inline type max( type x, type y ) { if ( y < x ) return x; return y; } + +DEF_MIN_MAX( int ) +DEF_MIN_MAX( unsigned ) +DEF_MIN_MAX( long ) +DEF_MIN_MAX( unsigned long ) +DEF_MIN_MAX( float ) +DEF_MIN_MAX( double ) + +#undef DEF_MIN_MAX + +/* // using const references generates crappy code, and I am currenly only using these // for built-in types, so they take arguments by value +// TODO: remove +inline int min( int x, int y ) template inline T min( T x, T y ) { @@ -60,17 +80,29 @@ inline T max( T x, T y ) return y; return x; } +*/ // TODO: good idea? bad idea? #undef byte #define byte byte_ typedef unsigned char byte; +// Setup compiler defines useful for exporting required public API symbols in gme.cpp +#ifndef BLARGG_EXPORT + #if defined (_WIN32) && defined(BLARGG_BUILD_DLL) + #define BLARGG_EXPORT __declspec(dllexport) + #elif defined (LIBGME_VISIBILITY) + #define BLARGG_EXPORT __attribute__((visibility ("default"))) + #else + #define BLARGG_EXPORT + #endif +#endif + // deprecated #define BLARGG_CHECK_ALLOC CHECK_ALLOC #define BLARGG_RETURN_ERR RETURN_ERR -// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check +// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check #ifdef BLARGG_SOURCE_BEGIN #include BLARGG_SOURCE_BEGIN #endif diff --git a/game-music-emu/gme/gb_cpu_io.h b/game-music-emu/gme/gb_cpu_io.h index ada99eadc..8bd69aa2d 100644 --- a/game-music-emu/gme/gb_cpu_io.h +++ b/game-music-emu/gme/gb_cpu_io.h @@ -10,9 +10,9 @@ int Gbs_Emu::cpu_read( gb_addr_t addr ) result = apu.read_register( clock(), addr ); #ifndef NDEBUG else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 ) - dprintf( "Read from unmapped memory $%.4x\n", (unsigned) addr ); + debug_printf( "Read from unmapped memory $%.4x\n", (unsigned) addr ); else if ( unsigned (addr - 0xFF01) < 0xFF80 - 0xFF01 ) - dprintf( "Unhandled I/O read 0x%4X\n", (unsigned) addr ); + debug_printf( "Unhandled I/O read 0x%4X\n", (unsigned) addr ); #endif return result; } @@ -38,7 +38,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data ) ram [offset] = 0xFF; //if ( addr == 0xFFFF ) - // dprintf( "Wrote interrupt mask\n" ); + // debug_printf( "Wrote interrupt mask\n" ); } } else if ( (addr ^ 0x2000) <= 0x2000 - 1 ) @@ -48,7 +48,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data ) #ifndef NDEBUG else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 ) { - dprintf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr ); + debug_printf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr ); } #endif } @@ -59,7 +59,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data ) #define CPU_READ_FAST_( emu, addr, time, out ) \ {\ out = READ_PROG( addr );\ - if ( unsigned (addr - Gb_Apu::start_addr) <= Gb_Apu::register_count )\ + if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )\ out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\ else\ check( out == emu->cpu_read( addr ) );\ diff --git a/game-music-emu/gme/gme.cpp b/game-music-emu/gme/gme.cpp index c9154c7a4..c05f25eb4 100644 --- a/game-music-emu/gme/gme.cpp +++ b/game-music-emu/gme/gme.cpp @@ -1,9 +1,8 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ - -#define IN_GME 1 +// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ #include "Music_Emu.h" +#include "gme_types.h" #if !GME_DISABLE_STEREO_DEPTH #include "Effects_Buffer.h" #endif @@ -24,32 +23,51 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "blargg_source.h" -#ifndef GME_TYPE_LIST - -// Default list of all supported game music types (copy this to blargg_config.h -// if you want to modify it) -#define GME_TYPE_LIST \ - gme_ay_type,\ - gme_gbs_type,\ - gme_gym_type,\ - gme_hes_type,\ - gme_kss_type,\ - gme_nsf_type,\ - gme_nsfe_type,\ - gme_sap_type,\ - gme_spc_type,\ - gme_vgm_type,\ - gme_vgz_type - -#endif - -gme_type_t const* GMEAPI gme_type_list() +BLARGG_EXPORT gme_type_t const* gme_type_list() { - static gme_type_t const gme_type_list_ [] = { GME_TYPE_LIST, 0 }; + static gme_type_t const gme_type_list_ [] = { +#ifdef GME_TYPE_LIST + GME_TYPE_LIST, +#else + #ifdef USE_GME_AY + gme_ay_type, + #endif + #ifdef USE_GME_GBS + gme_gbs_type, + #endif + #ifdef USE_GME_GYM + gme_gym_type, + #endif + #ifdef USE_GME_HES + gme_hes_type, + #endif + #ifdef USE_GME_KSS + gme_kss_type, + #endif + #ifdef USE_GME_NSF + gme_nsf_type, + #endif + #ifdef USE_GME_NSFE + gme_nsfe_type, + #endif + #ifdef USE_GME_SAP + gme_sap_type, + #endif + #ifdef USE_GME_SPC + gme_spc_type, + #endif + #ifdef USE_GME_VGM + gme_vgm_type, + gme_vgz_type, + #endif +#endif + 0 + }; + return gme_type_list_; } -const char* GMEAPI gme_identify_header( void const* header ) +BLARGG_EXPORT const char* gme_identify_header( void const* header ) { switch ( get_be32( header ) ) { @@ -78,7 +96,7 @@ static void to_uppercase( const char* in, int len, char* out ) *out = 0; // extension too long } -gme_type_t GMEAPI gme_identify_extension( const char* extension_ ) +BLARGG_EXPORT gme_type_t gme_identify_extension( const char* extension_ ) { char const* end = strrchr( extension_, '.' ); if ( end ) @@ -93,7 +111,7 @@ gme_type_t GMEAPI gme_identify_extension( const char* extension_ ) return 0; } -gme_err_t GMEAPI gme_identify_file( const char* path, gme_type_t* type_out ) +BLARGG_EXPORT gme_err_t gme_identify_file( const char* path, gme_type_t* type_out ) { *type_out = gme_identify_extension( path ); // TODO: don't examine header if file has extension? @@ -108,7 +126,7 @@ gme_err_t GMEAPI gme_identify_file( const char* path, gme_type_t* type_out ) return 0; } -gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate ) +BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate ) { require( (data || !size) && out ); *out = 0; @@ -132,7 +150,7 @@ gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, in return err; } -GMEEXPORT gme_err_t GMEAPI gme_open_file( const char* path, Music_Emu** out, int sample_rate ) +BLARGG_EXPORT gme_err_t gme_open_file( const char* path, Music_Emu** out, int sample_rate ) { require( path && out ); *out = 0; @@ -169,7 +187,7 @@ GMEEXPORT gme_err_t GMEAPI gme_open_file( const char* path, Music_Emu** out, int return err; } -Music_Emu* GMEAPI gme_new_emu( gme_type_t type, int rate ) +BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t type, int rate ) { if ( type ) { @@ -202,27 +220,27 @@ Music_Emu* GMEAPI gme_new_emu( gme_type_t type, int rate ) return 0; } -gme_err_t GMEAPI gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); } +BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); } -gme_err_t GMEAPI gme_load_data( Music_Emu* me, void const* data, long size ) +BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu* me, void const* data, long size ) { Mem_File_Reader in( data, size ); return me->load( in ); } -gme_err_t GMEAPI gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data ) +BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data ) { Callback_Reader in( func, size, data ); return me->load( in ); } -void GMEAPI gme_delete( Music_Emu* me ) { delete me; } +BLARGG_EXPORT void gme_delete( Music_Emu* me ) { delete me; } -gme_type_t GMEAPI gme_type( Music_Emu const* me ) { return me->type(); } +BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* me ) { return me->type(); } -const char* GMEAPI gme_warning( Music_Emu* me ) { return me->warning(); } +BLARGG_EXPORT const char* gme_warning( Music_Emu* me ) { return me->warning(); } -int GMEAPI gme_track_count( Music_Emu const* me ) { return me->track_count(); } +BLARGG_EXPORT int gme_track_count( Music_Emu const* me ) { return me->track_count(); } struct gme_info_t_ : gme_info_t { @@ -231,7 +249,7 @@ struct gme_info_t_ : gme_info_t BLARGG_DISABLE_NOTHROW }; -gme_err_t GMEAPI gme_track_info( Music_Emu const* me, gme_info_t** out, int track ) +BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track ) { *out = NULL; @@ -297,12 +315,12 @@ gme_err_t GMEAPI gme_track_info( Music_Emu const* me, gme_info_t** out, int trac return 0; } -void GMEAPI gme_free_info( gme_info_t* info ) +BLARGG_EXPORT void gme_free_info( gme_info_t* info ) { delete STATIC_CAST(gme_info_t_*,info); } -void GMEAPI gme_set_stereo_depth( Music_Emu* me, double depth ) +BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu* me, double depth ) { #if !GME_DISABLE_STEREO_DEPTH if ( me->effects_buffer ) @@ -310,24 +328,26 @@ void GMEAPI gme_set_stereo_depth( Music_Emu* me, double depth ) #endif } -void* GMEAPI gme_user_data ( Music_Emu const* me ) { return me->user_data(); } -void GMEAPI gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); } -void GMEAPI gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); } +BLARGG_EXPORT void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); } +BLARGG_EXPORT void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); } +BLARGG_EXPORT void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); } -gme_err_t GMEAPI gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); } -gme_err_t GMEAPI gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); } -gme_err_t GMEAPI gme_skip ( Music_Emu* me, long n ) { return me->skip( n ); } -void GMEAPI gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); } -int GMEAPI gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); } -int GMEAPI gme_tell ( Music_Emu const* me ) { return me->tell(); } -gme_err_t GMEAPI gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); } -int GMEAPI gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); } -void GMEAPI gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); } -void GMEAPI gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); } -void GMEAPI gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); } -void GMEAPI gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); } +BLARGG_EXPORT gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); } +BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); } +BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); } +BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); } +BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); } +BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); } +BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); } +BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); } +BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); } +BLARGG_EXPORT void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); } +BLARGG_EXPORT void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); } +BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( enabled ); } +BLARGG_EXPORT void gme_clear_playlist ( Music_Emu* me ) { me->clear_playlist(); } +BLARGG_EXPORT int gme_type_multitrack( gme_type_t t ) { return t->track_count != 1; } -void GMEAPI gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) +BLARGG_EXPORT void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) { Music_Emu::equalizer_t e = me->equalizer(); e.treble = eq->treble; @@ -335,16 +355,22 @@ void GMEAPI gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) me->set_equalizer( e ); } -void GMEAPI gme_equalizer( Music_Emu const* me, gme_equalizer_t* out ) +BLARGG_EXPORT void gme_equalizer( Music_Emu const* me, gme_equalizer_t* out ) { - gme_equalizer_t e = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gme_equalizer_t e = gme_equalizer_t(); // Default-init all fields to 0.0f e.treble = me->equalizer().treble; e.bass = me->equalizer().bass; *out = e; } -const char* GMEAPI gme_voice_name( Music_Emu const* me, int i ) +BLARGG_EXPORT const char* gme_voice_name( Music_Emu const* me, int i ) { assert( (unsigned) i < (unsigned) me->voice_count() ); return me->voice_names() [i]; } + +BLARGG_EXPORT const char* gme_type_system( gme_type_t type ) +{ + assert( type ); + return type->system; +} diff --git a/game-music-emu/gme/gme.h b/game-music-emu/gme/gme.h index 5e9470d02..1f2a2d150 100644 --- a/game-music-emu/gme/gme.h +++ b/game-music-emu/gme/gme.h @@ -1,33 +1,15 @@ /* Game music emulator library C interface (also usable from C++) */ -/* Game_Music_Emu 0.5.2 */ +/* Game_Music_Emu 0.6.0 */ #ifndef GME_H #define GME_H -#ifdef _MSC_VER -#define GMEAPI __stdcall -#else -#define GMEAPI -#endif - -#if defined(_MSC_VER) && defined(GME_DLL) -#define GMEEXPORT __declspec(dllexport) -#define GMEIMPORT __declspec(dllimport) -#if IN_GME -#define GMEDLL GMEEXPORT -#else -#define GMEDLL GMEIMPORT -#endif -#else -#define GMEEXPORT -#define GMEIMPORT -#define GMEDLL -#endif - #ifdef __cplusplus extern "C" { #endif +#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */ + /* Error string returned by library functions, or NULL if no error (success) */ typedef const char* gme_err_t; @@ -38,38 +20,35 @@ typedef struct Music_Emu Music_Emu; /******** Basic operations ********/ /* Create emulator and load game music file/data into it. Sets *out to new emulator. */ -GMEDLL gme_err_t GMEAPI gme_open_file( const char path [], Music_Emu** out, int sample_rate ); +gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate ); /* Number of tracks available */ -GMEDLL int GMEAPI gme_track_count( Music_Emu const* ); +int gme_track_count( Music_Emu const* ); /* Start a track, where 0 is the first track */ -GMEDLL gme_err_t GMEAPI gme_start_track( Music_Emu*, int index ); +gme_err_t gme_start_track( Music_Emu*, int index ); /* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */ -GMEDLL gme_err_t GMEAPI gme_play( Music_Emu*, int count, short out [] ); - -/* Skip n samples */ -GMEDLL gme_err_t GMEAPI gme_skip( Music_Emu*, long n ); +gme_err_t gme_play( Music_Emu*, int count, short out [] ); /* Finish using emulator and free memory */ -GMEDLL void GMEAPI gme_delete( Music_Emu* ); +void gme_delete( Music_Emu* ); /******** Track position/length ********/ /* Set time to start fading track out. Once fade ends track_ended() returns true. Fade time can be changed while track is playing. */ -GMEDLL void GMEAPI gme_set_fade( Music_Emu*, int start_msec ); +void gme_set_fade( Music_Emu*, int start_msec ); /* True if a track has reached its end */ -GMEDLL int GMEAPI gme_track_ended( Music_Emu const* ); +int gme_track_ended( Music_Emu const* ); /* Number of milliseconds (1000 = one second) played since beginning of track */ -GMEDLL int GMEAPI gme_tell( Music_Emu const* ); +int gme_tell( Music_Emu const* ); /* Seek to new time in track. Seeking backwards or far forward can take a while. */ -GMEDLL gme_err_t GMEAPI gme_seek( Music_Emu*, int msec ); +gme_err_t gme_seek( Music_Emu*, int msec ); /******** Informational ********/ @@ -80,22 +59,22 @@ enum { gme_info_only = -1 }; /* Most recent warning string, or NULL if none. Clears current warning after returning. Warning is also cleared when loading a file and starting a track. */ -GMEDLL const char* GMEAPI gme_warning( Music_Emu* ); +const char* gme_warning( Music_Emu* ); /* Load m3u playlist file (must be done after loading music) */ -GMEDLL gme_err_t GMEAPI gme_load_m3u( Music_Emu*, const char path [] ); +gme_err_t gme_load_m3u( Music_Emu*, const char path [] ); /* Clear any loaded m3u playlist and any internal playlist that the music format supports (NSFE for example). */ -GMEDLL void GMEAPI gme_clear_playlist( Music_Emu* ); +void gme_clear_playlist( Music_Emu* ); /* Gets information for a particular track (length, name, author, etc.). Must be freed after use. */ typedef struct gme_info_t gme_info_t; -GMEDLL gme_err_t GMEAPI gme_track_info( Music_Emu const*, gme_info_t** out, int track ); +gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track ); /* Frees track information */ -GMEDLL void GMEAPI gme_free_info( gme_info_t* ); +void gme_free_info( gme_info_t* ); struct gme_info_t { @@ -127,30 +106,31 @@ struct gme_info_t /* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for GYM, SPC, and Sega Genesis VGM music */ -GMEDLL void GMEAPI gme_set_stereo_depth( Music_Emu*, double depth ); +void gme_set_stereo_depth( Music_Emu*, double depth ); /* Disable automatic end-of-track detection and skipping of silence at beginning if ignore is true */ -GMEDLL void GMEAPI gme_ignore_silence( Music_Emu*, int ignore ); +void gme_ignore_silence( Music_Emu*, int ignore ); /* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. Track length as returned by track_info() assumes a tempo of 1.0. */ -GMEDLL void GMEAPI gme_set_tempo( Music_Emu*, double tempo ); +void gme_set_tempo( Music_Emu*, double tempo ); /* Number of voices used by currently loaded file */ -GMEDLL int GMEAPI gme_voice_count( Music_Emu const* ); +int gme_voice_count( Music_Emu const* ); /* Name of voice i, from 0 to gme_voice_count() - 1 */ -GMEDLL const char* GMEAPI gme_voice_name( Music_Emu const*, int i ); +const char* gme_voice_name( Music_Emu const*, int i ); /* Mute/unmute voice i, where voice 0 is first voice */ -GMEDLL void GMEAPI gme_mute_voice( Music_Emu*, int index, int mute ); +void gme_mute_voice( Music_Emu*, int index, int mute ); /* Set muting state of all voices at once using a bit mask, where -1 mutes all voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */ -GMEDLL void GMEAPI gme_mute_voices( Music_Emu*, int muting_mask ); +void gme_mute_voices( Music_Emu*, int muting_mask ); /* Frequency equalizer parameters (see gme.txt) */ +/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */ typedef struct gme_equalizer_t { double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */ @@ -160,11 +140,13 @@ typedef struct gme_equalizer_t } gme_equalizer_t; /* Get current frequency equalizater parameters */ -GMEDLL void GMEAPI gme_equalizer( Music_Emu const*, gme_equalizer_t* out ); +void gme_equalizer( Music_Emu const*, gme_equalizer_t* out ); /* Change frequency equalizer parameters */ -GMEDLL void GMEAPI gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq ); +void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq ); +/* Enables/disables most accurate sound emulation options */ +void gme_enable_accuracy( Music_Emu*, int enabled ); /******** Game music types ********/ @@ -187,17 +169,17 @@ extern const gme_type_t gme_vgz_type; /* Type of this emulator */ -GMEDLL gme_type_t GMEAPI gme_type( Music_Emu const* ); +gme_type_t gme_type( Music_Emu const* ); /* Pointer to array of all music types, with NULL entry at end. Allows a player linked to this library to support new music types without having to be updated. */ -GMEDLL gme_type_t const* GMEAPI gme_type_list(); +gme_type_t const* gme_type_list(); /* Name of game system for this music file type */ -GMEDLL const char* GMEAPI gme_type_system( gme_type_t ); +const char* gme_type_system( gme_type_t ); /* True if this music file type supports multiple tracks */ -GMEDLL int GMEAPI gme_type_multitrack( gme_type_t ); +int gme_type_multitrack( gme_type_t ); /******** Advanced file loading ********/ @@ -206,50 +188,50 @@ GMEDLL int GMEAPI gme_type_multitrack( gme_type_t ); extern const char* const gme_wrong_file_type; /* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */ -GMEDLL gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate ); +gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate ); /* Determine likely game music type based on first four bytes of file. Returns string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if file header is not recognized. */ -GMEDLL const char* GMEAPI gme_identify_header( void const* header ); +const char* gme_identify_header( void const* header ); /* Get corresponding music type for file path or extension passed in. */ -GMEDLL gme_type_t GMEAPI gme_identify_extension( const char path_or_extension [] ); +gme_type_t gme_identify_extension( const char path_or_extension [] ); /* Determine file type based on file's extension or header (if extension isn't recognized). Sets *type_out to type, or 0 if unrecognized or error. */ -GMEDLL gme_err_t GMEAPI gme_identify_file( const char path [], gme_type_t* type_out ); +gme_err_t gme_identify_file( const char path [], gme_type_t* type_out ); /* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need track information, pass gme_info_only for sample_rate. */ -GMEDLL Music_Emu* GMEAPI gme_new_emu( gme_type_t, int sample_rate ); +Music_Emu* gme_new_emu( gme_type_t, int sample_rate ); /* Load music file into emulator */ -GMEDLL gme_err_t GMEAPI gme_load_file( Music_Emu*, const char path [] ); +gme_err_t gme_load_file( Music_Emu*, const char path [] ); /* Load music file from memory into emulator. Makes a copy of data passed. */ -GMEDLL gme_err_t GMEAPI gme_load_data( Music_Emu*, void const* data, long size ); +gme_err_t gme_load_data( Music_Emu*, void const* data, long size ); /* Load music file using custom data reader function that will be called to read file data. Most emulators load the entire file in one read call. */ -typedef gme_err_t (GMEAPI *gme_reader_t)( void* your_data, void* out, int count ); -GMEDLL gme_err_t GMEAPI gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data ); +typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count ); +gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data ); /* Load m3u playlist file from memory (must be done after loading music) */ -GMEDLL gme_err_t GMEAPI gme_load_m3u_data( Music_Emu*, void const* data, long size ); +gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size ); /******** User data ********/ /* Set/get pointer to data you want to associate with this emulator. You can use this for whatever you want. */ -GMEDLL void GMEAPI gme_set_user_data( Music_Emu*, void* new_user_data ); -GMEDLL void* GMEAPI gme_user_data( Music_Emu const* ); +void gme_set_user_data( Music_Emu*, void* new_user_data ); +void* gme_user_data( Music_Emu const* ); /* Register cleanup function to be called when deleting emulator, or NULL to clear it. Passes user_data to cleanup function. */ -typedef void (GMEAPI *gme_user_cleanup_t)( void* user_data ); -GMEDLL void GMEAPI gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func ); +typedef void (*gme_user_cleanup_t)( void* user_data ); +void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func ); #ifdef __cplusplus diff --git a/game-music-emu/gme/gme_types.h b/game-music-emu/gme/gme_types.h new file mode 100644 index 000000000..06226f4aa --- /dev/null +++ b/game-music-emu/gme/gme_types.h @@ -0,0 +1,21 @@ +#ifndef GME_TYPES_H +#define GME_TYPES_H + +/* + * This is a default gme_types.h for use when *not* using + * CMake. If CMake is in use gme_types.h.in will be + * processed instead. + */ +#define USE_GME_AY +#define USE_GME_GBS +#define USE_GME_GYM +#define USE_GME_HES +#define USE_GME_KSS +#define USE_GME_NSF +#define USE_GME_NSFE +#define USE_GME_SAP +#define USE_GME_SPC +/* VGM and VGZ are a package deal */ +#define USE_GME_VGM + +#endif /* GME_TYPES_H */ diff --git a/game-music-emu/gme/gme_types.h.in b/game-music-emu/gme/gme_types.h.in new file mode 100644 index 000000000..4829b3e16 --- /dev/null +++ b/game-music-emu/gme/gme_types.h.in @@ -0,0 +1,23 @@ +#ifndef GME_TYPES_H +#define GME_TYPES_H + +/* CMake will either define the following to 1, or #undef it, + * depending on the options passed to CMake. This is used to + * conditionally compile in the various emulator types. + * + * See gme_type_list() in gme.cpp + */ + +#cmakedefine USE_GME_AY +#cmakedefine USE_GME_GBS +#cmakedefine USE_GME_GYM +#cmakedefine USE_GME_HES +#cmakedefine USE_GME_KSS +#cmakedefine USE_GME_NSF +#cmakedefine USE_GME_NSFE +#cmakedefine USE_GME_SAP +#cmakedefine USE_GME_SPC +/* VGM and VGZ are a package deal */ +#cmakedefine USE_GME_VGM + +#endif /* GME_TYPES_H */ diff --git a/game-music-emu/gme/hes_cpu_io.h b/game-music-emu/gme/hes_cpu_io.h index b3d71dad4..ce60ce8ef 100644 --- a/game-music-emu/gme/hes_cpu_io.h +++ b/game-music-emu/gme/hes_cpu_io.h @@ -44,7 +44,7 @@ inline byte const* Hes_Emu::cpu_set_mmr( int page, int bank ) default: if ( bank != 0xFF ) - dprintf( "Unmapped bank $%02X\n", bank ); + debug_printf( "Unmapped bank $%02X\n", bank ); return rom.unmapped(); } diff --git a/game-music-emu/gme/nes_cpu_io.h b/game-music-emu/gme/nes_cpu_io.h index 4bae37931..68ce9b6ff 100644 --- a/game-music-emu/gme/nes_cpu_io.h +++ b/game-music-emu/gme/nes_cpu_io.h @@ -34,7 +34,7 @@ int Nsf_Emu::cpu_read( nes_addr_t addr ) result = addr >> 8; // simulate open bus if ( addr != 0x2002 ) - dprintf( "Read unmapped $%.4X\n", (unsigned) addr ); + debug_printf( "Read unmapped $%.4X\n", (unsigned) addr ); exit: return result; diff --git a/game-music-emu/gme/sap_cpu_io.h b/game-music-emu/gme/sap_cpu_io.h index 8c2f6dd09..d009d0d9b 100644 --- a/game-music-emu/gme/sap_cpu_io.h +++ b/game-music-emu/gme/sap_cpu_io.h @@ -20,7 +20,7 @@ void Sap_Emu::cpu_write( sap_addr_t addr, int data ) int Sap_Emu::cpu_read( sap_addr_t addr ) { if ( (addr & 0xF900) == 0xD000 ) - dprintf( "Unmapped read $%04X\n", addr ); + debug_printf( "Unmapped read $%04X\n", addr ); return mem.ram [addr]; } #endif diff --git a/game-music-emu/readme.txt b/game-music-emu/readme.txt index e3470bfa1..b7451da9f 100644 --- a/game-music-emu/readme.txt +++ b/game-music-emu/readme.txt @@ -1,4 +1,4 @@ -Game_Music_Emu 0.5.2: Game Music Emulators +Game_Music_Emu 0.6.0: Game Music Emulators ------------------------------------------ Game_Music_Emu is a collection of video game music file emulators that support the following formats and systems: @@ -14,7 +14,7 @@ SPC Super Nintendo/Super Famicom VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro Features: -* Can be used in C and C++ code +* C interface for use in C, C++, and other compatible languages * High emphasis has been placed on making the library very easy to use * One set of common functions work with all emulators the same way * Several code examples, including music player using SDL @@ -42,8 +42,17 @@ License: GNU Lesser General Public License (LGPL) Getting Started --------------- Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and -all source files in gme/. Be sure "test.nsf" is in the same directory. -Running the program should generate the recording "out.wav". +all source files in gme/. If you have CMake 2.6 or later, execute + + run cmake + cd demo + run make + +Be sure "test.nsf" is in the same directory as the program. Running it +should generate the recording "out.wav". + +A slightly more extensive demo application is available in the player/ +directory. It requires SDL to build. Read gme.txt for more information. Post to the discussion forum for assistance. @@ -55,16 +64,17 @@ gme.txt General notes about the library changes.txt Changes made since previous releases design.txt Library design notes license.txt GNU Lesser General Public License +CMakeLists.txt CMake build rules test.nsf Test file for NSF emulator test.m3u Test m3u playlist for features.c demo demo/ basics.c Records NSF file to wave sound file - cpp_basics.cpp C++ version of basics.c features.c Demonstrates many additional features Wave_Writer.h WAVE sound file writer used for demo output Wave_Writer.cpp + CMakeLists.txt CMake build rules player/ Player using the SDL multimedia library player.cpp Simple music player with waveform display @@ -72,22 +82,13 @@ player/ Player using the SDL multimedia library Music_Player.h Audio_Scope.cpp Audio waveform scope Audio_Scope.h + CMakeLists.txt CMake build rules gme/ blargg_config.h Library configuration (modify this file as needed) - gme.h C interface (also usable in C++, and simpler too) + gme.h Library interface header file gme.cpp - - Gme_File.h File loading and track information - Music_Emu.h Track playback and adjustments - Data_Reader.h Custom data readers - - Effects_Buffer.h Sound buffer with stereo echo and panning - Effects_Buffer.cpp - - M3u_Playlist.h M3U playlist support - M3u_Playlist.cpp Ay_Emu.h ZX Spectrum AY emulator Ay_Emu.cpp @@ -113,7 +114,7 @@ gme/ Hes_Cpu.h hes_cpu_io.h Hes_Emu.cpp - + Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator Kss_Emu.cpp Kss_Cpu.cpp @@ -180,26 +181,36 @@ gme/ Dual_Resampler.h Fir_Resampler.cpp Fir_Resampler.h - + + M3u_Playlist.h M3U playlist support + M3u_Playlist.cpp + + Effects_Buffer.h Sound buffer with stereo echo and panning + Effects_Buffer.cpp + blargg_common.h Common files needed by all emulators blargg_endian.h blargg_source.h Blip_Buffer.cpp Blip_Buffer.h + Gme_File.h Gme_File.cpp + Music_Emu.h Music_Emu.cpp Classic_Emu.h Classic_Emu.cpp Multi_Buffer.h Multi_Buffer.cpp + Data_Reader.h Data_Reader.cpp + + CMakeLists.txt CMake build rules Legal ----- -Game_Music_Emu library copyright (C) 2003-2006 Shay Green. -SNES SPC DSP emulator based on OpenSPC, copyright (C) 2002 Brad Martin. +Game_Music_Emu library copyright (C) 2003-2009 Shay Green. Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville. --- +-- Shay Green From 43fe317dbe81545685807423784e945bc1ae2a74 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 16:28:29 -0500 Subject: [PATCH 146/311] Use flexible array members for structs that end with var-sized arrays - Since Clang++, G++, and VC++ all support this extension (even though it's technically officially only part of C99), use it. It lets Clang's array- bounds checker know that these are meant to be accessed out of their so-called "bounds". --- src/r_plane.cpp | 4 ++-- src/r_plane.h | 2 +- src/stringtable.cpp | 6 +++--- src/textures/textures.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 143b302e9..6572c1f0b 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -558,8 +558,8 @@ static visplane_t *new_visplane (unsigned hash) if (check == NULL) { - check = (visplane_t *)M_Malloc (sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); - memset(check, 0, sizeof(*check) + sizeof(*check->top)*(MAXWIDTH*2)); + check = (visplane_t *)M_Malloc (sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH*2)); + memset(check, 0, sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH*2)); check->bottom = check->top + MAXWIDTH+2; } else if (NULL == (freetail = freetail->next)) diff --git a/src/r_plane.h b/src/r_plane.h index 7ad711bcc..231fa3ad4 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -63,7 +63,7 @@ struct visplane_s unsigned short *bottom; // [RH] bottom and top arrays are dynamically unsigned short pad; // allocated immediately after the - unsigned short top[3]; // visplane. + unsigned short top[]; // visplane. }; typedef struct visplane_s visplane_t; diff --git a/src/stringtable.cpp b/src/stringtable.cpp index f575dca17..47cf00fae 100644 --- a/src/stringtable.cpp +++ b/src/stringtable.cpp @@ -55,7 +55,7 @@ struct FStringTable::StringEntry StringEntry *Next; char *Name; BYTE PassNum; - char String[2]; + char String[]; }; FStringTable::FStringTable () @@ -283,7 +283,7 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p } if (entry == NULL || cmpval > 0) { - entry = (StringEntry *)M_Malloc (sizeof(*entry) + strText.Len() + strName.Len()); + entry = (StringEntry *)M_Malloc (sizeof(*entry) + strText.Len() + strName.Len() + 2); entry->Next = *pentry; *pentry = entry; strcpy (entry->String, strText.GetChars()); @@ -409,7 +409,7 @@ void FStringTable::SetString (const char *name, const char *newString) size_t namelen = strlen (name); // Create a new string entry - StringEntry *entry = (StringEntry *)M_Malloc (sizeof(*entry) + newlen + namelen); + StringEntry *entry = (StringEntry *)M_Malloc (sizeof(*entry) + newlen + namelen + 2); strcpy (entry->String, newString); strcpy (entry->Name = entry->String + newlen + 1, name); entry->PassNum = 0; diff --git a/src/textures/textures.h b/src/textures/textures.h index 837c62689..da5f559ae 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -119,7 +119,7 @@ struct patch_t SWORD height; SWORD leftoffset; // pixels to the left of origin SWORD topoffset; // pixels below the origin - DWORD columnofs[8]; // only [width] used + DWORD columnofs[]; // only [width] used // the [0] is &columnofs[width] }; From fc97584c696ac4b7ab988b978f9fa5798ad21a5d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 16:50:20 -0500 Subject: [PATCH 147/311] Disable warning C4200 on VC++ - This warning is about using zero-sized arrays in structs (aka flexible member arrays). It's standard-enough for our purposes, so don't warn about it, since neither GCC nor Clang do. --- src/doomtype.h | 4 ++++ src/textures/textures.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 31f96d2ab..d201ca71d 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -34,6 +34,10 @@ // source files, so we can't use it. So define PATH_MAX to be what MAX_PATH // currently is: #define PATH_MAX 260 + +// Disable warning about using unsized arrays in structs. It supports it just +// fine, and so do Clang and GCC, but the latter two don't warn about it. +#pragma warning(disable:4200) #endif #include diff --git a/src/textures/textures.h b/src/textures/textures.h index da5f559ae..2992d8a46 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -107,8 +107,6 @@ struct FDoorAnimation FName CloseSound; }; - - // Patches. // A patch holds one or more columns. // Patches are used for sprites and all masked pictures, and we compose From 138e7ff749281ee33960a16b34163db4783f4919 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 17:16:40 -0500 Subject: [PATCH 148/311] Redo GME warning-silencing that was undone by commit fbddfbe57 --- game-music-emu/gme/Ay_Apu.cpp | 2 +- game-music-emu/gme/Ay_Cpu.cpp | 8 +++---- game-music-emu/gme/Ay_Emu.cpp | 6 ++--- game-music-emu/gme/Data_Reader.cpp | 8 ++++--- game-music-emu/gme/Dual_Resampler.cpp | 4 ++-- game-music-emu/gme/Fir_Resampler.cpp | 4 ++-- game-music-emu/gme/Fir_Resampler.h | 10 ++++----- game-music-emu/gme/Gb_Cpu.cpp | 8 ++++++- game-music-emu/gme/Gme_File.cpp | 4 ++-- game-music-emu/gme/Hes_Apu.cpp | 4 ++-- game-music-emu/gme/Kss_Cpu.cpp | 8 +++---- game-music-emu/gme/M3u_Playlist.cpp | 2 +- game-music-emu/gme/M3u_Playlist.h | 2 +- game-music-emu/gme/Multi_Buffer.cpp | 12 +++++----- game-music-emu/gme/Music_Emu.cpp | 2 +- game-music-emu/gme/Nsfe_Emu.cpp | 8 ++++--- game-music-emu/gme/Sap_Apu.cpp | 2 +- game-music-emu/gme/Sap_Emu.cpp | 8 +++---- game-music-emu/gme/Sms_Apu.cpp | 2 +- game-music-emu/gme/Snes_Spc.cpp | 2 +- game-music-emu/gme/Spc_Cpu.h | 8 +++---- game-music-emu/gme/Spc_Dsp.cpp | 2 +- game-music-emu/gme/Spc_Dsp.h | 2 +- game-music-emu/gme/Spc_Emu.cpp | 4 ++-- game-music-emu/gme/Vgm_Emu.cpp | 6 ++--- game-music-emu/gme/Ym2612_Emu.cpp | 32 +++++++++++++-------------- game-music-emu/gme/gme.cpp | 2 +- 27 files changed, 86 insertions(+), 76 deletions(-) diff --git a/game-music-emu/gme/Ay_Apu.cpp b/game-music-emu/gme/Ay_Apu.cpp index c1405231d..d58d839fe 100644 --- a/game-music-emu/gme/Ay_Apu.cpp +++ b/game-music-emu/gme/Ay_Apu.cpp @@ -299,7 +299,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time ) while ( ntime <= end ) // must advance *past* time to avoid hang { int changed = noise_lfsr + 1; - noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1); + noise_lfsr = ((blargg_ulong)-(blargg_long)(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1); if ( changed & 2 ) { delta = -delta; diff --git a/game-music-emu/gme/Ay_Cpu.cpp b/game-music-emu/gme/Ay_Cpu.cpp index 825320d08..cdc3947f6 100644 --- a/game-music-emu/gme/Ay_Cpu.cpp +++ b/game-music-emu/gme/Ay_Cpu.cpp @@ -469,7 +469,7 @@ possibly_out_of_time: add_hl_data: { blargg_ulong sum = rp.hl + data; data ^= rp.hl; - rp.hl = sum; + rp.hl = (uint16_t)sum; flags = (flags & (S80 | Z40 | V04)) | (sum >> 16) | (sum >> 8 & (F20 | F08)) | @@ -719,7 +719,7 @@ possibly_out_of_time: flags = (flags & (S80 | Z40 | P04)) | (temp & (F20 | F08)) | (temp >> 8); - rg.a = temp; + rg.a = (uint8_t)temp; goto loop; } @@ -1048,7 +1048,7 @@ possibly_out_of_time: blargg_ulong sum = temp + (flags & C01); flags = ~data >> 2 & N02; if ( flags ) - sum = -sum; + sum = (blargg_ulong)-(blargg_long)sum; sum += rp.hl; temp ^= rp.hl; temp ^= sum; @@ -1056,7 +1056,7 @@ possibly_out_of_time: (temp >> 8 & H10) | (sum >> 8 & (S80 | F20 | F08)) | ((temp - -0x8000) >> 14 & V04); - rp.hl = sum; + rp.hl = (uint16_t)sum; if ( (uint16_t) sum ) goto loop; flags |= Z40; diff --git a/game-music-emu/gme/Ay_Emu.cpp b/game-music-emu/gme/Ay_Emu.cpp index 43670d1bd..565559441 100644 --- a/game-music-emu/gme/Ay_Emu.cpp +++ b/game-music-emu/gme/Ay_Emu.cpp @@ -47,8 +47,8 @@ Ay_Emu::~Ay_Emu() { } static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size ) { - long pos = ptr - (byte const*) file.header; - long file_size = file.end - (byte const*) file.header; + long pos = long(ptr - (byte const*) file.header); + long file_size = long(file.end - (byte const*) file.header); assert( (unsigned long) pos <= (unsigned long) file_size - 2 ); int offset = (BOOST::int16_t) get_be16( ptr ); if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) ) @@ -207,7 +207,7 @@ blargg_err_t Ay_Emu::start_track_( int track ) if ( len > blargg_ulong (file.end - in) ) { set_warning( "Missing file data" ); - len = file.end - in; + len = unsigned(file.end - in); } //debug_printf( "addr: $%04X, len: $%04X\n", addr, len ); if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data diff --git a/game-music-emu/gme/Data_Reader.cpp b/game-music-emu/gme/Data_Reader.cpp index 5bbfbf551..67fc8aefd 100644 --- a/game-music-emu/gme/Data_Reader.cpp +++ b/game-music-emu/gme/Data_Reader.cpp @@ -1,5 +1,7 @@ // File_Extractor 0.4.0. http://www.slack.net/~ant/ +#define _CRT_SECURE_NO_WARNINGS + #include "Data_Reader.h" #include "blargg_endian.h" @@ -89,11 +91,11 @@ Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r ) in = r; } -long Remaining_Reader::remain() const { return header_end - header + in->remain(); } +long Remaining_Reader::remain() const { return long(header_end - header + in->remain()); } long Remaining_Reader::read_first( void* out, long count ) { - long first = header_end - header; + long first = long(header_end - header); if ( first ) { if ( first > count ) @@ -210,7 +212,7 @@ long Std_File_Reader::size() const long Std_File_Reader::read_avail( void* p, long s ) { - return fread( p, 1, s, (FILE*) file_ ); + return (long)fread( p, 1, s, (FILE*) file_ ); } blargg_err_t Std_File_Reader::read( void* p, long s ) diff --git a/game-music-emu/gme/Dual_Resampler.cpp b/game-music-emu/gme/Dual_Resampler.cpp index 1c2cc36e2..149f6d6af 100644 --- a/game-music-emu/gme/Dual_Resampler.cpp +++ b/game-music-emu/gme/Dual_Resampler.cpp @@ -127,8 +127,8 @@ void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out ) r = 0x7FFF - (r >> 24); in += 2; - out [0] = l; - out [1] = r; + out [0] = (dsample_t)l; + out [1] = (dsample_t)r; out += 2; } diff --git a/game-music-emu/gme/Fir_Resampler.cpp b/game-music-emu/gme/Fir_Resampler.cpp index 7a6600be8..fa426c78c 100644 --- a/game-music-emu/gme/Fir_Resampler.cpp +++ b/game-music-emu/gme/Fir_Resampler.cpp @@ -186,8 +186,8 @@ int Fir_Resampler_::avail_( blargg_long input_count ) const int Fir_Resampler_::skip_input( long count ) { - int remain = write_pos - buf.begin(); - int max_count = remain - width_ * stereo; + int remain = int(write_pos - buf.begin()); + int max_count = int(remain - width_ * stereo); if ( count > max_count ) count = max_count; diff --git a/game-music-emu/gme/Fir_Resampler.h b/game-music-emu/gme/Fir_Resampler.h index a1bb67781..6cd1c218d 100644 --- a/game-music-emu/gme/Fir_Resampler.h +++ b/game-music-emu/gme/Fir_Resampler.h @@ -31,7 +31,7 @@ public: void clear(); // Number of input samples that can be written - int max_write() const { return buf.end() - write_pos; } + int max_write() const { return int(buf.end() - write_pos); } // Pointer to place to write input samples sample_t* buffer() { return write_pos; } @@ -40,7 +40,7 @@ public: void write( long count ); // Number of input samples in buffer - int written() const { return write_pos - &buf [write_offset]; } + int written() const { return int(write_pos - &buf [write_offset]); } // Skip 'count' input samples. Returns number of samples actually skipped. int skip_input( long count ); @@ -51,7 +51,7 @@ public: int input_needed( blargg_long count ) const; // Number of output samples available - int avail() const { return avail_( write_pos - &buf [width_ * stereo] ); } + int avail() const { return avail_( blargg_long(write_pos - &buf [width_ * stereo] )); } public: ~Fir_Resampler_(); @@ -161,11 +161,11 @@ int Fir_Resampler::read( sample_t* out_begin, blargg_long count ) imp_phase = res - remain; - int left = write_pos - in; + int left = int(write_pos - in); write_pos = &buf [left]; memmove( buf.begin(), in, left * sizeof *in ); - return out - out_begin; + return int(out - out_begin); } #endif diff --git a/game-music-emu/gme/Gb_Cpu.cpp b/game-music-emu/gme/Gb_Cpu.cpp index b0128ea4c..bfae186e9 100644 --- a/game-music-emu/gme/Gb_Cpu.cpp +++ b/game-music-emu/gme/Gb_Cpu.cpp @@ -89,6 +89,12 @@ unsigned const n_flag = 0x40; unsigned const h_flag = 0x20; unsigned const c_flag = 0x10; +#ifdef _MSC_VER +// warning C4101: 'blargg_failed_' : unreferenced local variable +// -- produced by the BOOST_STATIC_ASSERT line below +#pragma warning(disable:4101) +#endif + bool Gb_Cpu::run( blargg_long cycle_count ) { state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr; @@ -711,7 +717,7 @@ loop: temp += prev; flags &= z_flag; add_16_hl: - rp.hl = temp; + rp.hl = (uint16_t)temp; add_16_comm: flags |= (temp >> 12) & c_flag; flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag; diff --git a/game-music-emu/gme/Gme_File.cpp b/game-music-emu/gme/Gme_File.cpp index 995f56b1c..912a9adc1 100644 --- a/game-music-emu/gme/Gme_File.cpp +++ b/game-music-emu/gme/Gme_File.cpp @@ -60,8 +60,8 @@ blargg_err_t Gme_File::load_mem_( byte const* data, long size ) blargg_err_t Gme_File::load_( Data_Reader& in ) { RETURN_ERR( file_data.resize( in.remain() ) ); - RETURN_ERR( in.read( file_data.begin(), file_data.size() ) ); - return load_mem_( file_data.begin(), file_data.size() ); + RETURN_ERR( in.read( file_data.begin(), (long)file_data.size() ) ); + return load_mem_( file_data.begin(), (long)file_data.size() ); } // public load functions call this at beginning diff --git a/game-music-emu/gme/Hes_Apu.cpp b/game-music-emu/gme/Hes_Apu.cpp index 9c7f515d6..56b59dd77 100644 --- a/game-music-emu/gme/Hes_Apu.cpp +++ b/game-music-emu/gme/Hes_Apu.cpp @@ -106,10 +106,10 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time ) unsigned noise_lfsr = this->noise_lfsr; do { - int new_dac = 0x1F & -(noise_lfsr >> 1 & 1); + int new_dac = 0x1F & (unsigned)-(int)(noise_lfsr >> 1 & 1); // Implemented using "Galios configuration" // TODO: find correct LFSR algorithm - noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1)); + noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & (unsigned)-(int)(noise_lfsr & 1)); //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1)); int delta = new_dac - dac; if ( delta ) diff --git a/game-music-emu/gme/Kss_Cpu.cpp b/game-music-emu/gme/Kss_Cpu.cpp index a2068efc4..74230bf71 100644 --- a/game-music-emu/gme/Kss_Cpu.cpp +++ b/game-music-emu/gme/Kss_Cpu.cpp @@ -503,7 +503,7 @@ possibly_out_of_time: add_hl_data: { blargg_ulong sum = rp.hl + data; data ^= rp.hl; - rp.hl = sum; + rp.hl = (uint16_t)sum; flags = (flags & (S80 | Z40 | V04)) | (sum >> 16) | (sum >> 8 & (F20 | F08)) | @@ -753,7 +753,7 @@ possibly_out_of_time: flags = (flags & (S80 | Z40 | P04)) | (temp & (F20 | F08)) | (temp >> 8); - rg.a = temp; + rg.a = (uint8_t)temp; goto loop; } @@ -1085,7 +1085,7 @@ possibly_out_of_time: blargg_ulong sum = temp + (flags & C01); flags = ~data >> 2 & N02; if ( flags ) - sum = -sum; + sum = (blargg_ulong)-(blargg_long)sum; sum += rp.hl; temp ^= rp.hl; temp ^= sum; @@ -1093,7 +1093,7 @@ possibly_out_of_time: (temp >> 8 & H10) | (sum >> 8 & (S80 | F20 | F08)) | ((temp - -0x8000) >> 14 & V04); - rp.hl = sum; + rp.hl = (uint16_t)sum; if ( (uint16_t) sum ) goto loop; flags |= Z40; diff --git a/game-music-emu/gme/M3u_Playlist.cpp b/game-music-emu/gme/M3u_Playlist.cpp index bbe52b1a7..ffd7d82c3 100644 --- a/game-music-emu/gme/M3u_Playlist.cpp +++ b/game-music-emu/gme/M3u_Playlist.cpp @@ -407,7 +407,7 @@ blargg_err_t M3u_Playlist::parse() blargg_err_t M3u_Playlist::load( Data_Reader& in ) { RETURN_ERR( data.resize( in.remain() + 1 ) ); - RETURN_ERR( in.read( data.begin(), data.size() - 1 ) ); + RETURN_ERR( in.read( data.begin(), long(data.size() - 1) ) ); return parse(); } diff --git a/game-music-emu/gme/M3u_Playlist.h b/game-music-emu/gme/M3u_Playlist.h index e764cb936..fe90dd9f8 100644 --- a/game-music-emu/gme/M3u_Playlist.h +++ b/game-music-emu/gme/M3u_Playlist.h @@ -43,7 +43,7 @@ public: int repeat; // count }; entry_t const& operator [] ( int i ) const { return entries [i]; } - int size() const { return entries.size(); } + int size() const { return int(entries.size()); } void clear(); diff --git a/game-music-emu/gme/Multi_Buffer.cpp b/game-music-emu/gme/Multi_Buffer.cpp index 57f93b317..b86142f63 100644 --- a/game-music-emu/gme/Multi_Buffer.cpp +++ b/game-music-emu/gme/Multi_Buffer.cpp @@ -171,8 +171,8 @@ void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count ) BLIP_READER_NEXT( left, bass ); BLIP_READER_NEXT( right, bass ); - out [0] = l; - out [1] = r; + out [0] = (blip_sample_t)l; + out [1] = (blip_sample_t)r; out += 2; } @@ -201,8 +201,8 @@ void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count BLIP_READER_NEXT( left, bass ); BLIP_READER_NEXT( right, bass ); - out [0] = l; - out [1] = r; + out [0] = (blip_sample_t)l; + out [1] = (blip_sample_t)r; out += 2; } @@ -223,8 +223,8 @@ void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count ) s = 0x7FFF - (s >> 24); BLIP_READER_NEXT( center, bass ); - out [0] = s; - out [1] = s; + out [0] = (blip_sample_t)s; + out [1] = (blip_sample_t)s; out += 2; } diff --git a/game-music-emu/gme/Music_Emu.cpp b/game-music-emu/gme/Music_Emu.cpp index 30b25dcfc..d0dbe77a8 100644 --- a/game-music-emu/gme/Music_Emu.cpp +++ b/game-music-emu/gme/Music_Emu.cpp @@ -348,7 +348,7 @@ blargg_err_t Music_Emu::play( long out_count, sample_t* out ) { // during a run of silence, run emulator at >=2x speed so it gets ahead long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time; - while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) ) + while ( emu_time < ahead_time && !(buf_remain || emu_track_ended_) ) fill_buf(); // fill with silence diff --git a/game-music-emu/gme/Nsfe_Emu.cpp b/game-music-emu/gme/Nsfe_Emu.cpp index 824a1a240..5559bca9b 100644 --- a/game-music-emu/gme/Nsfe_Emu.cpp +++ b/game-music-emu/gme/Nsfe_Emu.cpp @@ -1,5 +1,7 @@ // Game_Music_Emu 0.6.0. http://www.slack.net/~ant/ +#define _CRT_SECURE_NO_WARNINGS + #include "Nsfe_Emu.h" #include "blargg_endian.h" @@ -35,7 +37,7 @@ inline void Nsfe_Info::unload() void Nsfe_Info::disable_playlist( bool b ) { playlist_disabled = b; - info.track_count = playlist.size(); + info.track_count = (byte)playlist.size(); if ( !info.track_count || playlist_disabled ) info.track_count = actual_track_count_; } @@ -171,7 +173,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu ) blargg_vector chars; blargg_vector strs; RETURN_ERR( read_strs( in, size, chars, strs ) ); - int n = strs.size(); + int n = (int)strs.size(); if ( n > 3 ) copy_str( strs [3], info.dumper, sizeof info.dumper ); @@ -190,7 +192,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu ) case BLARGG_4CHAR('e','m','i','t'): RETURN_ERR( track_times.resize( size / 4 ) ); - RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) ); + RETURN_ERR( in.read( track_times.begin(), (long)track_times.size() * 4 ) ); break; case BLARGG_4CHAR('l','b','l','t'): diff --git a/game-music-emu/gme/Sap_Apu.cpp b/game-music-emu/gme/Sap_Apu.cpp index ecac3dafd..daf72ed4a 100644 --- a/game-music-emu/gme/Sap_Apu.cpp +++ b/game-music-emu/gme/Sap_Apu.cpp @@ -30,7 +30,7 @@ static void gen_poly( blargg_ulong mask, int count, byte* out ) { // implemented using "Galios configuration" bits |= (n & 1) << b; - n = (n >> 1) ^ (mask & -(n & 1)); + n = (n >> 1) ^ (mask & (blargg_ulong)-(blargg_long)(n & 1)); } while ( b++ < 7 ); *out++ = bits; diff --git a/game-music-emu/gme/Sap_Emu.cpp b/game-music-emu/gme/Sap_Emu.cpp index cb52714f9..31bce6a90 100644 --- a/game-music-emu/gme/Sap_Emu.cpp +++ b/game-music-emu/gme/Sap_Emu.cpp @@ -119,7 +119,7 @@ static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out char const* tag = (char const*) in; while ( in < line_end && *in > ' ' ) in++; - int tag_len = (char const*) in - tag; + int tag_len = int((char const*) in - tag); while ( in < line_end && *in <= ' ' ) in++; @@ -256,7 +256,7 @@ blargg_err_t Sap_Emu::load_mem_( byte const* in, long size ) set_warning( info.warning ); set_track_count( info.track_count ); - set_voice_count( Sap_Apu::osc_count << info.stereo ); + set_voice_count( Sap_Apu::osc_count << (int)info.stereo ); apu_impl.volume( gain() ); return setup_buffer( 1773447 ); @@ -315,8 +315,8 @@ inline void Sap_Emu::call_init( int track ) case 'C': r.a = 0x70; - r.x = info.music_addr&0xFF; - r.y = info.music_addr >> 8; + r.x = (BOOST::uint8_t)(info.music_addr&0xFF); + r.y = (BOOST::uint8_t)(info.music_addr >> 8); run_routine( info.play_addr + 3 ); r.a = 0; r.x = track; diff --git a/game-music-emu/gme/Sms_Apu.cpp b/game-music-emu/gme/Sms_Apu.cpp index b41fdec41..be226f8f9 100644 --- a/game-music-emu/gme/Sms_Apu.cpp +++ b/game-music-emu/gme/Sms_Apu.cpp @@ -141,7 +141,7 @@ void Sms_Noise::run( blip_time_t time, blip_time_t end_time ) do { int changed = shifter + 1; - shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1); + shifter = (feedback & (unsigned)-(signed)(shifter & 1)) ^ (shifter >> 1); if ( changed & 2 ) // true if bits 0 and 1 differ { delta = -delta; diff --git a/game-music-emu/gme/Snes_Spc.cpp b/game-music-emu/gme/Snes_Spc.cpp index de5585ffc..26574223d 100644 --- a/game-music-emu/gme/Snes_Spc.cpp +++ b/game-music-emu/gme/Snes_Spc.cpp @@ -303,7 +303,7 @@ void Snes_Spc::set_output( sample_t* out, int size ) assert( out <= out_end ); } - dsp.set_output( out, out_end - out ); + dsp.set_output( out, int(out_end - out) ); } else { diff --git a/game-music-emu/gme/Spc_Cpu.h b/game-music-emu/gme/Spc_Cpu.h index 4742e0990..0ce7af7de 100644 --- a/game-music-emu/gme/Spc_Cpu.h +++ b/game-music-emu/gme/Spc_Cpu.h @@ -69,7 +69,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define READ_PROG16( addr ) GET_LE16( ram + (addr) ) #define SET_PC( n ) (pc = ram + (n)) -#define GET_PC() (pc - ram) +#define GET_PC() (int(pc - ram)) #define READ_PC( pc ) (*(pc)) #define READ_PC16( pc ) GET_LE16( pc ) @@ -77,7 +77,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define SPC_NO_SP_WRAPAROUND 0 #define SET_SP( v ) (sp = ram + 0x101 + (v)) -#define GET_SP() (sp - 0x101 - ram) +#define GET_SP() (int(sp - 0x101 - ram)) #if SPC_NO_SP_WRAPAROUND #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v )) @@ -87,7 +87,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #else #define PUSH16( data )\ {\ - int addr = (sp -= 2) - ram;\ + int addr = int((sp -= 2) - ram);\ if ( addr > 0x100 )\ {\ SET_LE16( sp, data );\ @@ -256,7 +256,7 @@ loop: } #else { - int addr = sp - ram; + int addr = int(sp - ram); SET_PC( GET_LE16( sp ) ); sp += 2; if ( addr < 0x1FF ) diff --git a/game-music-emu/gme/Spc_Dsp.cpp b/game-music-emu/gme/Spc_Dsp.cpp index 0a84bfe16..ac0baed6b 100644 --- a/game-music-emu/gme/Spc_Dsp.cpp +++ b/game-music-emu/gme/Spc_Dsp.cpp @@ -155,7 +155,7 @@ inline void Spc_Dsp::init_counter() // counters start out with this synchronization m.counters [0] = 1; m.counters [1] = 0; - m.counters [2] = -0x20u; + m.counters [2] = -0x20; m.counters [3] = 0x0B; int n = 2; diff --git a/game-music-emu/gme/Spc_Dsp.h b/game-music-emu/gme/Spc_Dsp.h index 401af020a..3cec1bd91 100644 --- a/game-music-emu/gme/Spc_Dsp.h +++ b/game-music-emu/gme/Spc_Dsp.h @@ -154,7 +154,7 @@ private: #include -inline int Spc_Dsp::sample_count() const { return m.out - m.out_begin; } +inline int Spc_Dsp::sample_count() const { return int(m.out - m.out_begin); } inline int Spc_Dsp::read( int addr ) const { diff --git a/game-music-emu/gme/Spc_Emu.cpp b/game-music-emu/gme/Spc_Emu.cpp index b3c20f317..341b53f9d 100644 --- a/game-music-emu/gme/Spc_Emu.cpp +++ b/game-music-emu/gme/Spc_Emu.cpp @@ -228,14 +228,14 @@ struct Spc_File : Gme_Info_ { RETURN_ERR( xid6.resize( xid6_size ) ); RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) ); - RETURN_ERR( in.read( xid6.begin(), xid6.size() ) ); + RETURN_ERR( in.read( xid6.begin(), (long)xid6.size() ) ); } return 0; } blargg_err_t track_info_( track_info_t* out, int ) const { - get_spc_info( header, xid6.begin(), xid6.size(), out ); + get_spc_info( header, xid6.begin(), (long)xid6.size(), out ); return 0; } }; diff --git a/game-music-emu/gme/Vgm_Emu.cpp b/game-music-emu/gme/Vgm_Emu.cpp index 5c6bc7cda..0f6001aae 100644 --- a/game-music-emu/gme/Vgm_Emu.cpp +++ b/game-music-emu/gme/Vgm_Emu.cpp @@ -57,7 +57,7 @@ static byte const* skip_gd3_str( byte const* in, byte const* end ) static byte const* get_gd3_str( byte const* in, byte const* end, char* field ) { byte const* mid = skip_gd3_str( in, end ); - int len = (mid - in) / 2 - 1; + int len = int(mid - in) / 2 - 1; if ( len > 0 ) { len = min( len, (int) Gme_File::max_field_ ); @@ -108,7 +108,7 @@ byte const* Vgm_Emu::gd3_data( int* size ) const return 0; byte const* gd3 = data + header_size + gd3_offset; - long gd3_size = check_gd3_header( gd3, data_end - gd3 ); + long gd3_size = check_gd3_header( gd3, long(data_end - gd3) ); if ( !gd3_size ) return 0; @@ -184,7 +184,7 @@ struct Vgm_File : Gme_Info_ if ( gd3_size ) { RETURN_ERR( gd3.resize( gd3_size ) ); - RETURN_ERR( in.read( gd3.begin(), gd3.size() ) ); + RETURN_ERR( in.read( gd3.begin(), (long)gd3.size() ) ); } } return 0; diff --git a/game-music-emu/gme/Ym2612_Emu.cpp b/game-music-emu/gme/Ym2612_Emu.cpp index 5ea5c9a24..4f9d84271 100644 --- a/game-music-emu/gme/Ym2612_Emu.cpp +++ b/game-music-emu/gme/Ym2612_Emu.cpp @@ -11,7 +11,7 @@ #include #include -/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */ +/* Copyright (C) 2002 Stephane Dallongeville (gens AT consolemul.com) */ /* Copyright (C) 2004-2006 Shay Green. This module is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -44,9 +44,9 @@ struct slot_t int MUL; // parametre "multiple de frequence" int TL; // Total Level = volume lorsque l'enveloppe est au plus haut int TLL; // Total Level ajusted - int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression + int SLL; // Sustin Level (ajusted) = volume oEl'enveloppe termine sa premiere phase de regression int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe - int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer + int KSR; // Key Scale Rate = cette valeur est calculee par rapport Ela frequence actuelle, elle va influer // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite ! int SEG; // Type enveloppe SSG int env_xor; @@ -58,24 +58,24 @@ struct slot_t const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR]) int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16]) int Finc; // frequency step = pas d'incrementation du compteur-frequence - // plus le pas est grand, plus la frequence est aïgu (ou haute) + // plus le pas est grand, plus la frequence est aEu (ou haute) int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ... // en fonction de la valeur de cette variable, on va appeler une fonction permettant - // de mettre à jour l'enveloppe courante. - int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe + // de mettre Ejour l'enveloppe courante. + int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir oEl'on se trouve dans l'enveloppe int Einc; // Envelope step courant int Ecmp; // Envelope counter limite pour la prochaine phase int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque - // cette valeur est egal à AR[KSR] + // cette valeur est egal EAR[KSR] int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression - // cette valeur est egal à DR[KSR] + // cette valeur est egal EDR[KSR] int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue - // cette valeur est egal à SR[KSR] + // cette valeur est egal ESR[KSR] int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement - // cette valeur est egal à RR[KSR] - int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree - // d'un autre ou carrement à la sortie de la voie + // cette valeur est egal ERR[KSR] + int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot El'entree + // d'un autre ou carrement Ela sortie de la voie int INd; // input data of the slot = donnees en entree du slot int ChgEnM; // Change envelop mask. int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO @@ -102,10 +102,10 @@ struct state_t { int TimerBase; // TimerBase calculation int Status; // YM2612 Status (timer overflow) - int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter + int TimerA; // timerA limit = valeur jusqu'Elaquelle le timer A doit compter int TimerAL; int TimerAcnt; // timerA counter = valeur courante du Timer A - int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter + int TimerB; // timerB limit = valeur jusqu'Elaquelle le timer B doit compter int TimerBL; int TimerBcnt; // timerB counter = valeur courante du Timer B int Mode; // Mode actuel des voie 3 et 6 (normal / special) @@ -1255,7 +1255,7 @@ void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out ) if ( YM2612.Mode & 3 ) run_timer( pair_count ); - // Mise à jour des pas des compteurs-frequences s'ils ont ete modifies + // Mise Ejour des pas des compteurs-frequences s'ils ont ete modifies for ( int chi = 0; chi < channel_count; chi++ ) { @@ -1277,7 +1277,7 @@ void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out ) int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL; if (sl.KSR != ksr) // si le KSR a change alors - { // les differents taux pour l'enveloppe sont mis à jour + { // les differents taux pour l'enveloppe sont mis Ejour sl.KSR = ksr; sl.EincA = sl.AR [ksr]; diff --git a/game-music-emu/gme/gme.cpp b/game-music-emu/gme/gme.cpp index c05f25eb4..990fee345 100644 --- a/game-music-emu/gme/gme.cpp +++ b/game-music-emu/gme/gme.cpp @@ -343,7 +343,7 @@ BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); } BLARGG_EXPORT void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); } BLARGG_EXPORT void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); } -BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( enabled ); } +BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( !!enabled ); } BLARGG_EXPORT void gme_clear_playlist ( Music_Emu* me ) { me->clear_playlist(); } BLARGG_EXPORT int gme_type_multitrack( gme_type_t t ) { return t->track_count != 1; } From 1d52d75fab2929dcaac4e75ebadbed253e410d40 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 17:23:18 -0500 Subject: [PATCH 149/311] Add new GME files to VC++ 2005 project --- game-music-emu/game-music-emu.vcproj | 272 ++++++++++++++------------- 1 file changed, 142 insertions(+), 130 deletions(-) diff --git a/game-music-emu/game-music-emu.vcproj b/game-music-emu/game-music-emu.vcproj index 00b05d5fd..8ded6444a 100644 --- a/game-music-emu/game-music-emu.vcproj +++ b/game-music-emu/game-music-emu.vcproj @@ -80,6 +80,69 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -703,6 +707,10 @@ RelativePath=".\gme\Gme_File.h" > + + @@ -823,6 +831,10 @@ RelativePath=".\gme\Spc_Emu.h" > + + From f429510cd1ca373f366422761800a55ce4490d8f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 17:26:59 -0500 Subject: [PATCH 150/311] We're building GME static, so don't do any DLL magic on Win32 --- game-music-emu/gme/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game-music-emu/gme/CMakeLists.txt b/game-music-emu/gme/CMakeLists.txt index 73a14befb..10544d721 100644 --- a/game-music-emu/gme/CMakeLists.txt +++ b/game-music-emu/gme/CMakeLists.txt @@ -134,7 +134,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gme_types.h.in # On some platforms we may need to change headers or whatnot based on whether # we're building the library or merely using the library. The following is # only defined when building the library to allow us to tell which is which. -add_definitions(-DBLARGG_BUILD_DLL) +#add_definitions(-DBLARGG_BUILD_DLL) # For the gme_types.h include_directories(${CMAKE_CURRENT_BINARY_DIR}) From 940794929c2a0d31a3bc8d82354e19ead8dee8df Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Apr 2014 17:51:15 -0500 Subject: [PATCH 151/311] Remove more VC++ warnings --- src/p_acs.cpp | 2 +- src/p_mobj.cpp | 2 +- src/x86.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index d8fdf13d2..4909a79d6 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -7893,7 +7893,7 @@ scriptwait: if (tag != 0) secnum = P_FindSectorFromTag (tag, -1); else - secnum = P_PointInSector (x, y) - sectors; + secnum = int(P_PointInSector (x, y) - sectors); if (secnum >= 0) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 75df3bb3e..eb214279d 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2138,7 +2138,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) fixed_t oldz = mo->z; fixed_t grav = mo->GetGravity(); -// +// // check for smooth step up // if (mo->player && mo->player->mo == mo && mo->z < mo->floorz) diff --git a/src/x86.cpp b/src/x86.cpp index e03b4795e..ec36aae93 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -57,7 +57,7 @@ void CheckCPUID(CPUInfo *cpu) #if defined(_M_IX86) || defined(__i386__) // Old 486s do not have CPUID, so we must test for its presence. // This code is adapted from the samples in AMD's document - // entitled "AMD-K6™ MMX Processor Multimedia Extensions." + // entitled "AMD-K6 MMX Processor Multimedia Extensions." #ifndef __GNUC__ __asm { From 878dcdc0a46315227ee1d558ead5dbc538f34e55 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 6 Apr 2014 12:56:51 +0300 Subject: [PATCH 152/311] Fix loading of lumps from directory on OS X Use POSIX-compliant opendir() / readdir() functions instead fts_open() / fts_read() Unlike Linux version, on OS X fts_read() inserts extra slash character between source directory and traversed entry paths --- src/resourcefiles/file_directory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resourcefiles/file_directory.cpp b/src/resourcefiles/file_directory.cpp index e9076ae9b..024ef0633 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -198,7 +198,7 @@ int FDirectory::AddDirectory(const char *dirpath) return count; } -#elif defined(__sun) +#elif defined(__sun) || defined(__APPLE__) int FDirectory::AddDirectory(const char *dirpath) { From ca93e04de37cb9f105c7c8d0106868013b403395 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 7 Apr 2014 23:23:55 +1200 Subject: [PATCH 153/311] Added GetActorPowerupTics ACS function --- src/p_acs.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4909a79d6..4cb34defa 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4260,6 +4260,7 @@ enum EACSFunctions ACSF_CheckFlag, ACSF_SetLineActivation, ACSF_GetLineActivation, + ACSF_GetActorPowerupTics, // ZDaemon ACSF_GetTeamScore = 19620, // (int team) @@ -5325,6 +5326,27 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) } break; + case ACSF_GetActorPowerupTics: + if (argCount >= 2) + { + const PClass *powerupclass = PClass::FindClass(FBehavior::StaticLookupString(args[1])); + if (powerupclass == NULL || !RUNTIME_CLASS(APowerup)->IsAncestorOf(powerupclass)) + { + Printf("'%s' is not a type of Powerup.\n", FBehavior::StaticLookupString(args[1])); + return 0; + } + + AActor *actor = SingleActorFromTID(args[0], activator); + if (actor != NULL) + { + APowerup* powerup = (APowerup*)actor->FindInventory(powerupclass); + if (powerup != NULL) + return powerup->EffectTics; + } + return 0; + } + break; + default: break; } From 580094a7924ea586bc0c789e55d51aa3dc3f2287 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Thu, 10 Apr 2014 12:32:23 +0200 Subject: [PATCH 154/311] More editing flags PSX-inspired flags to change the render styles of monsters (and other things). --- src/doomdata.h | 12 +++++++++++- src/namedef.h | 5 +++++ src/p_mobj.cpp | 22 ++++++++++++++++++++++ src/p_udmf.cpp | 35 +++++++++++++++++++++++++++++++++++ src/p_xlat.cpp | 3 +++ wadsrc/static/xlat/defines.i | 3 ++- wadsrc/static/xlat/strife.txt | 1 + 7 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index 55903170a..8ba831082 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -192,9 +192,10 @@ enum EMapLineFlags // These are flags that use different values internally ML_RESERVED_ETERNITY = 0x0800, // [RH] Extra flags for Strife - ML_TRANSLUCENT_STRIFE = 0x1000, ML_RAILING_STRIFE = 0x0200, ML_BLOCK_FLOATERS_STRIFE = 0x0400, + ML_TRANSPARENT_STRIFE = 0x0800, + ML_TRANSLUCENT_STRIFE = 0x1000, }; @@ -385,6 +386,15 @@ enum EMapThingFlags MTF_SECRET = 0x080000, // Secret pickup MTF_NOINFIGHTING = 0x100000, + + // PSX Doom and Doom 64 effects + + MTF_TRANS = 0x200000, // 50% alpha + MTF_ADD = 0x400000, // 100% additive + MTF_SUBTRACT = 0x800000, // 100% subtractive + MTF_SPECTRE = 0x1000000, // 25% additive + MTF_DOUBLEHEALTH = 0x2000000, // Double hit points + // BOOM and DOOM compatible versions of some of the above BTF_NOTSINGLE = 0x0010, // (TF_COOPERATIVE|TF_DEATHMATCH) diff --git a/src/namedef.h b/src/namedef.h index 644d0deb4..50853f7ce 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -373,6 +373,11 @@ xx(Friend) xx(Strifeally) xx(Standing) xx(Countsecret) +//xx(Transparent) defined below for linedefs +//xx(Additive) already defined for invisibility types +xx(Subtractive) +xx(Spectre) +xx(Doublehealth) xx(Blocking) xx(Blockmonsters) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index eb214279d..2bf242cd2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4022,6 +4022,24 @@ void AActor::HandleSpawnFlags () RenderStyle = STYLE_Translucent; alpha = TRANSLUC25; } + else if (SpawnFlags & MTF_TRANS) + { + RenderStyle = STYLE_Translucent; + alpha = TRANSLUC50; + } + else if (SpawnFlags & MTF_ADD) + { + RenderStyle = STYLE_Add; + } + else if (SpawnFlags & MTF_SUBTRACT) + { + RenderStyle = STYLE_Subtract; + } + else if (SpawnFlags & MTF_SPECTRE) + { + RenderStyle = STYLE_Add; + alpha = TRANSLUC25; + } else if (SpawnFlags & MTF_ALTSHADOW) { RenderStyle = STYLE_None; @@ -4035,6 +4053,10 @@ void AActor::HandleSpawnFlags () level.total_secrets++; } } + if (SpawnFlags & MTF_DOUBLEHEALTH) + { + health *= 2; + } } void AActor::BeginPlay () diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index fc5964737..bc58aaef7 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -632,6 +632,31 @@ public: Flag(th->flags, MTF_SECRET, key); break; + case NAME_Transparent: + CHECK_N(Zd | Zdt) + Flag(th->flags, MTF_TRANS, key); + break; + + case NAME_Additive: + CHECK_N(Zd | Zdt) + Flag(th->flags, MTF_ADD, key); + break; + + case NAME_Subtractive: + CHECK_N(Zd | Zdt) + Flag(th->flags, MTF_SUBTRACT, key); + break; + + case NAME_Spectre: + CHECK_N(Zd | Zdt) + Flag(th->flags, MTF_SPECTRE, key); + break; + + case NAME_Doublehealth: + CHECK_N(Zd | Zdt) + Flag(th->flags, MTF_DOUBLEHEALTH, key); + break; + default: if (0 == strnicmp("user_", key.GetChars(), 5)) { // Custom user key - Sets an actor's user variable directly @@ -686,6 +711,7 @@ public: { bool passuse = false; bool strifetrans = false; + bool strifetrans2 = false; FString arg0str, arg1str; memset(ld, 0, sizeof(*ld)); @@ -803,6 +829,11 @@ public: strifetrans = CheckBool(key); continue; + case NAME_Transparent: + CHECK_N(St | Zd | Zdt | Va) + strifetrans2 = CheckBool(key); + continue; + case NAME_Passuse: CHECK_N(Dm | Zd | Zdt | Va) passuse = CheckBool(key); @@ -965,6 +996,10 @@ public: { ld->Alpha = FRACUNIT * 3/4; } + if (strifetrans2 && ld->Alpha == FRACUNIT) + { + ld->Alpha = FRACUNIT * 1/4; + } if (ld->sidedef[0] == NULL) { ld->sidedef[0] = (side_t*)(intptr_t)(1); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 7ece27ae8..be2d154c3 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -89,6 +89,9 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) case -2: ld->Alpha = FRACUNIT*3/4; break; + case -3: + ld->Alpha = FRACUNIT / 4; + break; default: newflags |= LineFlagTranslations[i].newvalue; break; diff --git a/wadsrc/static/xlat/defines.i b/wadsrc/static/xlat/defines.i index 60d582f70..0acc2465e 100644 --- a/wadsrc/static/xlat/defines.i +++ b/wadsrc/static/xlat/defines.i @@ -239,5 +239,6 @@ enum // ML_PASSTHROUGH = -1, - ML_TRANSLUCENT = -2 + ML_TRANSLUCENT = -2, + ML_TRANSPARENT = -3, } \ No newline at end of file diff --git a/wadsrc/static/xlat/strife.txt b/wadsrc/static/xlat/strife.txt index 710fa1fad..159933c80 100644 --- a/wadsrc/static/xlat/strife.txt +++ b/wadsrc/static/xlat/strife.txt @@ -363,5 +363,6 @@ lineflag 7 = ML_DONTDRAW; lineflag 8 = ML_MAPPED; lineflag 9 = ML_RAILING; lineflag 10 = ML_BLOCK_FLOATERS; +lineflag 11 = ML_TRANSPARENT; lineflag 12 = ML_TRANSLUCENT; From 4cac599b8899abd3385eeef4bece05c619d8aedc Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Fri, 11 Apr 2014 00:58:59 +0200 Subject: [PATCH 155/311] Less flags, more generic properties --- src/actor.h | 1 + src/doomdata.h | 17 ++++----- src/namedef.h | 22 +++++++++--- src/p_enemy.cpp | 2 +- src/p_mobj.cpp | 70 ++++++++++++++++++++++--------------- src/p_udmf.cpp | 91 +++++++++++++++++++++++++++++++++++++++++-------- src/version.h | 2 +- 7 files changed, 147 insertions(+), 58 deletions(-) diff --git a/src/actor.h b/src/actor.h index f8b583101..d3cba0041 100644 --- a/src/actor.h +++ b/src/actor.h @@ -873,6 +873,7 @@ public: TObjPtr LastLookActor; // Actor last looked for (if TIDtoHate != 0) fixed_t SpawnPoint[3]; // For nightmare respawn WORD SpawnAngle; + int StartHealth; BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions. BYTE WeaveIndexZ; int skillrespawncount; diff --git a/src/doomdata.h b/src/doomdata.h index 8ba831082..9cedf8cdc 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -345,6 +345,15 @@ struct FMapThing int args[5]; int Conversation; fixed_t gravity; + fixed_t alpha; + DWORD fillcolor; + fixed_t scaleX; + fixed_t scaleY; + int health; + int score; + short pitch; + short roll; + DWORD RenderStyle; void Serialize (FArchive &); }; @@ -387,14 +396,6 @@ enum EMapThingFlags MTF_SECRET = 0x080000, // Secret pickup MTF_NOINFIGHTING = 0x100000, - // PSX Doom and Doom 64 effects - - MTF_TRANS = 0x200000, // 50% alpha - MTF_ADD = 0x400000, // 100% additive - MTF_SUBTRACT = 0x800000, // 100% subtractive - MTF_SPECTRE = 0x1000000, // 25% additive - MTF_DOUBLEHEALTH = 0x2000000, // Double hit points - // BOOM and DOOM compatible versions of some of the above BTF_NOTSINGLE = 0x0010, // (TF_COOPERATIVE|TF_DEATHMATCH) diff --git a/src/namedef.h b/src/namedef.h index 50853f7ce..017f29932 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -31,6 +31,18 @@ xx(Fuzzy) xx(Opaque) xx(Stencil) +// Render styles +xx(Normal) +xx(SoulTrans) +xx(OptFuzzy) +xx(Add) +xx(Shaded) +xx(TranslucentStencil) +xx(Shadow) +xx(Subtract) +xx(Subtractive) +xx(FillColor) + // Healingradius types xx(Mana) xx(Armor) @@ -373,11 +385,11 @@ xx(Friend) xx(Strifeally) xx(Standing) xx(Countsecret) -//xx(Transparent) defined below for linedefs -//xx(Additive) already defined for invisibility types -xx(Subtractive) -xx(Spectre) -xx(Doublehealth) +xx(Score) +xx(Roll) +xx(Scale) +xx(ScaleX) +xx(ScaleY) xx(Blocking) xx(Blockmonsters) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index df1698837..39cd0813c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2648,7 +2648,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) corpsehit->flags5 = info->flags5; corpsehit->flags6 = info->flags6; corpsehit->flags7 = info->flags7; - corpsehit->health = info->health; + corpsehit->health = corpsehit->SpawnHealth(); corpsehit->target = NULL; corpsehit->lastenemy = NULL; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2bf242cd2..291f51a94 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -219,8 +219,12 @@ void AActor::Serialize (FArchive &arc) << threshold << player << SpawnPoint[0] << SpawnPoint[1] << SpawnPoint[2] - << SpawnAngle - << skillrespawncount + << SpawnAngle; + if (SaveVersion >= 4506) + { + arc << StartHealth; + } + arc << skillrespawncount << tracer << floorclip << tid @@ -4022,24 +4026,6 @@ void AActor::HandleSpawnFlags () RenderStyle = STYLE_Translucent; alpha = TRANSLUC25; } - else if (SpawnFlags & MTF_TRANS) - { - RenderStyle = STYLE_Translucent; - alpha = TRANSLUC50; - } - else if (SpawnFlags & MTF_ADD) - { - RenderStyle = STYLE_Add; - } - else if (SpawnFlags & MTF_SUBTRACT) - { - RenderStyle = STYLE_Subtract; - } - else if (SpawnFlags & MTF_SPECTRE) - { - RenderStyle = STYLE_Add; - alpha = TRANSLUC25; - } else if (SpawnFlags & MTF_ALTSHADOW) { RenderStyle = STYLE_None; @@ -4053,10 +4039,6 @@ void AActor::HandleSpawnFlags () level.total_secrets++; } } - if (SpawnFlags & MTF_DOUBLEHEALTH) - { - health *= 2; - } } void AActor::BeginPlay () @@ -4811,11 +4793,42 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } } + // Set various UDMF options + if (mthing->alpha != -1) + { + DPrintf("Setting alpha to %f", FIXED2FLOAT(mthing->alpha)); + mobj->alpha = mthing->alpha; + } + if (mthing->RenderStyle != STYLE_Count) + mobj->RenderStyle = (ERenderStyle)mthing->RenderStyle; + if (mthing->scaleX) + mobj->scaleX = FixedMul(mthing->scaleX, mobj->scaleX); + if (mthing->scaleY) + mobj->scaleY = FixedMul(mthing->scaleY, mobj->scaleY); + if (mthing->pitch) + mobj->pitch = ANGLE_1 * mthing->pitch; + if (mthing->roll) + mobj->roll = ANGLE_1 * mthing->roll; + if (mthing->score) + mobj->Score = mthing->score; + if (mthing->fillcolor) + mobj->fillcolor = mthing->fillcolor; + mobj->BeginPlay (); if (!(mobj->ObjectFlags & OF_EuthanizeMe)) { mobj->LevelSpawned (); } + + if (mthing->health > 0) + mobj->health *= mthing->health; + else + mobj->health = -mthing->health; + if (mthing->health == 0) + mobj->Die(NULL, NULL); + else if (mthing->health != 1) + mobj->StartHealth = mobj->health; + return mobj; } @@ -6038,18 +6051,19 @@ void AActor::SetIdle() int AActor::SpawnHealth() { - if (!(flags3 & MF3_ISMONSTER) || GetDefault()->health == 0) + int defhealth = StartHealth ? StartHealth : GetDefault()->health; + if (!(flags3 & MF3_ISMONSTER) || defhealth == 0) { - return GetDefault()->health; + return defhealth; } else if (flags & MF_FRIENDLY) { - int adj = FixedMul(GetDefault()->health, G_SkillProperty(SKILLP_FriendlyHealth)); + int adj = FixedMul(defhealth, G_SkillProperty(SKILLP_FriendlyHealth)); return (adj <= 0) ? 1 : adj; } else { - int adj = FixedMul(GetDefault()->health, G_SkillProperty(SKILLP_MonsterHealth)); + int adj = FixedMul(defhealth, G_SkillProperty(SKILLP_MonsterHealth)); return (adj <= 0) ? 1 : adj; } } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index bc58aaef7..ae3f94f87 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -476,6 +476,9 @@ public: memset(th, 0, sizeof(*th)); th->gravity = FRACUNIT; + th->RenderStyle = STYLE_Count; + th->alpha = -1; + th->health = 1; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { @@ -632,29 +635,87 @@ public: Flag(th->flags, MTF_SECRET, key); break; - case NAME_Transparent: - CHECK_N(Zd | Zdt) - Flag(th->flags, MTF_TRANS, key); + case NAME_Renderstyle: + { + FName style = CheckString(key); + switch (style) + { + case NAME_None: + th->RenderStyle = STYLE_None; + break; + default: + case NAME_Normal: + th->RenderStyle = STYLE_Normal; + break; + case NAME_Fuzzy: + th->RenderStyle = STYLE_Fuzzy; + break; + case NAME_SoulTrans: + th->RenderStyle = STYLE_SoulTrans; + break; + case NAME_OptFuzzy: + th->RenderStyle = STYLE_OptFuzzy; + break; + case NAME_Stencil: + th->RenderStyle = STYLE_Stencil; + break; + case NAME_Translucent: + th->RenderStyle = STYLE_Translucent; + break; + case NAME_Add: + case NAME_Additive: + th->RenderStyle = STYLE_Add; + break; + case NAME_Shaded: + th->RenderStyle = STYLE_Shaded; + break; + case NAME_TranslucentStencil: + th->RenderStyle = STYLE_TranslucentStencil; + break; + case NAME_Shadow: + th->RenderStyle = STYLE_Shadow; + break; + case NAME_Subtract: + case NAME_Subtractive: + th->RenderStyle = STYLE_Subtract; + break; + } + } break; - case NAME_Additive: - CHECK_N(Zd | Zdt) - Flag(th->flags, MTF_ADD, key); + case NAME_Alpha: + th->alpha = CheckFixed(key); break; - case NAME_Subtractive: - CHECK_N(Zd | Zdt) - Flag(th->flags, MTF_SUBTRACT, key); + case NAME_FillColor: + th->fillcolor = CheckInt(key); + + case NAME_Health: + th->health = CheckInt(key); break; - case NAME_Spectre: - CHECK_N(Zd | Zdt) - Flag(th->flags, MTF_SPECTRE, key); + case NAME_Score: + th->score = CheckInt(key); break; - case NAME_Doublehealth: - CHECK_N(Zd | Zdt) - Flag(th->flags, MTF_DOUBLEHEALTH, key); + case NAME_Pitch: + th->pitch = (short)CheckInt(key); + break; + + case NAME_Roll: + th->roll = (short)CheckInt(key); + break; + + case NAME_ScaleX: + th->scaleX = CheckFixed(key); + break; + + case NAME_ScaleY: + th->scaleY = CheckFixed(key); + break; + + case NAME_Scale: + th->scaleX = th->scaleY = CheckFixed(key); break; default: diff --git a/src/version.h b/src/version.h index 1e328b312..27bfe1021 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4505 +#define SAVEVER 4506 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 101107b1e5ea3f498747f31291d10694d7dbe09f Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sat, 12 Apr 2014 10:55:10 +0200 Subject: [PATCH 156/311] Updated documentation --- specs/udmf_zdoom.txt | 20 ++++++++++++++++++++ src/p_udmf.cpp | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 3241bf4c8..d7face672 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -117,6 +117,8 @@ Note: All fields default to false unless mentioned otherwise. locknumber = ; // Line special is locked arg0str = ; // Alternate string-based version of arg0 + transparent = ; // true = line is a Strife transparent line (alpha 0.25) + * Note about arg0str For lines with ACS specials (80-86 and 226), if arg0str is present and non-null, it @@ -207,6 +209,21 @@ Note: All fields default to false unless mentioned otherwise. arg0str = ; // Alternate string-based version of arg0 gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, // negative values are used as their absolute. Default = 1.0. + + health = ; // Set per-actor health. Positive values are multiplied with the class's property, + // negative values are used as their absolute. Default = 1. + + renderstyle = ; // Set per-actor render style, overriding the class default. Possible values can be "normal", + // "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil", + // "translucent", "fuzzy", "optfuzzy", "soultrans". Default is an empty string for no change. + fillcolor = ; // Fill color used by the "stencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000. + alpha = ; // Translucency of this actor (if applicable to renderstyle), default is 1.0. + score = ; // Score value of this actor, overriding the class default if not null. Default = 0. + pitch = ; // Pitch of thing in degrees. Default = 0 (horizontal). + roll = ; // Pitch of thing in degrees. Default = 0 (horizontal). + scalex = ; // Vertical scaling on thing. Default = 0 (ignored). + scaley = ; // Horizontal scaling on thing. Default = 0 (ignored). + scale = ; // Vertical and horizontal scaling on thing. Default = 0 (ignored). * Note about arg0str @@ -335,6 +352,9 @@ Added arg0str thing property. 1.21 09.08.2013 Added waterzone sector property. +1.22 12.04.2014 +Added transparent line property (to be folded back to core UDMF standard), and health, score, renderstyle, fillcolor, alpha, scale, scalex, scaley, pitch and roll thing properties. + =============================================================================== EOF =============================================================================== diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index ae3f94f87..6af777b36 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -643,7 +643,6 @@ public: case NAME_None: th->RenderStyle = STYLE_None; break; - default: case NAME_Normal: th->RenderStyle = STYLE_Normal; break; @@ -679,6 +678,8 @@ public: case NAME_Subtractive: th->RenderStyle = STYLE_Subtract; break; + default: + break; } } break; From 42708386138aea39d712df72b80a410e92243b4a Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 12 Apr 2014 22:02:19 +1200 Subject: [PATCH 157/311] CANRAISE state definition CANRAISE state for allowing a monster to be resurrected without an infinite frame --- src/info.h | 5 +++++ src/p_enemy.cpp | 5 +++-- src/thingdef/thingdef_states.cpp | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/info.h b/src/info.h index 24bbb5fea..9a316c78d 100644 --- a/src/info.h +++ b/src/info.h @@ -76,6 +76,7 @@ struct FState BYTE SameFrame:1; // Ignore Frame (except when spawning actor) BYTE Fast:1; BYTE NoDelay:1; // Spawn states executes its action normally + BYTE CanRaise:1; // Allows a monster to be resurrected without waiting for an infinate frame int ParameterIndex; inline int GetFrame() const @@ -114,6 +115,10 @@ struct FState { return NoDelay; } + inline bool GetCanRaise() const + { + return CanRaise; + } inline void SetFrame(BYTE frame) { Frame = frame - 'A'; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index df1698837..8b1dd951b 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2527,8 +2527,9 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if (!(corpsehit->flags & MF_CORPSE) ) continue; // not a monster - if (corpsehit->tics != -1) - continue; // not lying still yet + if (corpsehit->tics != -1 && // not lying still yet + !corpsehit->state->GetCanRaise()) // or not ready to be raised yet + continue; raisestate = corpsehit->FindState(NAME_Raise); if (raisestate == NULL) diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index 1d643e33c..5cc2de1c0 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -313,6 +313,11 @@ do_stop: sc.MustGetStringName(")"); continue; } + if (sc.Compare("CANRAISE")) + { + state.CanRaise = true; + continue; + } // Make the action name lowercase strlwr (sc.String); From 745b147d185f38d710649c61aceac68a93fbbc3e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Apr 2014 16:40:53 +0200 Subject: [PATCH 158/311] - fixed typo in xlat files (they don't use exactly C syntax.) --- wadsrc/static/xlat/defines.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/xlat/defines.i b/wadsrc/static/xlat/defines.i index 0acc2465e..04c8b21cc 100644 --- a/wadsrc/static/xlat/defines.i +++ b/wadsrc/static/xlat/defines.i @@ -240,5 +240,5 @@ enum // ML_PASSTHROUGH = -1, ML_TRANSLUCENT = -2, - ML_TRANSPARENT = -3, + ML_TRANSPARENT = -3 } \ No newline at end of file From e5578934ad711fa2e38369f1bbe9e1eb36fc191e Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 17:16:33 +0200 Subject: [PATCH 159/311] Init new non-0 fields for non-UDMF maps. --- src/p_mobj.cpp | 3 --- src/p_setup.cpp | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 291f51a94..2a26d7ef0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4795,10 +4795,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // Set various UDMF options if (mthing->alpha != -1) - { - DPrintf("Setting alpha to %f", FIXED2FLOAT(mthing->alpha)); mobj->alpha = mthing->alpha; - } if (mthing->RenderStyle != STYLE_Count) mobj->RenderStyle = (ERenderStyle)mthing->RenderStyle; if (mthing->scaleX) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 315da4ffc..b2d007f97 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1764,6 +1764,9 @@ void P_LoadThings (MapData * map) mti[i].Conversation = 0; mti[i].SkillFilter = MakeSkill(flags); mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes + mti[i].RenderStyle = STYLE_Count; + mti[i].alpha = -1; + mti[i].health = 1; flags &= ~MTF_SKILLMASK; mti[i].flags = (short)((flags & 0xf) | 0x7e0); if (gameinfo.gametype == GAME_Strife) From 8e3360453fa5d90cbfda05e28817060d8f98dde3 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 17:18:55 +0200 Subject: [PATCH 160/311] Hexen too. --- src/p_setup.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index b2d007f97..f56d761f2 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1840,6 +1840,9 @@ void P_LoadThings2 (MapData * map) mti[i].flags &= ~(MTF_SKILLMASK|MTF_CLASS_MASK); mti[i].Conversation = 0; mti[i].gravity = FRACUNIT; + mti[i].RenderStyle = STYLE_Count; + mti[i].alpha = -1; + mti[i].health = 1; } delete[] mtp; } From 6f2fd8edbfec14a62a6a96ddf3b1050ab3ad9bcb Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 17:22:56 +0200 Subject: [PATCH 161/311] Hexen also needs to init 0 fields. --- src/p_setup.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f56d761f2..c14fcdec0 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1843,6 +1843,7 @@ void P_LoadThings2 (MapData * map) mti[i].RenderStyle = STYLE_Count; mti[i].alpha = -1; mti[i].health = 1; + mti[i].fillcolor = 0 = mti[i].scaleX = mti[i].scaleY = mti[i].score = 0; } delete[] mtp; } From c54f5571ea174c19022354eb35dd3704d08f5ac8 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 17:24:01 +0200 Subject: [PATCH 162/311] Typo. --- src/p_setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c14fcdec0..77b9b077b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1843,7 +1843,7 @@ void P_LoadThings2 (MapData * map) mti[i].RenderStyle = STYLE_Count; mti[i].alpha = -1; mti[i].health = 1; - mti[i].fillcolor = 0 = mti[i].scaleX = mti[i].scaleY = mti[i].score = 0; + mti[i].fillcolor = mti[i].scaleX = mti[i].scaleY = mti[i].score = 0; } delete[] mtp; } From 83182b703de94b7645026db155e979bf0535d778 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 21:01:49 +0200 Subject: [PATCH 163/311] Added slow monsters, the inverse of fast monsters This is a skill setting only, no "always slow" or "never slow" actor flags, and no DM flags. --- src/actor.h | 1 + src/g_level.h | 2 ++ src/g_skill.cpp | 9 +++++++++ src/info.h | 1 + src/p_mobj.cpp | 11 ++++++++++- src/thingdef/thingdef_states.cpp | 5 +++++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/actor.h b/src/actor.h index d3cba0041..21057d86c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1008,6 +1008,7 @@ public: bool SetState (FState *newstate, bool nofunction=false); virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); bool isFast(); + bool isSlow(); void SetIdle(); void ClearCounters(); diff --git a/src/g_level.h b/src/g_level.h index c431b9695..4a84e6871 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -554,6 +554,7 @@ enum ESkillProperty SKILLP_NoPain, SKILLP_ArmorFactor, SKILLP_EasyKey, + SKILLP_SlowMonsters, }; int G_SkillProperty(ESkillProperty prop); const char * G_SkillName(); @@ -568,6 +569,7 @@ struct FSkillInfo fixed_t AmmoFactor, DoubleAmmoFactor, DropAmmoFactor; fixed_t DamageFactor; bool FastMonsters; + bool SlowMonsters; bool DisableCheats; bool AutoUseHealth; diff --git a/src/g_skill.cpp b/src/g_skill.cpp index 46b9a1702..ddfdbb4cc 100644 --- a/src/g_skill.cpp +++ b/src/g_skill.cpp @@ -64,6 +64,7 @@ void FMapInfoParser::ParseSkill () skill.DropAmmoFactor = -1; skill.DamageFactor = FRACUNIT; skill.FastMonsters = false; + skill.SlowMonsters = false; skill.DisableCheats = false; skill.EasyBossBrain = false; skill.EasyKey = false; @@ -118,6 +119,10 @@ void FMapInfoParser::ParseSkill () { skill.FastMonsters = true; } + else if (sc.Compare ("slowmonsters")) + { + skill.SlowMonsters = true; + } else if (sc.Compare ("disablecheats")) { skill.DisableCheats = true; @@ -336,6 +341,9 @@ int G_SkillProperty(ESkillProperty prop) case SKILLP_FastMonsters: return AllSkills[gameskill].FastMonsters || (dmflags & DF_FAST_MONSTERS); + case SKILLP_SlowMonsters: + return AllSkills[gameskill].SlowMonsters; + case SKILLP_Respawn: if (dmflags & DF_MONSTERS_RESPAWN && AllSkills[gameskill].RespawnCounter==0) return TICRATE * gameinfo.defaultrespawntime; @@ -433,6 +441,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other) DropAmmoFactor = other.DropAmmoFactor; DamageFactor = other.DamageFactor; FastMonsters = other.FastMonsters; + SlowMonsters = other.SlowMonsters; DisableCheats = other.DisableCheats; AutoUseHealth = other.AutoUseHealth; EasyBossBrain = other.EasyBossBrain; diff --git a/src/info.h b/src/info.h index 9a316c78d..51c4bd629 100644 --- a/src/info.h +++ b/src/info.h @@ -77,6 +77,7 @@ struct FState BYTE Fast:1; BYTE NoDelay:1; // Spawn states executes its action normally BYTE CanRaise:1; // Allows a monster to be resurrected without waiting for an infinate frame + BYTE Slow:1; // Inverse of fast int ParameterIndex; inline int GetFrame() const diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 291f51a94..f82cf9bce 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -405,7 +405,7 @@ bool AActor::InStateSequence(FState * newstate, FState * basestate) // // Get the actual duration of the next state // We are using a state flag now to indicate a state that should be -// accelerated in Fast mode. +// accelerated in Fast mode or slowed in Slow mode. // //========================================================================== @@ -416,6 +416,10 @@ int AActor::GetTics(FState * newstate) { return tics - (tics>>1); } + else if (isSlow() && newstate->Slow) + { + return tics<<1; + } return tics; } @@ -4082,6 +4086,11 @@ bool AActor::isFast() return !!G_SkillProperty(SKILLP_FastMonsters); } +bool AActor::isSlow() +{ + return !!G_SkillProperty(SKILLP_SlowMonsters); +} + void AActor::Activate (AActor *activator) { if ((flags3 & MF3_ISMONSTER) && (health > 0 || (flags & MF_ICECORPSE))) diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index 5cc2de1c0..6a28e54cd 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -275,6 +275,11 @@ do_stop: state.Fast = true; continue; } + if (sc.Compare("SLOW")) + { + state.Slow = true; + continue; + } if (sc.Compare("NODELAY")) { if (bag.statedef.GetStateLabelIndex(NAME_Spawn) == bag.statedef.GetStateCount()) From 94d47efbb5fa2b7269b50858a9dda9307c436ebb Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 15 Apr 2014 21:02:20 +0200 Subject: [PATCH 164/311] Added slow monsters to Strife's easiest skill --- wadsrc/static/mapinfo/strife.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 83c2285e6..5a25f3779 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -238,6 +238,7 @@ skill baby AmmoFactor = 2 DamageFactor = 0.5 EasyBossBrain + SlowMonsters SpawnFilter = Baby PicName = "M_JKILL" Name = "$SSKILL_BABY" From 48b926e5b47cf2380db412b6c08e8c7aeec1138a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 16 Apr 2014 09:53:07 +0200 Subject: [PATCH 165/311] - check +logfile explicitly at the start of execution. Due to the custom CVAR rewrite it would get called so late that it'd miss half of the log. - added version check for Windows 8. I also would have liked to add 8.1 but due to some incredibly stupid changes in the version API it's no longer possible to reliably retrieve the correct Windows version for later builds. --- src/c_cmds.cpp | 26 ++++++++++++++++---------- src/c_dispatch.h | 2 ++ src/d_main.cpp | 7 +++++++ src/win32/i_system.cpp | 12 ++++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index cdf615ef4..0e7adb8ef 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -441,27 +441,33 @@ CCMD (exec) } } +void execLogfile(const char *fn) +{ + if ((Logfile = fopen(fn, "w"))) + { + const char *timestr = myasctime(); + Printf("Log started: %s\n", timestr); + } + else + { + Printf("Could not start log\n"); + } +} + CCMD (logfile) { - const char *timestr = myasctime (); if (Logfile) { - Printf ("Log stopped: %s\n", timestr); + const char *timestr = myasctime(); + Printf("Log stopped: %s\n", timestr); fclose (Logfile); Logfile = NULL; } if (argv.argc() >= 2) { - if ( (Logfile = fopen (argv[1], "w")) ) - { - Printf ("Log started: %s\n", timestr); - } - else - { - Printf ("Could not start log\n"); - } + execLogfile(argv[1]); } } diff --git a/src/c_dispatch.h b/src/c_dispatch.h index 96dc50644..f4518608d 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -168,4 +168,6 @@ extern unsigned int MakeKey (const char *s); extern unsigned int MakeKey (const char *s, size_t len); extern unsigned int SuperFastHash (const char *data, size_t len); +void execLogfile(const char *fn); + #endif //__C_DISPATCH_H__ diff --git a/src/d_main.cpp b/src/d_main.cpp index 6c938ef53..695e7e517 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2223,6 +2223,13 @@ void D_DoomMain (void) FString *args; int argcount; + // +logfile gets checked too late to catch the full startup log in the logfile so do some extra check for it here. + FString logfile = Args->TakeValue("+logfile"); + if (logfile != NULL) + { + execLogfile(logfile); + } + D_DoomInit(); PClass::StaticInit (); atterm(FinalGC); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index a82cb65f9..4690c253d 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -581,6 +581,18 @@ void I_DetectOS(void) osname = "Server 2008 R2"; } } + else if (info.dwMinorVersion == 2) + { + // Microsoft broke this API for 8.1 so without jumping through hoops it won't be possible anymore to detect never versions aside from the build number, especially for older compilers. + if (info.wProductType == VER_NT_WORKSTATION) + { + osname = "8 (or higher)"; + } + else + { + osname = "Server 2012 (or higher)"; + } + } } break; From d855bd66b301ebd8ad969e6816a4c190d9e3ec8f Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Thu, 17 Apr 2014 00:46:33 +1200 Subject: [PATCH 166/311] Fixed P_LookForPlayers scanning redundancies - Players could be scanned multiple times, repeating expensive tests - Players could be skipped completely and become invisible as a result --- src/p_enemy.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 8b1dd951b..3be53cd64 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1542,7 +1542,6 @@ bool P_LookForEnemies (AActor *actor, INTBOOL allaround, FLookExParams *params) bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) { int c; - int stop; int pnum; player_t* player; bool chasegoal = params? (!(params->flags & LOF_DONTCHASEGOAL)) : true; @@ -1615,20 +1614,22 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) { pnum = actor->LastLookPlayerNumber; } - stop = (pnum - 1) & (MAXPLAYERS-1); for (;;) { - pnum = (pnum + 1) & (MAXPLAYERS-1); - if (!playeringame[pnum]) - continue; - - if (actor->TIDtoHate == 0) + // [ED850] Each and every player should only ever be checked once. + if (c++ < MAXPLAYERS) { - actor->LastLookPlayerNumber = pnum; - } + pnum = (pnum + 1) & (MAXPLAYERS - 1); + if (!playeringame[pnum]) + continue; - if (++c == MAXPLAYERS-1 || pnum == stop) + if (actor->TIDtoHate == 0) + { + actor->LastLookPlayerNumber = pnum; + } + } + else { // done looking if (actor->target == NULL) From 897d87a6a3841a0e484cc5de1e1b411848a3c6a8 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Thu, 17 Apr 2014 01:13:18 +1200 Subject: [PATCH 167/311] Invisibility would could P_LookForPlayers early --- src/p_enemy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 3be53cd64..e187dfb7c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1693,11 +1693,11 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) && P_AproxDistance (player->mo->velx, player->mo->vely) < 5*FRACUNIT) { // Player is sneaking - can't detect - return false; + continue; } if (pr_lookforplayers() < 225) { // Player isn't sneaking, but still didn't detect - return false; + continue; } } } From 60fe07df7451176803f4fe28b42160d02a72bd9c Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Thu, 17 Apr 2014 17:42:16 +0200 Subject: [PATCH 168/311] Added slow states to relevant Strife monsters Namely, acolyte, shadow acolyte, reaver, stalker, and turret. Info on which states needed the slow flag was obtained with Quasar's permission by looking at G_InitNew() in g_game.c and the info.c state tables from Chocolate Strife. Also added fast flag to acolyte states that needed it, based on the same source. --- wadsrc/static/actors/strife/acolyte.txt | 16 ++++++++-------- wadsrc/static/actors/strife/crusader.txt | 19 ++++++++----------- wadsrc/static/actors/strife/reaver.txt | 12 ++++++------ wadsrc/static/actors/strife/stalker.txt | 12 ++++++------ wadsrc/static/actors/strife/strifestuff.txt | 4 ++-- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/wadsrc/static/actors/strife/acolyte.txt b/wadsrc/static/actors/strife/acolyte.txt index 1d04147f0..3ca1dec62 100644 --- a/wadsrc/static/actors/strife/acolyte.txt +++ b/wadsrc/static/actors/strife/acolyte.txt @@ -39,16 +39,16 @@ ACTOR Acolyte : StrifeHumanoid AGRD ABCDABCD 5 A_Wander Loop See: - AGRD A 6 A_AcolyteBits - AGRD BCD 6 A_Chase + AGRD A 6 Fast Slow A_AcolyteBits + AGRD BCD 6 Fast Slow A_Chase Loop Missile: - AGRD E 8 A_FaceTarget - AGRD FE 4 A_ShootGun - AGRD F 6 A_ShootGun + AGRD E 8 Fast Slow A_FaceTarget + AGRD FE 4 Fast Slow A_ShootGun + AGRD F 6 Fast Slow A_ShootGun Goto See Pain: - AGRD O 8 A_Pain + AGRD O 8 Fast Slow A_Pain Goto See Death: AGRD G 4 @@ -170,8 +170,8 @@ ACTOR AcolyteShadow : Acolyte 58 AGRD A 6 A_BeShadowyFoe Goto Super::See+1 Pain: - AGRD O 0 A_SetShadow - AGRD O 8 A_Pain + AGRD O 0 Fast Slow A_SetShadow + AGRD O 8 Fast Slow A_Pain Goto See } } diff --git a/wadsrc/static/actors/strife/crusader.txt b/wadsrc/static/actors/strife/crusader.txt index 36d89ed57..7f7a0d0c5 100644 --- a/wadsrc/static/actors/strife/crusader.txt +++ b/wadsrc/static/actors/strife/crusader.txt @@ -42,19 +42,16 @@ ACTOR Crusader 3005 ROB2 AABBCCDD 3 A_Chase Loop Missile: - ROB2 E 3 A_FaceTarget - ROB2 F 2 Bright A_CrusaderChoose - ROB2 E 2 Bright A_CrusaderSweepLeft - ROB2 F 3 Bright A_CrusaderSweepLeft - ROB2 E 2 Bright A_CrusaderSweepLeft - ROB2 F 2 Bright A_CrusaderSweepLeft - ROB2 E 2 Bright A_CrusaderSweepRight - ROB2 F 2 Bright A_CrusaderSweepRight - ROB2 E 2 Bright A_CrusaderSweepRight - ROB2 F 2 A_CrusaderRefire + ROB2 E 3 Slow A_FaceTarget + ROB2 F 2 Slow Bright A_CrusaderChoose + ROB2 E 2 Slow Bright A_CrusaderSweepLeft + ROB2 F 3 Slow Bright A_CrusaderSweepLeft + ROB2 EF 2 Slow Bright A_CrusaderSweepLeft + ROB2 EFE 2 Slow Bright A_CrusaderSweepRight + ROB2 F 2 Slow A_CrusaderRefire Loop Pain: - ROB2 D 1 A_Pain + ROB2 D 1 Slow A_Pain Goto See Death: ROB2 G 3 A_Scream diff --git a/wadsrc/static/actors/strife/reaver.txt b/wadsrc/static/actors/strife/reaver.txt index 23439b9ba..a69947373 100644 --- a/wadsrc/static/actors/strife/reaver.txt +++ b/wadsrc/static/actors/strife/reaver.txt @@ -32,16 +32,16 @@ ACTOR Reaver 3001 ROB1 BBCCDDEE 3 A_Chase Loop Melee: - ROB1 H 6 A_FaceTarget - ROB1 I 8 A_CustomMeleeAttack(random[ReaverMelee](1,8)*3, "reaver/blade") - ROB1 H 6 + ROB1 H 6 Slow A_FaceTarget + ROB1 I 8 Slow A_CustomMeleeAttack(random[ReaverMelee](1,8)*3, "reaver/blade") + ROB1 H 6 Slow Goto See Missile: - ROB1 F 8 A_FaceTarget - ROB1 G 11 BRIGHT A_ReaverRanged + ROB1 F 8 Slow A_FaceTarget + ROB1 G 11 Slow BRIGHT A_ReaverRanged Goto See Pain: - ROB1 A 2 + ROB1 A 2 Slow ROB1 A 2 A_Pain Goto See Death: diff --git a/wadsrc/static/actors/strife/stalker.txt b/wadsrc/static/actors/strife/stalker.txt index 80732131e..0a537c762 100644 --- a/wadsrc/static/actors/strife/stalker.txt +++ b/wadsrc/static/actors/strife/stalker.txt @@ -45,14 +45,14 @@ ACTOR Stalker 186 STLK J 10 A_Look Loop See: - STLK A 1 A_StalkerChaseDecide - STLK ABB 3 A_Chase - STLK C 3 A_StalkerWalk - STLK C 3 A_Chase + STLK A 1 Slow A_StalkerChaseDecide + STLK ABB 3 Slow A_Chase + STLK C 3 Slow A_StalkerWalk + STLK C 3 Slow A_Chase Loop Melee: - STLK J 3 A_FaceTarget - STLK K 3 A_StalkerAttack + STLK J 3 Slow A_FaceTarget + STLK K 3 Slow A_StalkerAttack SeeFloor: STLK J 3 A_StalkerWalk STLK KK 3 A_Chase diff --git a/wadsrc/static/actors/strife/strifestuff.txt b/wadsrc/static/actors/strife/strifestuff.txt index b0f4024f4..ef762cbb6 100644 --- a/wadsrc/static/actors/strife/strifestuff.txt +++ b/wadsrc/static/actors/strife/strifestuff.txt @@ -1786,8 +1786,8 @@ ACTOR CeilingTurret 27 Loop Missile: Pain: - TURT B 4 A_ShootGun - TURT D 3 A_SentinelRefire + TURT B 4 Slow A_ShootGun + TURT D 3 Slow A_SentinelRefire TURT A 4 A_SentinelRefire Loop Death: From 1c50b5dd6f764eb70f29624cead70a929ffeab9c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 20 Apr 2014 13:37:59 +0300 Subject: [PATCH 169/311] Fixed initialization of Hexen-style things Recently added pitch and roll members were not initialized with zeroes when loading Hexen-style maps At least, hitscan attack can be fired in random direction because of this --- src/p_setup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 77b9b077b..c564d1aa7 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1826,6 +1826,8 @@ void P_LoadThings2 (MapData * map) for(int i = 0; i< numthings; i++) { + memset (&mti[i], 0, sizeof(mti[i])); + mti[i].thingid = LittleShort(mth[i].thingid); mti[i].x = LittleShort(mth[i].x)<> MTF_CLASS_SHIFT; mti[i].flags &= ~(MTF_SKILLMASK|MTF_CLASS_MASK); - mti[i].Conversation = 0; mti[i].gravity = FRACUNIT; mti[i].RenderStyle = STYLE_Count; mti[i].alpha = -1; mti[i].health = 1; - mti[i].fillcolor = mti[i].scaleX = mti[i].scaleY = mti[i].score = 0; } delete[] mtp; } From 265917c923bb33bac32d91ad15ebbf79b1d169dc Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 22 Apr 2014 13:31:55 +0200 Subject: [PATCH 170/311] Add shadow and subtract styles to ACS. There is a matching pull request for rheit/acs. --- src/p_acs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4cb34defa..1c84c9401 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3546,6 +3546,8 @@ static const int LegacyRenderStyleIndices[] = 65, // STYLE_Add, 66, // STYLE_Shaded, 67, // STYLE_TranslucentStencil, + 68, // STYLE_Shadow, + 69, // STYLE_Subtract, -1 }; From 7c3660087ed7fc1db18c0ae38285a14f6f5a5c9f Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 22 Apr 2014 13:32:33 +0200 Subject: [PATCH 171/311] Restore shadow renderstyle. It was accidentally lost in r3085. --- src/thingdef/thingdef_properties.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 61ab5b968..4e4fb4218 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -796,11 +796,13 @@ DEFINE_PROPERTY(renderstyle, S, Actor) { PROP_STRING_PARM(str, 0); static const char * renderstyles[]={ - "NONE", "NORMAL", "FUZZY", "SOULTRANS", "OPTFUZZY", "STENCIL", "TRANSLUCENT", "ADD", "SHADED", "SUBTRACT", NULL }; + "NONE", "NORMAL", "FUZZY", "SOULTRANS", "OPTFUZZY", "STENCIL", + "TRANSLUCENT", "ADD", "SHADED", "SHADOW", "SUBTRACT", NULL }; static const int renderstyle_values[]={ STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, - STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded, STYLE_Subtract}; + STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded, + STYLE_Shadow, STYLE_Subtract}; // make this work for old style decorations, too. if (!strnicmp(str, "style_", 6)) str+=6; From 3fa89b4e9fb9579b2b77927997dbc41c4cc876e8 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 Apr 2014 10:18:50 +0300 Subject: [PATCH 172/311] Fixed crash on attempt to load corrupted data file Instance of FileReader is no longer destructed when header of data file is valid but complete loading of file fails Loading of truncated .zip file is the simplest test case --- src/resourcefiles/file_7z.cpp | 2 ++ src/resourcefiles/file_grp.cpp | 2 ++ src/resourcefiles/file_pak.cpp | 2 ++ src/resourcefiles/file_rff.cpp | 2 ++ src/resourcefiles/file_wad.cpp | 2 ++ src/resourcefiles/file_zip.cpp | 2 ++ 6 files changed, 12 insertions(+) diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 8b1c23b67..5c9289242 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -351,6 +351,8 @@ FResourceFile *Check7Z(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new F7ZFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } diff --git a/src/resourcefiles/file_grp.cpp b/src/resourcefiles/file_grp.cpp index dc4c97812..63738d7e6 100644 --- a/src/resourcefiles/file_grp.cpp +++ b/src/resourcefiles/file_grp.cpp @@ -147,6 +147,8 @@ FResourceFile *CheckGRP(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new FGrpFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } diff --git a/src/resourcefiles/file_pak.cpp b/src/resourcefiles/file_pak.cpp index 099e8046c..9ea01767b 100644 --- a/src/resourcefiles/file_pak.cpp +++ b/src/resourcefiles/file_pak.cpp @@ -139,6 +139,8 @@ FResourceFile *CheckPak(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new FPakFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index 2e6a3bc5a..682df985d 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -260,6 +260,8 @@ FResourceFile *CheckRFF(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new FRFFFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } diff --git a/src/resourcefiles/file_wad.cpp b/src/resourcefiles/file_wad.cpp index ea8cac15b..384290782 100644 --- a/src/resourcefiles/file_wad.cpp +++ b/src/resourcefiles/file_wad.cpp @@ -651,6 +651,8 @@ FResourceFile *CheckWad(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new FWadFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 101b51982..7ae0e90a5 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -423,6 +423,8 @@ FResourceFile *CheckZip(const char *filename, FileReader *file, bool quiet) { FResourceFile *rf = new FZipFile(filename, file); if (rf->Open(quiet)) return rf; + + rf->Reader = NULL; // to avoid destruction of reader delete rf; } } From 6b26b710b84110b4f96e27da59dc9c8329948e86 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 Apr 2014 10:23:20 +0300 Subject: [PATCH 173/311] Added simple check for unsupported compression method in .7z files --- src/resourcefiles/file_7z.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 5c9289242..a00626774 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -293,6 +293,21 @@ bool F7ZFile::Open(bool quiet) } // Resize the lump record array to its actual size NumLumps -= skipped; + + if (NumLumps > 0) + { + // Quick check for unsupported compression method + + TArray temp; + temp.Resize(Lumps[0].LumpSize); + + if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) + { + if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", Filename); + return false; + } + } + if (!quiet) Printf(", %d lumps\n", NumLumps); // Entries in archives are sorted alphabetically From 3af7d8a245a3d8c310fb8077a14ecaec36df1714 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 27 Apr 2014 13:05:40 +0300 Subject: [PATCH 174/311] Added support for LZMA2 compression method in .7z archives Updated LZMA SDK to version 9.20 http://www.7-zip.org/sdk.html http://downloads.sourceforge.net/sevenzip/lzma920.tar.bz2 --- lzma/C/7z.h | 203 ++++++++++++++ lzma/C/7zBuf.h | 10 +- lzma/C/7zCrc.c | 77 ++++-- lzma/C/7zCrc.h | 13 +- lzma/C/7zCrcOpt.c | 34 +++ lzma/C/7zDec.c | 470 +++++++++++++++++++++++++++++++++ lzma/C/{Archive/7z => }/7zIn.c | 366 +++++++++++++++++++------ lzma/C/7zStream.c | 8 +- lzma/C/7zVersion.h | 8 +- lzma/C/Alloc.c | 127 --------- lzma/C/Alloc.h | 32 --- lzma/C/Archive/7z/7zDecode.c | 254 ------------------ lzma/C/Archive/7z/7zDecode.h | 13 - lzma/C/Archive/7z/7zExtract.c | 93 ------- lzma/C/Archive/7z/7zExtract.h | 41 --- lzma/C/Archive/7z/7zHeader.c | 6 - lzma/C/Archive/7z/7zHeader.h | 57 ---- lzma/C/Archive/7z/7zIn.h | 41 --- lzma/C/Archive/7z/7zItem.c | 127 --------- lzma/C/Archive/7z/7zItem.h | 84 ------ lzma/C/Bcj2.h | 10 +- lzma/C/Bra.c | 133 ++++++++++ lzma/C/Bra.h | 10 +- lzma/C/CpuArch.c | 168 ++++++++++++ lzma/C/CpuArch.h | 118 +++++++-- lzma/C/LzFind.c | 20 +- lzma/C/LzFind.h | 16 +- lzma/C/LzFindMt.c | 34 +-- lzma/C/LzFindMt.h | 16 +- lzma/C/LzHash.h | 6 +- lzma/C/Lzma2Dec.c | 356 +++++++++++++++++++++++++ lzma/C/Lzma2Dec.h | 84 ++++++ lzma/C/LzmaDec.c | 14 +- lzma/C/LzmaDec.h | 22 +- lzma/C/LzmaEnc.c | 103 ++++---- lzma/C/LzmaEnc.h | 14 +- lzma/C/LzmaLib.c | 46 ---- lzma/C/LzmaLib.h | 135 ---------- lzma/C/Threads.c | 294 +++------------------ lzma/C/Threads.h | 162 +++--------- lzma/C/Types.h | 72 ++++- lzma/CMakeLists.txt | 28 +- lzma/history.txt | 35 +++ lzma/lzma.txt | 34 +-- lzma/lzmalib.vcproj | 80 ++---- src/resourcefiles/file_7z.cpp | 30 ++- 46 files changed, 2311 insertions(+), 1793 deletions(-) create mode 100644 lzma/C/7z.h create mode 100644 lzma/C/7zCrcOpt.c create mode 100644 lzma/C/7zDec.c rename lzma/C/{Archive/7z => }/7zIn.c (75%) delete mode 100644 lzma/C/Alloc.c delete mode 100644 lzma/C/Alloc.h delete mode 100644 lzma/C/Archive/7z/7zDecode.c delete mode 100644 lzma/C/Archive/7z/7zDecode.h delete mode 100644 lzma/C/Archive/7z/7zExtract.c delete mode 100644 lzma/C/Archive/7z/7zExtract.h delete mode 100644 lzma/C/Archive/7z/7zHeader.c delete mode 100644 lzma/C/Archive/7z/7zHeader.h delete mode 100644 lzma/C/Archive/7z/7zIn.h delete mode 100644 lzma/C/Archive/7z/7zItem.c delete mode 100644 lzma/C/Archive/7z/7zItem.h create mode 100644 lzma/C/Bra.c create mode 100644 lzma/C/CpuArch.c create mode 100644 lzma/C/Lzma2Dec.c create mode 100644 lzma/C/Lzma2Dec.h delete mode 100644 lzma/C/LzmaLib.c delete mode 100644 lzma/C/LzmaLib.h mode change 100644 => 100755 lzma/history.txt mode change 100644 => 100755 lzma/lzma.txt diff --git a/lzma/C/7z.h b/lzma/C/7z.h new file mode 100644 index 000000000..b7edd3ba5 --- /dev/null +++ b/lzma/C/7z.h @@ -0,0 +1,203 @@ +/* 7z.h -- 7z interface +2010-03-11 : Igor Pavlov : Public domain */ + +#ifndef __7Z_H +#define __7Z_H + +#include "7zBuf.h" + +EXTERN_C_BEGIN + +#define k7zStartHeaderSize 0x20 +#define k7zSignatureSize 6 +extern Byte k7zSignature[k7zSignatureSize]; +#define k7zMajorVersion 0 + +enum EIdEnum +{ + k7zIdEnd, + k7zIdHeader, + k7zIdArchiveProperties, + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + k7zIdSize, + k7zIdCRC, + k7zIdFolder, + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttributes, + k7zIdComment, + k7zIdEncodedHeader, + k7zIdStartPos, + k7zIdDummy +}; + +typedef struct +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + UInt64 MethodID; + CBuf Props; +} CSzCoderInfo; + +void SzCoderInfo_Init(CSzCoderInfo *p); +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); + +typedef struct +{ + UInt32 InIndex; + UInt32 OutIndex; +} CSzBindPair; + +typedef struct +{ + CSzCoderInfo *Coders; + CSzBindPair *BindPairs; + UInt32 *PackStreams; + UInt64 *UnpackSizes; + UInt32 NumCoders; + UInt32 NumBindPairs; + UInt32 NumPackStreams; + int UnpackCRCDefined; + UInt32 UnpackCRC; + + UInt32 NumUnpackStreams; +} CSzFolder; + +void SzFolder_Init(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); + +SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *stream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); + +typedef struct +{ + UInt32 Low; + UInt32 High; +} CNtfsFileTime; + +typedef struct +{ + CNtfsFileTime MTime; + UInt64 Size; + UInt32 Crc; + UInt32 Attrib; + Byte HasStream; + Byte IsDir; + Byte IsAnti; + Byte CrcDefined; + Byte MTimeDefined; + Byte AttribDefined; +} CSzFileItem; + +void SzFile_Init(CSzFileItem *p); + +typedef struct +{ + UInt64 *PackSizes; + Byte *PackCRCsDefined; + UInt32 *PackCRCs; + CSzFolder *Folders; + CSzFileItem *Files; + UInt32 NumPackStreams; + UInt32 NumFolders; + UInt32 NumFiles; +} CSzAr; + +void SzAr_Init(CSzAr *p); +void SzAr_Free(CSzAr *p, ISzAlloc *alloc); + + +/* + SzExtract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +typedef struct +{ + CSzAr db; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + + UInt32 *FolderStartPackStreamIndex; + UInt64 *PackStreamStartPositions; + UInt32 *FolderStartFileIndex; + UInt32 *FileIndexToFolderIndexMap; + + size_t *FileNameOffsets; /* in 2-byte steps */ + CBuf FileNames; /* UTF-16-LE */ +} CSzArEx; + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); + +/* +if dest == NULL, the return value specifies the required size of the buffer, + in 16-bit characters, including the null-terminating character. +if dest != NULL, the return value specifies the number of 16-bit characters that + are written to the dest, including the null-terminating character. */ + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); + +SRes SzArEx_Extract( + const CSzArEx *db, + ILookInStream *inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + + +/* +SzArEx_Open Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); + +EXTERN_C_END + +#endif diff --git a/lzma/C/7zBuf.h b/lzma/C/7zBuf.h index 49b2354bd..88ff0c2f2 100644 --- a/lzma/C/7zBuf.h +++ b/lzma/C/7zBuf.h @@ -1,11 +1,15 @@ /* 7zBuf.h -- Byte Buffer -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ #ifndef __7Z_BUF_H #define __7Z_BUF_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { Byte *data; @@ -28,4 +32,8 @@ void DynBuf_SeekToBeg(CDynBuf *p); int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/7zCrc.c b/lzma/C/7zCrc.c index 92c47de0d..5801dabfc 100644 --- a/lzma/C/7zCrc.c +++ b/lzma/C/7zCrc.c @@ -1,35 +1,74 @@ /* 7zCrc.c -- CRC32 calculation -2008-08-05 -Igor Pavlov -Public domain */ +2009-11-23 : Igor Pavlov : Public domain */ #include "7zCrc.h" +#include "CpuArch.h" #define kCrcPoly 0xEDB88320 -UInt32 g_CrcTable[256]; -void MY_FAST_CALL CrcGenerateTable(void) +#ifdef MY_CPU_LE +#define CRC_NUM_TABLES 8 +#else +#define CRC_NUM_TABLES 1 +#endif + +typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); + +static CRC_FUNC g_CrcUpdate; +UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; + +#if CRC_NUM_TABLES == 1 + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#else + +UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); + +#endif + +UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) +{ + return g_CrcUpdate(v, data, size, g_CrcTable); +} + +UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) +{ + return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; +} + +void MY_FAST_CALL CrcGenerateTable() { UInt32 i; for (i = 0; i < 256; i++) { UInt32 r = i; - int j; + unsigned j; for (j = 0; j < 8; j++) r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); g_CrcTable[i] = r; } -} - -UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 ; size--, p++) - v = CRC_UPDATE_BYTE(v, *p); - return v; -} - -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) -{ - return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; + #if CRC_NUM_TABLES == 1 + g_CrcUpdate = CrcUpdateT1; + #else + for (; i < 256 * CRC_NUM_TABLES; i++) + { + UInt32 r = g_CrcTable[i - 256]; + g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); + } + g_CrcUpdate = CrcUpdateT4; + #ifdef MY_CPU_X86_OR_AMD64 + if (!CPU_Is_InOrder()) + g_CrcUpdate = CrcUpdateT8; + #endif + #endif } diff --git a/lzma/C/7zCrc.h b/lzma/C/7zCrc.h index ae230991e..4a1ec38c9 100644 --- a/lzma/C/7zCrc.h +++ b/lzma/C/7zCrc.h @@ -1,24 +1,25 @@ /* 7zCrc.h -- CRC32 calculation -2008-03-13 -Igor Pavlov -Public domain */ +2009-11-21 : Igor Pavlov : Public domain */ #ifndef __7Z_CRC_H #define __7Z_CRC_H -#include - #include "Types.h" +EXTERN_C_BEGIN + extern UInt32 g_CrcTable[]; +/* Call CrcGenerateTable one time before other CRC functions */ void MY_FAST_CALL CrcGenerateTable(void); #define CRC_INIT_VAL 0xFFFFFFFF -#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) +#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); +EXTERN_C_END + #endif diff --git a/lzma/C/7zCrcOpt.c b/lzma/C/7zCrcOpt.c new file mode 100644 index 000000000..6205d7161 --- /dev/null +++ b/lzma/C/7zCrcOpt.c @@ -0,0 +1,34 @@ +/* 7zCrcOpt.c -- CRC32 calculation : optimized version +2009-11-23 : Igor Pavlov : Public domain */ + +#include "CpuArch.h" + +#ifdef MY_CPU_LE + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + table[0x300 + (v & 0xFF)] ^ + table[0x200 + ((v >> 8) & 0xFF)] ^ + table[0x100 + ((v >> 16) & 0xFF)] ^ + table[0x000 + ((v >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + return CrcUpdateT4(v, data, size, table); +} + +#endif diff --git a/lzma/C/7zDec.c b/lzma/C/7zDec.c new file mode 100644 index 000000000..338680747 --- /dev/null +++ b/lzma/C/7zDec.c @@ -0,0 +1,470 @@ +/* 7zDec.c -- Decoding from 7z folder +2010-11-02 : Igor Pavlov : Public domain */ + +#include + +/* #define _7ZIP_PPMD_SUPPPORT */ + +#include "7z.h" + +#include "Bcj2.h" +#include "Bra.h" +#include "CpuArch.h" +#include "LzmaDec.h" +#include "Lzma2Dec.h" +#ifdef _7ZIP_PPMD_SUPPPORT +#include "Ppmd7.h" +#endif + +#define k_Copy 0 +#define k_LZMA2 0x21 +#define k_LZMA 0x30101 +#define k_BCJ 0x03030103 +#define k_PPC 0x03030205 +#define k_ARM 0x03030501 +#define k_ARMT 0x03030701 +#define k_SPARC 0x03030805 +#define k_BCJ2 0x0303011B + +#ifdef _7ZIP_PPMD_SUPPPORT + +#define k_PPMD 0x30401 + +typedef struct +{ + IByteIn p; + const Byte *cur; + const Byte *end; + const Byte *begin; + UInt64 processed; + Bool extra; + SRes res; + ILookInStream *inStream; +} CByteInToLook; + +static Byte ReadByte(void *pp) +{ + CByteInToLook *p = (CByteInToLook *)pp; + if (p->cur != p->end) + return *p->cur++; + if (p->res == SZ_OK) + { + size_t size = p->cur - p->begin; + p->processed += size; + p->res = p->inStream->Skip(p->inStream, size); + size = (1 << 25); + p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); + p->cur = p->begin; + p->end = p->begin + size; + if (size != 0) + return *p->cur++;; + } + p->extra = True; + return 0; +} + +static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CPpmd7 ppmd; + CByteInToLook s; + SRes res = SZ_OK; + + s.p.Read = ReadByte; + s.inStream = inStream; + s.begin = s.end = s.cur = NULL; + s.extra = False; + s.res = SZ_OK; + s.processed = 0; + + if (coder->Props.size != 5) + return SZ_ERROR_UNSUPPORTED; + + { + unsigned order = coder->Props.data[0]; + UInt32 memSize = GetUi32(coder->Props.data + 1); + if (order < PPMD7_MIN_ORDER || + order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) + return SZ_ERROR_UNSUPPORTED; + Ppmd7_Construct(&ppmd); + if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) + return SZ_ERROR_MEM; + Ppmd7_Init(&ppmd, order); + } + { + CPpmd7z_RangeDec rc; + Ppmd7z_RangeDec_CreateVTable(&rc); + rc.Stream = &s.p; + if (!Ppmd7z_RangeDec_Init(&rc)) + res = SZ_ERROR_DATA; + else if (s.extra) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else + { + SizeT i; + for (i = 0; i < outSize; i++) + { + int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); + if (s.extra || sym < 0) + break; + outBuffer[i] = (Byte)sym; + } + if (i != outSize) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) + res = SZ_ERROR_DATA; + } + } + Ppmd7_Free(&ppmd, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) + { + if (state.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CLzma2Dec state; + SRes res = SZ_OK; + + Lzma2Dec_Construct(&state); + if (coder->Props.size != 1) + return SZ_ERROR_DATA; + RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); + state.decoder.dic = outBuffer; + state.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&state); + + for (;;) + { + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; + ELzmaStatus status; + res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) + { + if (state.decoder.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + Lzma2Dec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +{ + while (inSize > 0) + { + void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(inStream->Skip((void *)inStream, curSize)); + } + return SZ_OK; +} + +static Bool IS_MAIN_METHOD(UInt32 m) +{ + switch(m) + { + case k_Copy: + case k_LZMA: + case k_LZMA2: + #ifdef _7ZIP_PPMD_SUPPPORT + case k_PPMD: + #endif + return True; + } + return False; +} + +static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) +{ + return + c->NumInStreams == 1 && + c->NumOutStreams == 1 && + c->MethodID <= (UInt32)0xFFFFFFFF && + IS_MAIN_METHOD((UInt32)c->MethodID); +} + +#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) + +static SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (!IS_SUPPORTED_CODER(&f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + if (f->NumCoders == 2) + { + CSzCoderInfo *c = &f->Coders[1]; + if (c->MethodID > (UInt32)0xFFFFFFFF || + c->NumInStreams != 1 || + c->NumOutStreams != 1 || + f->NumPackStreams != 1 || + f->PackStreams[0] != 0 || + f->NumBindPairs != 1 || + f->BindPairs[0].InIndex != 1 || + f->BindPairs[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + switch ((UInt32)c->MethodID) + { + case k_BCJ: + case k_ARM: + break; + default: + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; + } + if (f->NumCoders == 4) + { + if (!IS_SUPPORTED_CODER(&f->Coders[1]) || + !IS_SUPPORTED_CODER(&f->Coders[2]) || + !IS_BCJ2(&f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 || + f->PackStreams[0] != 2 || + f->PackStreams[1] != 6 || + f->PackStreams[2] != 1 || + f->PackStreams[3] != 0 || + f->NumBindPairs != 3 || + f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || + f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || + f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + return SZ_ERROR_UNSUPPORTED; +} + +static UInt64 GetSum(const UInt64 *values, UInt32 index) +{ + UInt64 sum = 0; + UInt32 i; + for (i = 0; i < index; i++) + sum += values[i]; + return sum; +} + +#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; + +static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, + Byte *tempBuf[]) +{ + UInt32 ci; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; + Byte *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)); + + for (ci = 0; ci < folder->NumCoders; ci++) + { + CSzCoderInfo *coder = &folder->Coders[ci]; + + if (IS_MAIN_METHOD((UInt32)coder->MethodID)) + { + UInt32 si = 0; + UInt64 offset; + UInt64 inSize; + Byte *outBufCur = outBuffer; + SizeT outSizeCur = outSize; + if (folder->NumCoders == 4) + { + UInt32 indices[] = { 3, 2, 0 }; + UInt64 unpackSize = folder->UnpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + Byte *temp; + outSizeCur = (SizeT)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); + if (temp == 0 && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (SizeT)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = GetSum(packSizes, si); + inSize = packSizes[si]; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + } + else if (coder->MethodID == k_LZMA) + { + RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else if (coder->MethodID == k_LZMA2) + { + RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else + { + #ifdef _7ZIP_PPMD_SUPPPORT + RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + #else + return SZ_ERROR_UNSUPPORTED; + #endif + } + } + else if (coder->MethodID == k_BCJ2) + { + UInt64 offset = GetSum(packSizes, 1); + UInt64 s3Size = packSizes[1]; + SRes res; + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + tempSizes[2] = (SizeT)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); + if (tempBuf[2] == 0 && tempSizes[2] != 0) + return SZ_ERROR_MEM; + res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); + RINOK(res) + + res = Bcj2_Decode( + tempBuf3, tempSize3, + tempBuf[0], tempSizes[0], + tempBuf[1], tempSizes[1], + tempBuf[2], tempSizes[2], + outBuffer, outSize); + RINOK(res) + } + else + { + if (ci != 1) + return SZ_ERROR_UNSUPPORTED; + switch(coder->MethodID) + { + case k_BCJ: + { + UInt32 state; + x86_Convert_Init(state); + x86_Convert(outBuffer, outSize, 0, &state, 0); + break; + } + CASE_BRA_CONV(ARM) + default: + return SZ_ERROR_UNSUPPORTED; + } + } + } + return SZ_OK; +} + +SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + Byte *tempBuf[3] = { 0, 0, 0}; + int i; + SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); + for (i = 0; i < 3; i++) + IAlloc_Free(allocMain, tempBuf[i]); + return res; +} diff --git a/lzma/C/Archive/7z/7zIn.c b/lzma/C/7zIn.c similarity index 75% rename from lzma/C/Archive/7z/7zIn.c rename to lzma/C/7zIn.c index 75b0bcd1d..f1a44928e 100644 --- a/lzma/C/Archive/7z/7zIn.c +++ b/lzma/C/7zIn.c @@ -1,17 +1,134 @@ /* 7zIn.c -- 7z Input functions -2008-12-31 : Igor Pavlov : Public domain */ +2010-10-29 : Igor Pavlov : Public domain */ -#include "../../7zCrc.h" -#include "../../CpuArch.h" +#include -#include "7zDecode.h" -#include "7zIn.h" +#include "7z.h" +#include "7zCrc.h" +#include "CpuArch.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; #define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } #define NUM_FOLDER_CODERS_MAX 32 #define NUM_CODER_STREAMS_MAX 32 +void SzCoderInfo_Init(CSzCoderInfo *p) +{ + Buf_Init(&p->Props); +} + +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) +{ + Buf_Free(&p->Props, alloc); + SzCoderInfo_Init(p); +} + +void SzFolder_Init(CSzFolder *p) +{ + p->Coders = 0; + p->BindPairs = 0; + p->PackStreams = 0; + p->UnpackSizes = 0; + p->NumCoders = 0; + p->NumBindPairs = 0; + p->NumPackStreams = 0; + p->UnpackCRCDefined = 0; + p->UnpackCRC = 0; + p->NumUnpackStreams = 0; +} + +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Coders) + for (i = 0; i < p->NumCoders; i++) + SzCoderInfo_Free(&p->Coders[i], alloc); + IAlloc_Free(alloc, p->Coders); + IAlloc_Free(alloc, p->BindPairs); + IAlloc_Free(alloc, p->PackStreams); + IAlloc_Free(alloc, p->UnpackSizes); + SzFolder_Init(p); +} + +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) +{ + UInt32 result = 0; + UInt32 i; + for (i = 0; i < p->NumCoders; i++) + result += p->Coders[i].NumOutStreams; + return result; +} + +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +UInt64 SzFolder_GetUnpackSize(CSzFolder *p) +{ + int i = (int)SzFolder_GetNumOutStreams(p); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolder_FindBindPairForOutStream(p, i) < 0) + return p->UnpackSizes[i]; + /* throw 1; */ + return 0; +} + +void SzFile_Init(CSzFileItem *p) +{ + p->HasStream = 1; + p->IsDir = 0; + p->IsAnti = 0; + p->CrcDefined = 0; + p->MTimeDefined = 0; +} + +void SzAr_Init(CSzAr *p) +{ + p->PackSizes = 0; + p->PackCRCsDefined = 0; + p->PackCRCs = 0; + p->Folders = 0; + p->Files = 0; + p->NumPackStreams = 0; + p->NumFolders = 0; + p->NumFiles = 0; +} + +void SzAr_Free(CSzAr *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Folders) + for (i = 0; i < p->NumFolders; i++) + SzFolder_Free(&p->Folders[i], alloc); + + IAlloc_Free(alloc, p->PackSizes); + IAlloc_Free(alloc, p->PackCRCsDefined); + IAlloc_Free(alloc, p->PackCRCs); + IAlloc_Free(alloc, p->Folders); + IAlloc_Free(alloc, p->Files); + SzAr_Init(p); +} + + void SzArEx_Init(CSzArEx *p) { SzAr_Init(&p->db); @@ -19,6 +136,8 @@ void SzArEx_Init(CSzArEx *p) p->PackStreamStartPositions = 0; p->FolderStartFileIndex = 0; p->FileIndexToFolderIndexMap = 0; + p->FileNameOffsets = 0; + Buf_Init(&p->FileNames); } void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) @@ -27,6 +146,10 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) IAlloc_Free(alloc, p->PackStreamStartPositions); IAlloc_Free(alloc, p->FolderStartFileIndex); IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); + + IAlloc_Free(alloc, p->FileNameOffsets); + Buf_Free(&p->FileNames, alloc); + SzAr_Free(&p->db, alloc); SzArEx_Init(p); } @@ -488,11 +611,11 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) return SZ_ERROR_UNSUPPORTED; folder->NumBindPairs = numBindPairs = numOutStreams - 1; - MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); + MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); for (i = 0; i < numBindPairs; i++) { - CBindPair *bp = folder->BindPairs + i; + CSzBindPair *bp = folder->BindPairs + i; RINOK(SzReadNumber32(sd, &bp->InIndex)); RINOK(SzReadNumber32(sd, &bp->OutIndex)); } @@ -780,81 +903,38 @@ static SRes SzReadStreamsInfo( } } -Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + if (dest != 0) + { + size_t i; + const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); + for (i = 0; i < len; i++) + dest[i] = GetUi16(src + i * 2); + } + return len; +} -static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) +static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes) { UInt32 i; + size_t pos = 0; for (i = 0; i < numFiles; i++) { - UInt32 len = 0; - UInt32 pos = 0; - CSzFileItem *file = files + i; - while (pos + 2 <= sd->Size) + sizes[i] = pos; + for (;;) { - int numAdds; - UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); - pos += 2; - len++; - if (value == 0) + if (pos >= size) + return SZ_ERROR_ARCHIVE; + if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) break; - if (value < 0x80) - continue; - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2; - if (value >= 0xDC00) - return SZ_ERROR_ARCHIVE; - if (pos + 2 > sd->Size) - return SZ_ERROR_ARCHIVE; - c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); - pos += 2; - if (c2 < 0xDC00 || c2 >= 0xE000) - return SZ_ERROR_ARCHIVE; - value = ((value - 0xD800) << 10) | (c2 - 0xDC00); - } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - len += numAdds; - } - - MY_ALLOC(char, file->Name, (size_t)len, alloc); - - len = 0; - while (2 <= sd->Size) - { - int numAdds; - UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); - SzSkeepDataSize(sd, 2); - if (value < 0x80) - { - file->Name[len++] = (char)value; - if (value == 0) - break; - continue; - } - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); - SzSkeepDataSize(sd, 2); - value = ((value - 0xD800) << 10) | (c2 - 0xDC00); - } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); - do - { - numAdds--; - file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); - } - while (numAdds > 0); - - len += numAdds; + pos++; } + pos++; } - return SZ_OK; + sizes[i] = pos; + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; } static SRes SzReadHeader2( @@ -920,7 +1000,8 @@ static SRes SzReadHeader2( if (type == k7zIdEnd) break; RINOK(SzReadNumber(sd, &size)); - + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; if ((UInt64)(int)type != type) { RINOK(SzSkeepDataSize(sd, size)); @@ -930,8 +1011,17 @@ static SRes SzReadHeader2( { case k7zIdName: { + size_t namesSize; RINOK(SzReadSwitch(sd)); - RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) + namesSize = (size_t)size - 1; + if ((namesSize & 1) != 0) + return SZ_ERROR_ARCHIVE; + if (!Buf_Create(&p->FileNames, namesSize, allocMain)) + return SZ_ERROR_MEM; + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); + memcpy(p->FileNames.data, sd->Data, namesSize); + RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) + RINOK(SzSkeepDataSize(sd, namesSize)); break; } case k7zIdEmptyStream: @@ -948,6 +1038,25 @@ static SRes SzReadHeader2( RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); break; } + case k7zIdWinAttributes: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + Byte defined = (*lwtVector)[i]; + f->AttribDefined = defined; + f->Attrib = 0; + if (defined) + { + RINOK(SzReadUInt32(sd, &f->Attrib)); + } + } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; + break; + } case k7zIdMTime: { RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); @@ -964,6 +1073,8 @@ static SRes SzReadHeader2( RINOK(SzReadUInt32(sd, &f->MTime.High)); } } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; break; } default: @@ -988,8 +1099,8 @@ static SRes SzReadHeader2( { file->IsDir = 0; file->Size = (*unpackSizes)[sizeIndex]; - file->FileCRC = (*digests)[sizeIndex]; - file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; + file->Crc = (*digests)[sizeIndex]; + file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex]; sizeIndex++; } else @@ -1000,7 +1111,8 @@ static SRes SzReadHeader2( file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); emptyFileIndex++; file->Size = 0; - file->FileCRCDefined = 0; + file->Crc = 0; + file->CrcDefined = 0; } } } @@ -1066,7 +1178,7 @@ static SRes SzReadAndDecodePackedStreams2( if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) return SZ_ERROR_MEM; - res = SzDecode(p->PackSizes, folder, + res = SzFolder_Decode(folder, p->PackSizes, inStream, dataStartPos, outBuffer->data, (size_t)unpackSize, allocTemp); RINOK(res); @@ -1106,12 +1218,16 @@ static SRes SzArEx_Open2( ISzAlloc *allocTemp) { Byte header[k7zStartHeaderSize]; + Int64 startArcPos; UInt64 nextHeaderOffset, nextHeaderSize; size_t nextHeaderSizeT; UInt32 nextHeaderCRC; CBuf buffer; SRes res; + startArcPos = 0; + RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); if (!TestSignatureCandidate(header)) @@ -1123,7 +1239,7 @@ static SRes SzArEx_Open2( nextHeaderSize = GetUi64(header + 20); nextHeaderCRC = GetUi32(header + 28); - p->startPosAfterHeader = k7zStartHeaderSize; + p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) return SZ_ERROR_CRC; @@ -1140,13 +1256,13 @@ static SRes SzArEx_Open2( { Int64 pos = 0; RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); - if ((UInt64)pos < nextHeaderOffset || - (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || - (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + if ((UInt64)pos < startArcPos + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) return SZ_ERROR_INPUT_EOF; } - RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); + RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) return SZ_ERROR_MEM; @@ -1202,3 +1318,85 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAl SzArEx_Free(p, allocMain); return res; } + +SRes SzArEx_Extract( + const CSzArEx *p, + ILookInStream *inStream, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; + SRes res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + IAlloc_Free(allocMain, *outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CSzFolder *folder = p->db.Folders + folderIndex; + UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); + size_t unpackSize = (size_t)unpackSizeSpec; + UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + IAlloc_Free(allocMain, *outBuffer); + *outBuffer = 0; + + RINOK(LookInStream_SeekTo(inStream, startOffset)); + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); + if (*outBuffer == 0) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SzFolder_Decode(folder, + p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], + inStream, startOffset, + *outBuffer, unpackSize, allocTemp); + if (res == SZ_OK) + { + if (folder->UnpackCRCDefined) + { + if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) + res = SZ_ERROR_CRC; + } + } + } + } + } + if (res == SZ_OK) + { + UInt32 i; + CSzFileItem *fileItem = p->db.Files + fileIndex; + *offset = 0; + for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)p->db.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) + res = SZ_ERROR_CRC; + } + return res; +} diff --git a/lzma/C/7zStream.c b/lzma/C/7zStream.c index a0a2405d0..f0959fb07 100644 --- a/lzma/C/7zStream.c +++ b/lzma/C/7zStream.c @@ -1,5 +1,5 @@ /* 7zStream.c -- 7z Stream functions -2008-11-23 : Igor Pavlov : Public domain */ +2010-03-11 : Igor Pavlov : Public domain */ #include @@ -39,7 +39,7 @@ SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) { - void *lookBuf; + const void *lookBuf; if (*size == 0) return SZ_OK; RINOK(stream->Look(stream, &lookBuf, size)); @@ -66,7 +66,7 @@ SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } -static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) +static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) { SRes res = SZ_OK; CLookToRead *p = (CLookToRead *)pp; @@ -84,7 +84,7 @@ static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) return res; } -static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) +static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) { SRes res = SZ_OK; CLookToRead *p = (CLookToRead *)pp; diff --git a/lzma/C/7zVersion.h b/lzma/C/7zVersion.h index 5a6bcadac..d4ac470e2 100644 --- a/lzma/C/7zVersion.h +++ b/lzma/C/7zVersion.h @@ -1,7 +1,7 @@ -#define MY_VER_MAJOR 4 -#define MY_VER_MINOR 65 +#define MY_VER_MAJOR 9 +#define MY_VER_MINOR 20 #define MY_VER_BUILD 0 -#define MY_VERSION "4.65" -#define MY_DATE "2009-02-03" +#define MY_VERSION "9.20" +#define MY_DATE "2010-11-18" #define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/lzma/C/Alloc.c b/lzma/C/Alloc.c deleted file mode 100644 index bb24a772b..000000000 --- a/lzma/C/Alloc.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Alloc.c -- Memory allocation functions -2008-09-24 -Igor Pavlov -Public domain */ - -#ifdef _WIN32 -#include -#endif -#include - -#include "Alloc.h" - -/* #define _SZ_ALLOC_DEBUG */ - -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ -#ifdef _SZ_ALLOC_DEBUG -#include -int g_allocCount = 0; -int g_allocCountMid = 0; -int g_allocCountBig = 0; -#endif - -void *MyAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - { - void *p = malloc(size); - fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); - return p; - } - #else - return malloc(size); - #endif -} - -void MyFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); - #endif - free(address); -} - -#ifdef _WIN32 - -void *MidAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); - #endif - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); -} - -void MidFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); - #endif - if (address == 0) - return; - VirtualFree(address, 0, MEM_RELEASE); -} - -#ifndef MEM_LARGE_PAGES -#undef _7ZIP_LARGE_PAGES -#endif - -#ifdef _7ZIP_LARGE_PAGES -SIZE_T g_LargePageSize = 0; -typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); -#endif - -void SetLargePageSize() -{ - #ifdef _7ZIP_LARGE_PAGES - SIZE_T size = 0; - GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) - GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); - if (largePageMinimum == 0) - return; - size = largePageMinimum(); - if (size == 0 || (size & (size - 1)) != 0) - return; - g_LargePageSize = size; - #endif -} - - -void *BigAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) - { - void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), - MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); - if (res != 0) - return res; - } - #endif - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); -} - -void BigFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); - #endif - - if (address == 0) - return; - VirtualFree(address, 0, MEM_RELEASE); -} - -#endif diff --git a/lzma/C/Alloc.h b/lzma/C/Alloc.h deleted file mode 100644 index a396c6b9e..000000000 --- a/lzma/C/Alloc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Alloc.h -- Memory allocation functions -2008-03-13 -Igor Pavlov -Public domain */ - -#ifndef __COMMON_ALLOC_H -#define __COMMON_ALLOC_H - -#include - -void *MyAlloc(size_t size); -void MyFree(void *address); - -#ifdef _WIN32 - -void SetLargePageSize(); - -void *MidAlloc(size_t size); -void MidFree(void *address); -void *BigAlloc(size_t size); -void BigFree(void *address); - -#else - -#define MidAlloc(size) MyAlloc(size) -#define MidFree(address) MyFree(address) -#define BigAlloc(size) MyAlloc(size) -#define BigFree(address) MyFree(address) - -#endif - -#endif diff --git a/lzma/C/Archive/7z/7zDecode.c b/lzma/C/Archive/7z/7zDecode.c deleted file mode 100644 index 097d2ea3c..000000000 --- a/lzma/C/Archive/7z/7zDecode.c +++ /dev/null @@ -1,254 +0,0 @@ -/* 7zDecode.c -- Decoding from 7z folder -2008-11-23 : Igor Pavlov : Public domain */ - -#include - -#include "../../Bcj2.h" -#include "../../Bra.h" -#include "../../LzmaDec.h" -#include "7zDecode.h" - -#define k_Copy 0 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_BCJ2 0x0303011B - -static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzmaDec state; - SRes res = SZ_OK; - - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); - state.dic = outBuffer; - state.dicBufSize = outSize; - LzmaDec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; - ELzmaStatus status; - res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) - { - if (state.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - LzmaDec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) -{ - while (inSize > 0) - { - void *inBuf; - size_t curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)inSize; - RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); - if (curSize == 0) - return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuf, curSize); - outBuffer += curSize; - inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); - } - return SZ_OK; -} - -#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) -#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) - -SRes CheckSupportedFolder(const CSzFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZ_ERROR_UNSUPPORTED; - if (IS_UNSUPPORTED_CODER(f->Coders[0])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 2) - { - if (IS_NO_BCJ(f->Coders[1]) || - f->NumPackStreams != 1 || f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (IS_UNSUPPORTED_CODER(f->Coders[1]) || - IS_UNSUPPORTED_CODER(f->Coders[2]) || - IS_NO_BCJ2(f->Coders[3])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - return SZ_ERROR_UNSUPPORTED; -} - -UInt64 GetSum(const UInt64 *values, UInt32 index) -{ - UInt64 sum = 0; - UInt32 i; - for (i = 0; i < index; i++) - sum += values[i]; - return sum; -} - -SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, - Byte *tempBuf[]) -{ - UInt32 ci; - SizeT tempSizes[3] = { 0, 0, 0}; - SizeT tempSize3 = 0; - Byte *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - CSzCoderInfo *coder = &folder->Coders[ci]; - - if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) - { - UInt32 si = 0; - UInt64 offset; - UInt64 inSize; - Byte *outBufCur = outBuffer; - SizeT outSizeCur = outSize; - if (folder->NumCoders == 4) - { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = folder->UnpackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - Byte *temp; - outSizeCur = (SizeT)unpackSize; - if (outSizeCur != unpackSize) - return SZ_ERROR_MEM; - temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZ_ERROR_MEM; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) /* check it */ - return SZ_ERROR_PARAM; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (SizeT)unpackSize; - } - else - return SZ_ERROR_UNSUPPORTED; - } - offset = GetSum(packSizes, si); - inSize = packSizes[si]; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) /* check it */ - return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - } - else - { - RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - } - else if (coder->MethodID == k_BCJ) - { - UInt32 state; - if (ci != 1) - return SZ_ERROR_UNSUPPORTED; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - } - else if (coder->MethodID == k_BCJ2) - { - UInt64 offset = GetSum(packSizes, 1); - UInt64 s3Size = packSizes[1]; - SRes res; - if (ci != 3) - return SZ_ERROR_UNSUPPORTED; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - tempSizes[2] = (SizeT)s3Size; - if (tempSizes[2] != s3Size) - return SZ_ERROR_MEM; - tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZ_ERROR_MEM; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) - } - else - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; -} - -SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - Byte *tempBuf[3] = { 0, 0, 0}; - int i; - SRes res = SzDecode2(packSizes, folder, inStream, startPos, - outBuffer, (SizeT)outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); - return res; -} diff --git a/lzma/C/Archive/7z/7zDecode.h b/lzma/C/Archive/7z/7zDecode.h deleted file mode 100644 index 9607915bf..000000000 --- a/lzma/C/Archive/7z/7zDecode.h +++ /dev/null @@ -1,13 +0,0 @@ -/* 7zDecode.h -- Decoding from 7z folder -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_DECODE_H -#define __7Z_DECODE_H - -#include "7zItem.h" - -SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *stream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); - -#endif diff --git a/lzma/C/Archive/7z/7zExtract.c b/lzma/C/Archive/7z/7zExtract.c deleted file mode 100644 index 0f957add1..000000000 --- a/lzma/C/Archive/7z/7zExtract.c +++ /dev/null @@ -1,93 +0,0 @@ -/* 7zExtract.c -- Extracting from 7z archive -2008-11-23 : Igor Pavlov : Public domain */ - -#include "../../7zCrc.h" -#include "7zDecode.h" -#include "7zExtract.h" - -SRes SzAr_Extract( - const CSzArEx *p, - ILookInStream *inStream, - UInt32 fileIndex, - UInt32 *blockIndex, - Byte **outBuffer, - size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; - SRes res = SZ_OK; - *offset = 0; - *outSizeProcessed = 0; - if (folderIndex == (UInt32)-1) - { - IAlloc_Free(allocMain, *outBuffer); - *blockIndex = folderIndex; - *outBuffer = 0; - *outBufferSize = 0; - return SZ_OK; - } - - if (*outBuffer == 0 || *blockIndex != folderIndex) - { - CSzFolder *folder = p->db.Folders + folderIndex; - UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); - size_t unpackSize = (size_t)unpackSizeSpec; - UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); - - if (unpackSize != unpackSizeSpec) - return SZ_ERROR_MEM; - *blockIndex = folderIndex; - IAlloc_Free(allocMain, *outBuffer); - *outBuffer = 0; - - RINOK(LookInStream_SeekTo(inStream, startOffset)); - - if (res == SZ_OK) - { - *outBufferSize = unpackSize; - if (unpackSize != 0) - { - *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); - if (*outBuffer == 0) - res = SZ_ERROR_MEM; - } - if (res == SZ_OK) - { - res = SzDecode(p->db.PackSizes + - p->FolderStartPackStreamIndex[folderIndex], folder, - inStream, startOffset, - *outBuffer, unpackSize, allocTemp); - if (res == SZ_OK) - { - if (folder->UnpackCRCDefined) - { - if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) - res = SZ_ERROR_CRC; - } - } - } - } - } - if (res == SZ_OK) - { - UInt32 i; - CSzFileItem *fileItem = p->db.Files + fileIndex; - *offset = 0; - for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) - *offset += (UInt32)p->db.Files[i].Size; - *outSizeProcessed = (size_t)fileItem->Size; - if (*offset + *outSizeProcessed > *outBufferSize) - return SZ_ERROR_FAIL; - { - if (fileItem->FileCRCDefined) - { - if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) - res = SZ_ERROR_CRC; - } - } - } - return res; -} diff --git a/lzma/C/Archive/7z/7zExtract.h b/lzma/C/Archive/7z/7zExtract.h deleted file mode 100644 index e171f4ab8..000000000 --- a/lzma/C/Archive/7z/7zExtract.h +++ /dev/null @@ -1,41 +0,0 @@ -/* 7zExtract.h -- Extracting from 7z archive -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_EXTRACT_H -#define __7Z_EXTRACT_H - -#include "7zIn.h" - -/* - SzExtract extracts file from archive - - *outBuffer must be 0 before first call for each new archive. - - Extracting cache: - If you need to decompress more than one file, you can send - these values from previous call: - *blockIndex, - *outBuffer, - *outBufferSize - You can consider "*outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - If you use external function, you can declare these 3 cache variables - (blockIndex, outBuffer, outBufferSize) as static in that external function. - - Free *outBuffer and set *outBuffer to 0, if you want to flush cache. -*/ - -SRes SzAr_Extract( - const CSzArEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - -#endif diff --git a/lzma/C/Archive/7z/7zHeader.c b/lzma/C/Archive/7z/7zHeader.c deleted file mode 100644 index c44ff4a48..000000000 --- a/lzma/C/Archive/7z/7zHeader.c +++ /dev/null @@ -1,6 +0,0 @@ -/* 7zHeader.c -- 7z Headers -2008-10-04 : Igor Pavlov : Public domain */ - -#include "7zHeader.h" - -Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; diff --git a/lzma/C/Archive/7z/7zHeader.h b/lzma/C/Archive/7z/7zHeader.h deleted file mode 100644 index 1ef8c0196..000000000 --- a/lzma/C/Archive/7z/7zHeader.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 7zHeader.h -- 7z Headers -2008-10-04 : Igor Pavlov : Public domain */ - -#ifndef __7Z_HEADER_H -#define __7Z_HEADER_H - -#include "../../Types.h" - -#define k7zSignatureSize 6 -extern Byte k7zSignature[k7zSignatureSize]; - -#define k7zMajorVersion 0 - -#define k7zStartHeaderSize 0x20 - -enum EIdEnum -{ - k7zIdEnd, - - k7zIdHeader, - - k7zIdArchiveProperties, - - k7zIdAdditionalStreamsInfo, - k7zIdMainStreamsInfo, - k7zIdFilesInfo, - - k7zIdPackInfo, - k7zIdUnpackInfo, - k7zIdSubStreamsInfo, - - k7zIdSize, - k7zIdCRC, - - k7zIdFolder, - - k7zIdCodersUnpackSize, - k7zIdNumUnpackStream, - - k7zIdEmptyStream, - k7zIdEmptyFile, - k7zIdAnti, - - k7zIdName, - k7zIdCTime, - k7zIdATime, - k7zIdMTime, - k7zIdWinAttributes, - k7zIdComment, - - k7zIdEncodedHeader, - - k7zIdStartPos, - k7zIdDummy -}; - -#endif diff --git a/lzma/C/Archive/7z/7zIn.h b/lzma/C/Archive/7z/7zIn.h deleted file mode 100644 index 717fe52c9..000000000 --- a/lzma/C/Archive/7z/7zIn.h +++ /dev/null @@ -1,41 +0,0 @@ -/* 7zIn.h -- 7z Input functions -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_IN_H -#define __7Z_IN_H - -#include "7zHeader.h" -#include "7zItem.h" - -typedef struct -{ - CSzAr db; - - UInt64 startPosAfterHeader; - UInt64 dataPos; - - UInt32 *FolderStartPackStreamIndex; - UInt64 *PackStreamStartPositions; - UInt32 *FolderStartFileIndex; - UInt32 *FileIndexToFolderIndexMap; -} CSzArEx; - -void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); - -/* -Errors: -SZ_ERROR_NO_ARCHIVE -SZ_ERROR_ARCHIVE -SZ_ERROR_UNSUPPORTED -SZ_ERROR_MEM -SZ_ERROR_CRC -SZ_ERROR_INPUT_EOF -SZ_ERROR_FAIL -*/ - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); - -#endif diff --git a/lzma/C/Archive/7z/7zItem.c b/lzma/C/Archive/7z/7zItem.c deleted file mode 100644 index a11d5008f..000000000 --- a/lzma/C/Archive/7z/7zItem.c +++ /dev/null @@ -1,127 +0,0 @@ -/* 7zItem.c -- 7z Items -2008-10-04 : Igor Pavlov : Public domain */ - -#include "7zItem.h" - -void SzCoderInfo_Init(CSzCoderInfo *p) -{ - Buf_Init(&p->Props); -} - -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) -{ - Buf_Free(&p->Props, alloc); - SzCoderInfo_Init(p); -} - -void SzFolder_Init(CSzFolder *p) -{ - p->Coders = 0; - p->BindPairs = 0; - p->PackStreams = 0; - p->UnpackSizes = 0; - p->NumCoders = 0; - p->NumBindPairs = 0; - p->NumPackStreams = 0; - p->UnpackCRCDefined = 0; - p->UnpackCRC = 0; - p->NumUnpackStreams = 0; -} - -void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Coders) - for (i = 0; i < p->NumCoders; i++) - SzCoderInfo_Free(&p->Coders[i], alloc); - IAlloc_Free(alloc, p->Coders); - IAlloc_Free(alloc, p->BindPairs); - IAlloc_Free(alloc, p->PackStreams); - IAlloc_Free(alloc, p->UnpackSizes); - SzFolder_Init(p); -} - -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) -{ - UInt32 result = 0; - UInt32 i; - for (i = 0; i < p->NumCoders; i++) - result += p->Coders[i].NumOutStreams; - return result; -} - -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].InIndex == inStreamIndex) - return i; - return -1; -} - - -int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].OutIndex == outStreamIndex) - return i; - return -1; -} - -UInt64 SzFolder_GetUnpackSize(CSzFolder *p) -{ - int i = (int)SzFolder_GetNumOutStreams(p); - if (i == 0) - return 0; - for (i--; i >= 0; i--) - if (SzFolder_FindBindPairForOutStream(p, i) < 0) - return p->UnpackSizes[i]; - /* throw 1; */ - return 0; -} - -void SzFile_Init(CSzFileItem *p) -{ - p->HasStream = 1; - p->IsDir = 0; - p->IsAnti = 0; - p->FileCRCDefined = 0; - p->MTimeDefined = 0; - p->Name = 0; -} - -static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->Name); - SzFile_Init(p); -} - -void SzAr_Init(CSzAr *p) -{ - p->PackSizes = 0; - p->PackCRCsDefined = 0; - p->PackCRCs = 0; - p->Folders = 0; - p->Files = 0; - p->NumPackStreams = 0; - p->NumFolders = 0; - p->NumFiles = 0; -} - -void SzAr_Free(CSzAr *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Folders) - for (i = 0; i < p->NumFolders; i++) - SzFolder_Free(&p->Folders[i], alloc); - if (p->Files) - for (i = 0; i < p->NumFiles; i++) - SzFile_Free(&p->Files[i], alloc); - IAlloc_Free(alloc, p->PackSizes); - IAlloc_Free(alloc, p->PackCRCsDefined); - IAlloc_Free(alloc, p->PackCRCs); - IAlloc_Free(alloc, p->Folders); - IAlloc_Free(alloc, p->Files); - SzAr_Init(p); -} diff --git a/lzma/C/Archive/7z/7zItem.h b/lzma/C/Archive/7z/7zItem.h deleted file mode 100644 index 190b2e2a9..000000000 --- a/lzma/C/Archive/7z/7zItem.h +++ /dev/null @@ -1,84 +0,0 @@ -/* 7zItem.h -- 7z Items -2008-10-04 : Igor Pavlov : Public domain */ - -#ifndef __7Z_ITEM_H -#define __7Z_ITEM_H - -#include "../../7zBuf.h" - -typedef struct -{ - UInt32 NumInStreams; - UInt32 NumOutStreams; - UInt64 MethodID; - CBuf Props; -} CSzCoderInfo; - -void SzCoderInfo_Init(CSzCoderInfo *p); -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); - -typedef struct -{ - UInt32 InIndex; - UInt32 OutIndex; -} CBindPair; - -typedef struct -{ - CSzCoderInfo *Coders; - CBindPair *BindPairs; - UInt32 *PackStreams; - UInt64 *UnpackSizes; - UInt32 NumCoders; - UInt32 NumBindPairs; - UInt32 NumPackStreams; - int UnpackCRCDefined; - UInt32 UnpackCRC; - - UInt32 NumUnpackStreams; -} CSzFolder; - -void SzFolder_Init(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); - -typedef struct CNtfsFileTime -{ - UInt32 Low; - UInt32 High; -} CNtfsFileTime; - -typedef struct CSzFileItem -{ - CNtfsFileTime MTime; - UInt64 Size; - char *Name; - UInt32 FileCRC; - - Byte HasStream; - Byte IsDir; - Byte IsAnti; - Byte FileCRCDefined; - Byte MTimeDefined; -} CSzFileItem; - -void SzFile_Init(CSzFileItem *p); - -typedef struct CSzAr -{ - UInt64 *PackSizes; - Byte *PackCRCsDefined; - UInt32 *PackCRCs; - CSzFolder *Folders; - CSzFileItem *Files; - UInt32 NumPackStreams; - UInt32 NumFolders; - UInt32 NumFiles; -} CSzAr; - -void SzAr_Init(CSzAr *p); -void SzAr_Free(CSzAr *p, ISzAlloc *alloc); - -#endif diff --git a/lzma/C/Bcj2.h b/lzma/C/Bcj2.h index f58e3bcb4..d9d857bc3 100644 --- a/lzma/C/Bcj2.h +++ b/lzma/C/Bcj2.h @@ -1,11 +1,15 @@ /* Bcj2.h -- Converter for x86 code (BCJ2) -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ #ifndef __BCJ2_H #define __BCJ2_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Conditions: outSize <= FullOutputSize, @@ -27,4 +31,8 @@ int Bcj2_Decode( const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/Bra.c b/lzma/C/Bra.c new file mode 100644 index 000000000..2a0f147b2 --- /dev/null +++ b/lzma/C/Bra.c @@ -0,0 +1,133 @@ +/* Bra.c -- Converters for RISC code +2010-04-16 : Igor Pavlov : Public domain */ + +#include "Bra.h" + +SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 8; + for (i = 0; i <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + UInt32 dest; + UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 2; + data[i + 2] = (Byte)(dest >> 16); + data[i + 1] = (Byte)(dest >> 8); + data[i + 0] = (Byte)dest; + } + } + return i; +} + +SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + ip += 4; + for (i = 0; i <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + UInt32 dest; + UInt32 src = + (((UInt32)data[i + 1] & 0x7) << 19) | + ((UInt32)data[i + 0] << 11) | + (((UInt32)data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + dest >>= 1; + + data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); + data[i + 0] = (Byte)(dest >> 11); + data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); + data[i + 2] = (Byte)dest; + i += 2; + } + } + return i; +} + +SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + SizeT i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + { + UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3] & (~3)); + + UInt32 dest; + if (encoding) + dest = ip + (UInt32)i + src; + else + dest = src - (ip + (UInt32)i); + data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} + +SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +{ + UInt32 i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || + (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) + { + UInt32 src = + ((UInt32)data[i + 0] << 24) | + ((UInt32)data[i + 1] << 16) | + ((UInt32)data[i + 2] << 8) | + ((UInt32)data[i + 3]); + UInt32 dest; + + src <<= 2; + if (encoding) + dest = ip + i + src; + else + dest = src - (ip + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (Byte)(dest >> 24); + data[i + 1] = (Byte)(dest >> 16); + data[i + 2] = (Byte)(dest >> 8); + data[i + 3] = (Byte)dest; + } + } + return i; +} diff --git a/lzma/C/Bra.h b/lzma/C/Bra.h index b9018eb99..9c91e332d 100644 --- a/lzma/C/Bra.h +++ b/lzma/C/Bra.h @@ -1,11 +1,15 @@ /* Bra.h -- Branch converters for executables -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ #ifndef __BRA_H #define __BRA_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + /* These functions convert relative addresses to absolute addresses in CALL instructions to increase the compression ratio. @@ -57,4 +61,8 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c new file mode 100644 index 000000000..36e7680d9 --- /dev/null +++ b/lzma/C/CpuArch.c @@ -0,0 +1,168 @@ +/* CpuArch.c -- CPU specific code +2010-10-26: Igor Pavlov : Public domain */ + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + +#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) +#define USE_ASM +#endif + +#if defined(USE_ASM) && !defined(MY_CPU_AMD64) +static UInt32 CheckFlag(UInt32 flag) +{ + #ifdef _MSC_VER + __asm pushfd; + __asm pop EAX; + __asm mov EDX, EAX; + __asm xor EAX, flag; + __asm push EAX; + __asm popfd; + __asm pushfd; + __asm pop EAX; + __asm xor EAX, EDX; + __asm push EDX; + __asm popfd; + __asm and flag, EAX; + #else + __asm__ __volatile__ ( + "pushf\n\t" + "pop %%EAX\n\t" + "movl %%EAX,%%EDX\n\t" + "xorl %0,%%EAX\n\t" + "push %%EAX\n\t" + "popf\n\t" + "pushf\n\t" + "pop %%EAX\n\t" + "xorl %%EDX,%%EAX\n\t" + "push %%EDX\n\t" + "popf\n\t" + "andl %%EAX, %0\n\t": + "=c" (flag) : "c" (flag)); + #endif + return flag; +} +#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif + +static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) +{ + #ifdef USE_ASM + + #ifdef _MSC_VER + + UInt32 a2, b2, c2, d2; + __asm xor EBX, EBX; + __asm xor ECX, ECX; + __asm xor EDX, EDX; + __asm mov EAX, function; + __asm cpuid; + __asm mov a2, EAX; + __asm mov b2, EBX; + __asm mov c2, ECX; + __asm mov d2, EDX; + + *a = a2; + *b = b2; + *c = c2; + *d = d2; + + #else + + __asm__ __volatile__ ( + "cpuid" + : "=a" (*a) , + "=b" (*b) , + "=c" (*c) , + "=d" (*d) + : "0" (function)) ; + + #endif + + #else + + int CPUInfo[4]; + __cpuid(CPUInfo, function); + *a = CPUInfo[0]; + *b = CPUInfo[1]; + *c = CPUInfo[2]; + *d = CPUInfo[3]; + + #endif +} + +Bool x86cpuid_CheckAndRead(Cx86cpuid *p) +{ + CHECK_CPUID_IS_SUPPORTED + MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); + MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); + return True; +} + +static UInt32 kVendors[][3] = +{ + { 0x756E6547, 0x49656E69, 0x6C65746E}, + { 0x68747541, 0x69746E65, 0x444D4163}, + { 0x746E6543, 0x48727561, 0x736C7561} +}; + +int x86cpuid_GetFirm(const Cx86cpuid *p) +{ + unsigned i; + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) + { + const UInt32 *v = kVendors[i]; + if (v[0] == p->vendor[0] && + v[1] == p->vendor[1] && + v[2] == p->vendor[2]) + return (int)i; + } + return -1; +} + +Bool CPU_Is_InOrder() +{ + Cx86cpuid p; + int firm; + UInt32 family, model; + if (!x86cpuid_CheckAndRead(&p)) + return True; + family = x86cpuid_GetFamily(&p); + model = x86cpuid_GetModel(&p); + firm = x86cpuid_GetFirm(&p); + switch (firm) + { + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C)); + case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); + case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); + } + return True; +} + +#if !defined(MY_CPU_AMD64) && defined(_WIN32) +static Bool CPU_Sys_Is_SSE_Supported() +{ + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (!GetVersionEx(&vi)) + return False; + return (vi.dwMajorVersion >= 5); +} +#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; +#else +#define CHECK_SYS_SSE_SUPPORT +#endif + +Bool CPU_Is_Aes_Supported() +{ + Cx86cpuid p; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_CheckAndRead(&p)) + return False; + return (p.c >> 25) & 1; +} + +#endif diff --git a/lzma/C/CpuArch.h b/lzma/C/CpuArch.h index db441641b..0a709bb26 100644 --- a/lzma/C/CpuArch.h +++ b/lzma/C/CpuArch.h @@ -1,29 +1,73 @@ -/* CpuArch.h -2008-08-05 -Igor Pavlov -Public domain */ +/* CpuArch.h -- CPU specific code +2010-10-26: Igor Pavlov : Public domain */ -#ifndef __CPUARCH_H -#define __CPUARCH_H +#ifndef __CPU_ARCH_H +#define __CPU_ARCH_H + +#include "Types.h" + +EXTERN_C_BEGIN /* -LITTLE_ENDIAN_UNALIGN means: - 1) CPU is LITTLE_ENDIAN - 2) it's allowed to make unaligned memory accesses -if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know -about these properties of platform. +MY_CPU_LE means that CPU is LITTLE ENDIAN. +If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). + +MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. +If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. */ -#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) -#define LITTLE_ENDIAN_UNALIGN +#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) +#define MY_CPU_AMD64 #endif -#ifdef LITTLE_ENDIAN_UNALIGN +#if defined(MY_CPU_AMD64) || defined(_M_IA64) +#define MY_CPU_64BIT +#endif + +#if defined(_M_IX86) || defined(__i386__) +#define MY_CPU_X86 +#endif + +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) +#define MY_CPU_X86_OR_AMD64 +#endif + +#if defined(MY_CPU_X86) || defined(_M_ARM) +#define MY_CPU_32BIT +#endif + +#if defined(_WIN32) && defined(_M_ARM) +#define MY_CPU_ARM_LE +#endif + +#if defined(_WIN32) && defined(_M_IA64) +#define MY_CPU_IA64_LE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) +#define MY_CPU_LE_UNALIGN +#endif + +#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) +#define MY_CPU_LE +#endif + +#if defined(__BIG_ENDIAN__) +#define MY_CPU_BE +#endif + +#if defined(MY_CPU_LE) && defined(MY_CPU_BE) +Stop_Compiling_Bad_Endian +#endif + +#ifdef MY_CPU_LE_UNALIGN #define GetUi16(p) (*(const UInt16 *)(p)) #define GetUi32(p) (*(const UInt32 *)(p)) #define GetUi64(p) (*(const UInt64 *)(p)) +#define SetUi16(p, d) *(UInt16 *)(p) = (d); #define SetUi32(p, d) *(UInt32 *)(p) = (d); +#define SetUi64(p, d) *(UInt64 *)(p) = (d); #else @@ -37,18 +81,24 @@ about these properties of platform. #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#define SetUi16(p, d) { UInt32 _x_ = (d); \ + ((Byte *)(p))[0] = (Byte)_x_; \ + ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } + #define SetUi32(p, d) { UInt32 _x_ = (d); \ ((Byte *)(p))[0] = (Byte)_x_; \ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } +#define SetUi64(p, d) { UInt64 _x64_ = (d); \ + SetUi32(p, (UInt32)_x64_); \ + SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } + #endif -#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) +#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) -unsigned long _byteswap_ulong(unsigned long); -unsigned __int64 _byteswap_uint64(unsigned __int64); #pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_uint64) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) @@ -68,4 +118,38 @@ unsigned __int64 _byteswap_uint64(unsigned __int64); #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) + +#ifdef MY_CPU_X86_OR_AMD64 + +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; + +Bool x86cpuid_CheckAndRead(Cx86cpuid *p); +int x86cpuid_GetFirm(const Cx86cpuid *p); + +#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) +#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) +#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) + +Bool CPU_Is_InOrder(); +Bool CPU_Is_Aes_Supported(); + +#endif + +EXTERN_C_END + #endif diff --git a/lzma/C/LzFind.c b/lzma/C/LzFind.c index e0ebe6235..f6c9e66d5 100644 --- a/lzma/C/LzFind.c +++ b/lzma/C/LzFind.c @@ -1,5 +1,5 @@ /* LzFind.c -- Match finder for LZ algorithms -2008-10-04 : Igor Pavlov : Public domain */ +2009-04-22 : Igor Pavlov : Public domain */ #include @@ -58,6 +58,17 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) { if (p->streamEndWasReached || p->result != SZ_OK) return; + if (p->directInput) + { + UInt32 curSize = 0xFFFFFFFF - p->streamPos; + if (curSize > p->directInputRem) + curSize = (UInt32)p->directInputRem; + p->directInputRem -= curSize; + p->streamPos += curSize; + if (p->directInputRem == 0) + p->streamEndWasReached = 1; + return; + } for (;;) { Byte *dest = p->buffer + (p->streamPos - p->pos); @@ -88,6 +99,8 @@ void MatchFinder_MoveBlock(CMatchFinder *p) int MatchFinder_NeedMove(CMatchFinder *p) { + if (p->directInput) + return 0; /* if (p->streamEndWasReached) return 0; */ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); } @@ -112,8 +125,6 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) p->cutValue = 32; p->btMode = 1; p->numHashBytes = 4; - /* p->skipModeBits = 0; */ - p->directInput = 0; p->bigHash = 0; } @@ -177,7 +188,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ if (LzInWindow_Create(p, sizeReserv, alloc)) { - UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1; + UInt32 newCyclicBufferSize = historySize + 1; UInt32 hs; p->matchMaxLen = matchMaxLen; { @@ -192,7 +203,6 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, hs |= (hs >> 4); hs |= (hs >> 8); hs >>= 1; - /* hs >>= p->skipModeBits; */ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ if (hs > (1 << 24)) { diff --git a/lzma/C/LzFind.h b/lzma/C/LzFind.h index 423d67e0c..7ebdfa446 100644 --- a/lzma/C/LzFind.h +++ b/lzma/C/LzFind.h @@ -1,11 +1,15 @@ /* LzFind.h -- Match finder for LZ algorithms -2008-10-04 : Igor Pavlov : Public domain */ +2009-04-22 : Igor Pavlov : Public domain */ -#ifndef __LZFIND_H -#define __LZFIND_H +#ifndef __LZ_FIND_H +#define __LZ_FIND_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef UInt32 CLzRef; typedef struct _CMatchFinder @@ -35,8 +39,8 @@ typedef struct _CMatchFinder UInt32 numHashBytes; int directInput; + size_t directInputRem; int btMode; - /* int skipModeBits; */ int bigHash; UInt32 historySize; UInt32 fixedHashSize; @@ -104,4 +108,8 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/LzFindMt.c b/lzma/C/LzFindMt.c index a67899ab0..db95590c3 100644 --- a/lzma/C/LzFindMt.c +++ b/lzma/C/LzFindMt.c @@ -1,5 +1,5 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2008-10-04 : Igor Pavlov : Public domain */ +2009-09-20 : Igor Pavlov : Public domain */ #include "LzHash.h" @@ -97,7 +97,7 @@ void MtSync_Destruct(CMtSync *p) #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } -static SRes MtSync_Create2(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *obj, UInt32 numBlocks) +static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) { if (p->wasCreated) return SZ_OK; @@ -119,7 +119,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAdd return SZ_OK; } -static SRes MtSync_Create(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *obj, UInt32 numBlocks) +static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) { SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); if (res != SZ_OK) @@ -143,7 +143,7 @@ DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) -DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) +/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ void HashThreadFunc(CMatchFinderMt *mt) { @@ -451,8 +451,8 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) #define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) #define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) -static unsigned THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } -static unsigned THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) +static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } +static unsigned MY_STD_CALL BtThreadFunc2(void *p) { Byte allocaDummy[0x180]; int i = 0; @@ -711,47 +711,47 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) return len; } -#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED -#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; -#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); +#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED +#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; +#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) { - SKIP_HEADER2 { p->btNumAvailBytes--; - SKIP_FOOTER + SKIP_HEADER2_MT { p->btNumAvailBytes--; + SKIP_FOOTER_MT } void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) { - SKIP_HEADER(2) + SKIP_HEADER_MT(2) UInt32 hash2Value; MT_HASH2_CALC hash[hash2Value] = p->lzPos; - SKIP_FOOTER + SKIP_FOOTER_MT } void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) { - SKIP_HEADER(3) + SKIP_HEADER_MT(3) UInt32 hash2Value, hash3Value; MT_HASH3_CALC hash[kFix3HashSize + hash3Value] = hash[ hash2Value] = p->lzPos; - SKIP_FOOTER + SKIP_FOOTER_MT } /* void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) { - SKIP_HEADER(4) + SKIP_HEADER_MT(4) UInt32 hash2Value, hash3Value, hash4Value; MT_HASH4_CALC hash[kFix4HashSize + hash4Value] = hash[kFix3HashSize + hash3Value] = hash[ hash2Value] = p->lzPos; - SKIP_FOOTER + SKIP_FOOTER_MT } */ diff --git a/lzma/C/LzFindMt.h b/lzma/C/LzFindMt.h index b7ead2d47..17ed237d6 100644 --- a/lzma/C/LzFindMt.h +++ b/lzma/C/LzFindMt.h @@ -1,11 +1,15 @@ /* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ -#ifndef __LZFINDMT_H -#define __LZFINDMT_H +#ifndef __LZ_FIND_MT_H +#define __LZ_FIND_MT_H -#include "Threads.h" #include "LzFind.h" +#include "Threads.h" + +#ifdef __cplusplus +extern "C" { +#endif #define kMtHashBlockSize (1 << 13) #define kMtHashNumBlocks (1 << 3) @@ -94,4 +98,8 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/LzHash.h b/lzma/C/LzHash.h index c92341750..b2f0e3c24 100644 --- a/lzma/C/LzHash.h +++ b/lzma/C/LzHash.h @@ -1,8 +1,8 @@ /* LzHash.h -- HASH functions for LZ algorithms -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ -#ifndef __LZHASH_H -#define __LZHASH_H +#ifndef __LZ_HASH_H +#define __LZ_HASH_H #define kHash2Size (1 << 10) #define kHash3Size (1 << 16) diff --git a/lzma/C/Lzma2Dec.c b/lzma/C/Lzma2Dec.c new file mode 100644 index 000000000..8f2406755 --- /dev/null +++ b/lzma/C/Lzma2Dec.c @@ -0,0 +1,356 @@ +/* Lzma2Dec.c -- LZMA2 Decoder +2009-05-03 : Igor Pavlov : Public domain */ + +/* #define SHOW_DEBUG_INFO */ + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include + +#include "Lzma2Dec.h" + +/* +00000000 - EOS +00000001 U U - Uncompressed Reset Dic +00000010 U U - Uncompressed No Reset +100uuuuu U U P P - LZMA no reset +101uuuuu U U P P - LZMA reset state +110uuuuu U U P P S - LZMA reset state + new prop +111uuuuu U U P P S - LZMA reset state + new prop + reset dic + + u, U - Unpack Size + P - Pack Size + S - Props +*/ + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) + +#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) +#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +typedef enum +{ + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) +{ + UInt32 dicSize; + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (Byte)LZMA2_LCLP_MAX; + props[1] = (Byte)(dicSize); + props[2] = (Byte)(dicSize >> 8); + props[3] = (Byte)(dicSize >> 16); + props[4] = (Byte)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitDic = True; + p->needInitState = True; + p->needInitProp = True; + LzmaDec_Init(&p->decoder); +} + +static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) +{ + switch(p->state) + { + case LZMA2_STATE_CONTROL: + p->control = b; + PRF(printf("\n %4X ", p->decoder.dicPos)); + PRF(printf(" %2X", b)); + if (p->control == 0) + return LZMA2_STATE_FINISHED; + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if ((p->control & 0x7F) > 2) + return LZMA2_STATE_ERROR; + p->unpackSize = 0; + } + else + p->unpackSize = (UInt32)(p->control & 0x1F) << 16; + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (UInt32)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (UInt32)b; + p->unpackSize++; + PRF(printf(" %8d", p->unpackSize)); + return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (UInt32)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (UInt32)b; + p->packSize++; + PRF(printf(" %8d", p->packSize)); + return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: + (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); + + case LZMA2_STATE_PROP: + { + int lc, lp; + if (b >= (9 * 5 * 5)) + return LZMA2_STATE_ERROR; + lc = b % 9; + b /= 9; + p->decoder.prop.pb = b / 5; + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) + return LZMA2_STATE_ERROR; + p->decoder.prop.lc = lc; + p->decoder.prop.lp = lp; + p->needInitProp = False; + return LZMA2_STATE_DATA; + } + } + return LZMA2_STATE_ERROR; +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) + p->checkDicSize = p->prop.dicSize; + p->processedPos += (UInt32)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_FINISHED) + { + SizeT dicPos = p->decoder.dicPos; + if (p->state == LZMA2_STATE_ERROR) + return SZ_ERROR_DATA; + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + continue; + } + { + SizeT destSizeCur = dicLimit - dicPos; + SizeT srcSizeCur = inSize - *srcLen; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (p->unpackSize <= destSizeCur) + { + destSizeCur = (SizeT)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) + { + Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + if (initDic) + p->needInitProp = p->needInitState = True; + else if (p->needInitDic) + return SZ_ERROR_DATA; + p->needInitDic = False; + LzmaDec_InitDicAndState(&p->decoder, initDic, False); + } + + if (srcSizeCur > destSizeCur) + srcSizeCur = destSizeCur; + + if (srcSizeCur == 0) + return SZ_ERROR_DATA; + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->unpackSize -= (UInt32)srcSizeCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + SizeT outSizeProcessed; + SRes res; + + if (p->state == LZMA2_STATE_DATA) + { + int mode = LZMA2_GET_LZMA_MODE(p); + Bool initDic = (mode == 3); + Bool initState = (mode > 0); + if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) + return SZ_ERROR_DATA; + + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->needInitDic = False; + p->needInitState = False; + p->state = LZMA2_STATE_DATA_CONT; + } + if (srcSizeCur > p->packSize) + srcSizeCur = (SizeT)p->packSize; + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->packSize -= (UInt32)srcSizeCur; + + outSizeProcessed = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outSizeProcessed; + + RINOK(res); + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) + return res; + + if (srcSizeCur == 0 && outSizeProcessed == 0) + { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || + p->unpackSize != 0 || p->packSize != 0) + return SZ_ERROR_DATA; + p->state = LZMA2_STATE_CONTROL; + } + if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + *status = LZMA_STATUS_NOT_FINISHED; + } + } + } + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; +} + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT srcSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->decoder.dicPos == p->decoder.dicBufSize) + p->decoder.dicPos = 0; + dicPos = p->decoder.dicPos; + if (outSize > p->decoder.dicBufSize - dicPos) + { + outSizeCur = p->decoder.dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); + src += srcSizeCur; + inSize -= srcSizeCur; + *srcLen += srcSizeCur; + outSizeCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzma2Dec decoder; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + Byte props[LZMA_PROPS_SIZE]; + + Lzma2Dec_Construct(&decoder); + + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + decoder.decoder.dic = dest; + decoder.decoder.dicBufSize = outSize; + + RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); + + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); + *destLen = decoder.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + LzmaDec_FreeProbs(&decoder.decoder, alloc); + return res; +} diff --git a/lzma/C/Lzma2Dec.h b/lzma/C/Lzma2Dec.h new file mode 100644 index 000000000..827698dee --- /dev/null +++ b/lzma/C/Lzma2Dec.h @@ -0,0 +1,84 @@ +/* Lzma2Dec.h -- LZMA2 Decoder +2009-05-03 : Igor Pavlov : Public domain */ + +#ifndef __LZMA2_DEC_H +#define __LZMA2_DEC_H + +#include "LzmaDec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- State Interface ---------- */ + +typedef struct +{ + CLzmaDec decoder; + UInt32 packSize; + UInt32 unpackSize; + int state; + Byte control; + Bool needInitDic; + Bool needInitState; + Bool needInitProp; +} CLzma2Dec; + +#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lzma/C/LzmaDec.c b/lzma/C/LzmaDec.c index eb5250174..4fdc11d4b 100644 --- a/lzma/C/LzmaDec.c +++ b/lzma/C/LzmaDec.c @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2008-11-06 : Igor Pavlov : Public domain */ +2009-09-20 : Igor Pavlov : Public domain */ #include "LzmaDec.h" @@ -113,12 +113,6 @@ StopCompilingDueBUG #endif -static const Byte kLiteralNextStates[kNumStates * 2] = -{ - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, - 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 -}; - #define LZMA_DIC_MIN (1 << 12) /* First LZMA-symbol is always decoded. @@ -175,6 +169,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte if (state < kNumLitStates) { + state -= (state < 4) ? state : 3; symbol = 1; do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); } @@ -182,6 +177,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; symbol = 1; do { @@ -196,9 +192,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte } dic[dicPos++] = (Byte)symbol; processedPos++; - - state = kLiteralNextStates[state]; - /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ continue; } else @@ -378,7 +371,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte else if (distance >= checkDicSize) return SZ_ERROR_DATA; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - /* state = kLiteralNextStates[state]; */ } len += kMatchMinLen; diff --git a/lzma/C/LzmaDec.h b/lzma/C/LzmaDec.h index 9ec549c86..6741a644b 100644 --- a/lzma/C/LzmaDec.h +++ b/lzma/C/LzmaDec.h @@ -1,11 +1,15 @@ /* LzmaDec.h -- LZMA Decoder -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ -#ifndef __LZMADEC_H -#define __LZMADEC_H +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + /* #define _LZMA_PROB32 */ /* _LZMA_PROB32 can increase the speed on some CPUs, but memory usage for CLzmaDec::probs will be doubled in that case */ @@ -66,13 +70,7 @@ typedef struct #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -#ifdef __cplusplus -extern "C" { -#endif void LzmaDec_Init(CLzmaDec *p); -#ifdef __cplusplus -} -#endif /* There are two types of LZMA streams: 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. @@ -132,11 +130,7 @@ LzmaDec_Allocate* can return: SZ_ERROR_MEM - Memory allocation error SZ_ERROR_UNSUPPORTED - Unsupported properties */ - -#ifdef __cplusplus -extern "C" { -#endif - + SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); diff --git a/lzma/C/LzmaEnc.c b/lzma/C/LzmaEnc.c index 529fd98f8..9e6dbdbe2 100644 --- a/lzma/C/LzmaEnc.c +++ b/lzma/C/LzmaEnc.c @@ -1,5 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2009-02-02 : Igor Pavlov : Public domain */ +2010-04-16 : Igor Pavlov : Public domain */ #include @@ -13,7 +13,7 @@ #include "LzmaEnc.h" #include "LzFind.h" -#ifdef COMPRESS_MF_MT +#ifndef _7ZIP_ST #include "LzFindMt.h" #endif @@ -66,7 +66,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); if (p->numThreads < 0) p->numThreads = - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST ((p->btMode && p->algo) ? 2 : 1); #else 1; @@ -139,7 +139,7 @@ void LzmaEnc_FastPosInit(Byte *g_FastPos) typedef unsigned CState; -typedef struct _COptimal +typedef struct { UInt32 price; @@ -172,7 +172,7 @@ typedef struct _COptimal #define kEndPosModelIndex 14 #define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) #ifdef _LZMA_PROB32 #define CLzmaProb UInt32 @@ -218,7 +218,7 @@ typedef struct UInt32 counters[LZMA_NUM_PB_STATES_MAX]; } CLenPriceEnc; -typedef struct _CRangeEnc +typedef struct { UInt32 range; Byte cache; @@ -232,26 +232,6 @@ typedef struct _CRangeEnc SRes res; } CRangeEnc; -typedef struct _CSeqInStreamBuf -{ - ISeqInStream funcTable; - const Byte *data; - SizeT rem; -} CSeqInStreamBuf; - -static SRes MyRead(void *pp, void *data, size_t *size) -{ - size_t curSize = *size; - CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; - if (p->rem < curSize) - curSize = p->rem; - memcpy(data, p->data, curSize); - p->rem -= curSize; - p->data += curSize; - *size = curSize; - return SZ_OK; -} - typedef struct { CLzmaProb *litProbs; @@ -274,19 +254,19 @@ typedef struct UInt32 state; } CSaveState; -typedef struct _CLzmaEnc +typedef struct { IMatchFinder matchFinder; void *matchFinderObj; - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST Bool mtMode; CMatchFinderMt matchFinderMt; #endif CMatchFinder matchFinderBase; - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST Byte pad[128]; #endif @@ -351,8 +331,7 @@ typedef struct _CLzmaEnc UInt32 dictSize; UInt32 matchFinderCycles; - ISeqInStream *inStream; - CSeqInStreamBuf seqBufInStream; + int needInit; CSaveState saveState; } CLzmaEnc; @@ -416,7 +395,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) LzmaEncProps_Normalize(&props); if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || - props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) + props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) return SZ_ERROR_PARAM; p->dictSize = props.dictSize; p->matchFinderCycles = props.mc; @@ -449,7 +428,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) p->writeEndMark = props.writeEndMark; - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST /* if (newMultiThread != _multiThread) { @@ -1698,7 +1677,7 @@ void LzmaEnc_Construct(CLzmaEnc *p) { RangeEnc_Construct(&p->rc); MatchFinder_Construct(&p->matchFinderBase); - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST MatchFinderMt_Construct(&p->matchFinderMt); p->matchFinderMt.MatchFinder = &p->matchFinderBase; #endif @@ -1737,7 +1716,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) { - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); #endif MatchFinder_Free(&p->matchFinderBase, allocBig); @@ -1754,11 +1733,10 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) { UInt32 nowPos32, startPos32; - if (p->inStream != 0) + if (p->needInit) { - p->matchFinderBase.stream = p->inStream; p->matchFinder.Init(p->matchFinderObj); - p->inStream = 0; + p->needInit = 0; } if (p->finished) @@ -1923,7 +1901,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; btMode = (p->matchFinderBase.btMode != 0); - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST p->mtMode = (p->multiThread && !p->fastMode && btMode); #endif @@ -1948,7 +1926,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I if (beforeSize + p->dictSize < keepWindowSize) beforeSize = keepWindowSize - p->dictSize; - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST if (p->mtMode) { RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); @@ -2056,11 +2034,12 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a return SZ_OK; } -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ISzAlloc *alloc, ISzAlloc *allocBig) { CLzmaEnc *p = (CLzmaEnc *)pp; - p->inStream = inStream; + p->matchFinderBase.stream = inStream; + p->needInit = 1; p->rc.outStream = outStream; return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); } @@ -2070,15 +2049,16 @@ SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISzAlloc *alloc, ISzAlloc *allocBig) { CLzmaEnc *p = (CLzmaEnc *)pp; - p->inStream = inStream; + p->matchFinderBase.stream = inStream; + p->needInit = 1; return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) { - p->seqBufInStream.funcTable.Read = MyRead; - p->seqBufInStream.data = src; - p->seqBufInStream.rem = srcLen; + p->matchFinderBase.directInput = 1; + p->matchFinderBase.bufferBase = (Byte *)src; + p->matchFinderBase.directInputRem = srcLen; } SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, @@ -2086,13 +2066,14 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, { CLzmaEnc *p = (CLzmaEnc *)pp; LzmaEnc_SetInputBuf(p, src, srcLen); - p->inStream = &p->seqBufInStream.funcTable; + p->needInit = 1; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } void LzmaEnc_Finish(CLzmaEncHandle pp) { - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST CLzmaEnc *p = (CLzmaEnc *)pp; if (p->mtMode) MatchFinderMt_ReleaseStream(&p->matchFinderMt); @@ -2101,7 +2082,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp) #endif } -typedef struct _CSeqOutStreamBuf +typedef struct { ISeqOutStream funcTable; Byte *data; @@ -2170,21 +2151,17 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, return res; } -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) { - CLzmaEnc *p = (CLzmaEnc *)pp; SRes res = SZ_OK; - #ifdef COMPRESS_MF_MT + #ifndef _7ZIP_ST Byte allocaDummy[0x300]; int i = 0; for (i = 0; i < 16; i++) allocaDummy[i] = (Byte)i; #endif - RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); - for (;;) { res = LzmaEnc_CodeOneBlock(p, False, 0, 0); @@ -2200,10 +2177,17 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i } } } - LzmaEnc_Finish(pp); + LzmaEnc_Finish(p); return res; } +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); + return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); +} + SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) { CLzmaEnc *p = (CLzmaEnc *)pp; @@ -2249,8 +2233,11 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte outStream.overflow = False; p->writeEndMark = writeEndMark; - res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, - progress, alloc, allocBig); + + p->rc.outStream = &outStream.funcTable; + res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); + if (res == SZ_OK) + res = LzmaEnc_Encode2(p, progress); *destLen -= outStream.rem; if (outStream.overflow) diff --git a/lzma/C/LzmaEnc.h b/lzma/C/LzmaEnc.h index e3d84fa35..999f5afff 100644 --- a/lzma/C/LzmaEnc.h +++ b/lzma/C/LzmaEnc.h @@ -1,11 +1,15 @@ /* LzmaEnc.h -- LZMA Encoder -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ -#ifndef __LZMAENC_H -#define __LZMAENC_H +#ifndef __LZMA_ENC_H +#define __LZMA_ENC_H #include "Types.h" +#ifdef __cplusplus +extern "C" { +#endif + #define LZMA_PROPS_SIZE 5 typedef struct _CLzmaEncProps @@ -69,4 +73,8 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lzma/C/LzmaLib.c b/lzma/C/LzmaLib.c deleted file mode 100644 index 3e3cf40ae..000000000 --- a/lzma/C/LzmaLib.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LzmaLib.c -- LZMA library wrapper -2008-08-05 -Igor Pavlov -Public domain */ - -#include "LzmaEnc.h" -#include "LzmaDec.h" -#include "Alloc.h" -#include "LzmaLib.h" - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ -) -{ - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - props.lc = lc; - props.lp = lp; - props.pb = pb; - props.fb = fb; - props.numThreads = numThreads; - - return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); -} - - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, - const unsigned char *props, size_t propsSize) -{ - ELzmaStatus status; - return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); -} diff --git a/lzma/C/LzmaLib.h b/lzma/C/LzmaLib.h deleted file mode 100644 index 849d347e9..000000000 --- a/lzma/C/LzmaLib.h +++ /dev/null @@ -1,135 +0,0 @@ -/* LzmaLib.h -- LZMA library interface -2008-08-05 -Igor Pavlov -Public domain */ - -#ifndef __LZMALIB_H -#define __LZMALIB_H - -#include "Types.h" - -#ifdef __cplusplus - #define MY_EXTERN_C extern "C" -#else - #define MY_EXTERN_C extern -#endif - -#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL - -#define LZMA_PROPS_SIZE 5 - -/* -RAM requirements for LZMA: - for compression: (dictSize * 11.5 + 6 MB) + state_size - for decompression: dictSize + state_size - state_size = (4 + (1.5 << (lc + lp))) KB - by default (lc=3, lp=0), state_size = 16 KB. - -LZMA properties (5 bytes) format - Offset Size Description - 0 1 lc, lp and pb in encoded form. - 1 4 dictSize (little endian). -*/ - -/* -LzmaCompress ------------- - -outPropsSize - - In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. - - LZMA Encoder will use defult values for any parameter, if it is - -1 for any from: level, loc, lp, pb, fb, numThreads - 0 for dictSize - -level - compression level: 0 <= level <= 9; - - level dictSize algo fb - 0: 16 KB 0 32 - 1: 64 KB 0 32 - 2: 256 KB 0 32 - 3: 1 MB 0 32 - 4: 4 MB 0 32 - 5: 16 MB 1 32 - 6: 32 MB 1 32 - 7+: 64 MB 1 64 - - The default value for "level" is 5. - - algo = 0 means fast method - algo = 1 means normal method - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - -lc - The number of literal context bits (high bits of previous literal). - It can be in the range from 0 to 8. The default value is 3. - Sometimes lc=4 gives the gain for big files. - -lp - The number of literal pos bits (low bits of current position for literals). - It can be in the range from 0 to 4. The default value is 0. - The lp switch is intended for periodical data when the period is equal to 2^lp. - For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's - better to set lc=0, if you change lp switch. - -pb - The number of pos bits (low bits of current position). - It can be in the range from 0 to 4. The default value is 2. - The pb switch is intended for periodical data when the period is equal 2^pb. - -fb - Word size (the number of fast bytes). - It can be in the range from 5 to 273. The default value is 32. - Usually, a big number gives a little bit better compression ratio and - slower compression process. - -numThreads - The number of thereads. 1 or 2. The default value is 2. - Fast mode (algo = 0) can use only 1 thread. - -Out: - destLen - processed output size -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, - unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ - int level, /* 0 <= level <= 9, default = 5 */ - unsigned dictSize, /* default = (1 << 24) */ - int lc, /* 0 <= lc <= 8, default = 3 */ - int lp, /* 0 <= lp <= 4, default = 0 */ - int pb, /* 0 <= pb <= 4, default = 2 */ - int fb, /* 5 <= fb <= 273, default = 32 */ - int numThreads /* 1 or 2, default = 2 */ - ); - -/* -LzmaUncompress --------------- -In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size -Out: - destLen - processed output size - srcLen - processed input size -Returns: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation arror - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) -*/ - -MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, - const unsigned char *props, size_t propsSize); - -#endif diff --git a/lzma/C/Threads.c b/lzma/C/Threads.c index 64d871abe..4be44fb0f 100644 --- a/lzma/C/Threads.c +++ b/lzma/C/Threads.c @@ -1,13 +1,12 @@ /* Threads.c -- multithreading library -2008-08-05 -Igor Pavlov -Public domain */ +2009-09-20 : Igor Pavlov : Public domain */ + +#ifndef _WIN32_WCE +#include +#endif #include "Threads.h" -#ifdef _WIN32 -#include - static WRes GetError() { DWORD res = GetLastError(); @@ -17,276 +16,69 @@ static WRes GetError() WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } -static WRes MyCloseHandle(HANDLE *h) +WRes HandlePtr_Close(HANDLE *p) { - if (*h != NULL) - if (!CloseHandle(*h)) + if (*p != NULL) + if (!CloseHandle(*p)) return GetError(); - *h = NULL; + *p = NULL; return 0; } -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) +WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } + +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) { unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ - thread->handle = - /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */ - (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId); + *p = + #ifdef UNDER_CE + CreateThread(0, 0, func, param, 0, &threadId); + #else + (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); + #endif /* maybe we must use errno here, but probably GetLastError() is also OK. */ - return HandleToWRes(thread->handle); + return HandleToWRes(*p); } -WRes WaitObject(HANDLE h) +WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) { - return (WRes)WaitForSingleObject(h, INFINITE); + *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); + return HandleToWRes(*p); } -WRes Thread_Wait(CThread *thread) +WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } +WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } + +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } + + +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) { - if (thread->handle == NULL) - return 1; - return WaitObject(thread->handle); + *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); + return HandleToWRes(*p); } -WRes Thread_Close(CThread *thread) -{ - return MyCloseHandle(&thread->handle); -} - -WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) -{ - p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL); - return HandleToWRes(p->handle); -} - -WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) - { return Event_Create(p, TRUE, initialSignaled); } -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) - { return ManualResetEvent_Create(p, 0); } - -WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) - { return Event_Create(p, FALSE, initialSignaled); } -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) - { return AutoResetEvent_Create(p, 0); } - -WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); } -WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); } -WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } -WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } - - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) -{ - p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL); - return HandleToWRes(p->handle); -} - -WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) -{ - return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); -} -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) -{ - return Semaphore_Release(p, (LONG)releaseCount, NULL); -} -WRes Semaphore_Release1(CSemaphore *p) -{ - return Semaphore_ReleaseN(p, 1); -} - -WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } -WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } +static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) + { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) + { return Semaphore_Release(p, (LONG)num, NULL); } +WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } WRes CriticalSection_Init(CCriticalSection *p) { /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ -#ifndef __GNUC__ + #ifdef _MSC_VER __try -#endif + #endif { InitializeCriticalSection(p); /* InitializeCriticalSectionAndSpinCount(p, 0); */ } -#ifndef __GNUC__ + #ifdef _MSC_VER __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } -#endif + #endif return 0; } - -#else - -#include -#include - -#include - -#if defined(__linux__) -#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP -#endif - - -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *parameter) -{ - pthread_attr_t attr; - int ret; - - thread->_created = 0; - - ret = pthread_attr_init(&attr); - if (ret) return ret; - - ret = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); - if (ret) return ret; - - ret = pthread_create(&thread->_tid, &attr, (void * (*)(void *))startAddress, parameter); - - /* ret2 = */ pthread_attr_destroy(&attr); - - if (ret) return ret; - - thread->_created = 1; - - return 0; // SZ_OK; -} - -WRes Thread_Wait(CThread *thread) -{ - void *thread_return; - int ret; - - if (thread->_created == 0) - return EINVAL; - - ret = pthread_join(thread->_tid,&thread_return); - thread->_created = 0; - - return ret; -} - -WRes Thread_Close(CThread *thread) -{ - if (!thread->_created) return SZ_OK; - - pthread_detach(thread->_tid); - thread->_tid = 0; - thread->_created = 0; - return SZ_OK; -} - -WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) -{ - pthread_mutex_init(&p->_mutex,0); - pthread_cond_init(&p->_cond,0); - p->_manual_reset = manualReset; - p->_state = (initialSignaled ? TRUE : FALSE); - p->_created = 1; - return 0; -} - -WRes Event_Set(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - p->_state = TRUE; - pthread_cond_broadcast(&p->_cond); - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Reset(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - p->_state = FALSE; - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Wait(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - while (p->_state == FALSE) - { - pthread_cond_wait(&p->_cond, &p->_mutex); - } - if (p->_manual_reset == FALSE) - { - p->_state = FALSE; - } - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Close(CEvent *p) { - if (p->_created) - { - p->_created = 0; - pthread_mutex_destroy(&p->_mutex); - pthread_cond_destroy(&p->_cond); - } - return 0; -} - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) -{ - pthread_mutex_init(&p->_mutex,0); - pthread_cond_init(&p->_cond,0); - p->_count = initiallyCount; - p->_maxCount = maxCount; - p->_created = 1; - return 0; -} - -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) -{ - UInt32 newCount; - - if (releaseCount < 1) return EINVAL; - - pthread_mutex_lock(&p->_mutex); - - newCount = p->_count + releaseCount; - if (newCount > p->_maxCount) - { - pthread_mutex_unlock(&p->_mutex); - return EINVAL; - } - p->_count = newCount; - pthread_cond_broadcast(&p->_cond); - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Semaphore_Wait(CSemaphore *p) { - pthread_mutex_lock(&p->_mutex); - while (p->_count < 1) - { - pthread_cond_wait(&p->_cond, &p->_mutex); - } - p->_count--; - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Semaphore_Close(CSemaphore *p) { - if (p->_created) - { - p->_created = 0; - pthread_mutex_destroy(&p->_mutex); - pthread_cond_destroy(&p->_cond); - } - return 0; -} - -WRes CriticalSection_Init(CCriticalSection * lpCriticalSection) -{ - return pthread_mutex_init(&(lpCriticalSection->_mutex),0); -} - -WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) - { return Event_Create(p, TRUE, initialSignaled); } - -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) - { return ManualResetEvent_Create(p, 0); } - -WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) - { return Event_Create(p, FALSE, initialSignaled); } -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) - { return AutoResetEvent_Create(p, 0); } - -#endif diff --git a/lzma/C/Threads.h b/lzma/C/Threads.h index c895c7e51..6a7afa829 100644 --- a/lzma/C/Threads.h +++ b/lzma/C/Threads.h @@ -1,151 +1,59 @@ /* Threads.h -- multithreading library -2008-11-22 : Igor Pavlov : Public domain */ +2009-03-27 : Igor Pavlov : Public domain */ -#ifndef __7Z_THRESDS_H -#define __7Z_THRESDS_H - -#ifdef _WIN32 -#include -typedef DWORD WRes; +#ifndef __7Z_THREADS_H +#define __7Z_THREADS_H #include "Types.h" -typedef struct _CThread -{ - HANDLE handle; -} CThread; +#ifdef __cplusplus +extern "C" { +#endif -#define Thread_Construct(thread) (thread)->handle = NULL -#define Thread_WasCreated(thread) ((thread)->handle != NULL) - +WRes HandlePtr_Close(HANDLE *h); +WRes Handle_WaitObject(HANDLE h); + +typedef HANDLE CThread; +#define Thread_Construct(p) *(p) = NULL +#define Thread_WasCreated(p) (*(p) != NULL) +#define Thread_Close(p) HandlePtr_Close(p) +#define Thread_Wait(p) Handle_WaitObject(*(p)) typedef unsigned THREAD_FUNC_RET_TYPE; -#define THREAD_FUNC_CALL_TYPE __stdcall +#define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE +typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); -WRes Thread_Wait(CThread *thread); -WRes Thread_Close(CThread *thread); - -typedef struct _CEvent -{ - HANDLE handle; -} CEvent; - +typedef HANDLE CEvent; typedef CEvent CAutoResetEvent; typedef CEvent CManualResetEvent; +#define Event_Construct(p) *(p) = NULL +#define Event_IsCreated(p) (*(p) != NULL) +#define Event_Close(p) HandlePtr_Close(p) +#define Event_Wait(p) Handle_WaitObject(*(p)) +WRes Event_Set(CEvent *p); +WRes Event_Reset(CEvent *p); +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); -#define Event_Construct(event) (event)->handle = NULL -#define Event_IsCreated(event) ((event)->handle != NULL) - -WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); -WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); -WRes Event_Set(CEvent *event); -WRes Event_Reset(CEvent *event); -WRes Event_Wait(CEvent *event); -WRes Event_Close(CEvent *event); - - -typedef struct _CSemaphore -{ - HANDLE handle; -} CSemaphore; - -#define Semaphore_Construct(p) (p)->handle = NULL - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); +typedef HANDLE CSemaphore; +#define Semaphore_Construct(p) (*p) = NULL +#define Semaphore_Close(p) HandlePtr_Close(p) +#define Semaphore_Wait(p) Handle_WaitObject(*(p)) +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); WRes Semaphore_Release1(CSemaphore *p); -WRes Semaphore_Wait(CSemaphore *p); -WRes Semaphore_Close(CSemaphore *p); - typedef CRITICAL_SECTION CCriticalSection; - WRes CriticalSection_Init(CCriticalSection *p); #define CriticalSection_Delete(p) DeleteCriticalSection(p) #define CriticalSection_Enter(p) EnterCriticalSection(p) #define CriticalSection_Leave(p) LeaveCriticalSection(p) -#else -typedef int WRes; - -#include "Types.h" -#include - -/* #define DEBUG_SYNCHRO 1 */ - -typedef struct _CThread -{ - pthread_t _tid; - int _created; - -} CThread; - -#define Thread_Construct(thread) (thread)->_created = 0 -#define Thread_WasCreated(thread) ((thread)->_created != 0) - -typedef unsigned THREAD_FUNC_RET_TYPE; -#define THREAD_FUNC_CALL_TYPE -#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE - -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *parameter); -WRes Thread_Wait(CThread *thread); -WRes Thread_Close(CThread *thread); - -typedef struct _CEvent -{ - int _created; - int _manual_reset; - int _state; - pthread_mutex_t _mutex; - pthread_cond_t _cond; -} CEvent; - -typedef CEvent CAutoResetEvent; -typedef CEvent CManualResetEvent; - -#define Event_Construct(event) (event)->_created = 0 -#define Event_IsCreated(event) ((event)->_created) - -WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); -WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); -WRes Event_Set(CEvent *event); -WRes Event_Reset(CEvent *event); -WRes Event_Wait(CEvent *event); -WRes Event_Close(CEvent *event); - - -typedef struct _CSemaphore -{ - int _created; - UInt32 _count; - UInt32 _maxCount; - pthread_mutex_t _mutex; - pthread_cond_t _cond; -} CSemaphore; - -#define Semaphore_Construct(p) (p)->_created = 0 - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); -#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1) -WRes Semaphore_Wait(CSemaphore *p); -WRes Semaphore_Close(CSemaphore *p); - -typedef struct { - pthread_mutex_t _mutex; -} CCriticalSection; - -WRes CriticalSection_Init(CCriticalSection *p); -#define CriticalSection_Delete(p) pthread_mutex_destroy(&((p)->_mutex)) -#define CriticalSection_Enter(p) pthread_mutex_lock(&((p)->_mutex)) -#define CriticalSection_Leave(p) pthread_mutex_unlock(&((p)->_mutex)) - +#ifdef __cplusplus +} #endif #endif - diff --git a/lzma/C/Types.h b/lzma/C/Types.h index 958b2af2d..834709bb9 100644 --- a/lzma/C/Types.h +++ b/lzma/C/Types.h @@ -1,15 +1,27 @@ /* Types.h -- Basic types -2008-11-23 : Igor Pavlov : Public domain */ +2010-10-09 : Igor Pavlov : Public domain */ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H #include -#ifdef __cplusplus -extern "C" { +#ifdef _WIN32 +#include #endif +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + #define SZ_OK 0 #define SZ_ERROR_DATA 1 @@ -30,6 +42,12 @@ extern "C" { typedef int SRes; +#ifdef _WIN32 +typedef DWORD WRes; +#else +typedef int WRes; +#endif + #ifndef RINOK #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #endif @@ -37,10 +55,8 @@ typedef int SRes; #if defined(__APPLE__) && !__LP64__ #define _LZMA_UINT32_IS_ULONG #endif - -#ifndef ZCONF_H + typedef unsigned char Byte; -#endif typedef short Int16; typedef unsigned short UInt16; @@ -65,9 +81,11 @@ typedef unsigned long UInt64; #if defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 Int64; typedef unsigned __int64 UInt64; +#define UINT64_CONST(n) n #else typedef long long int Int64; typedef unsigned long long int UInt64; +#define UINT64_CONST(n) n ## ULL #endif #endif @@ -83,6 +101,12 @@ typedef int Bool; #define False 0 +#ifdef _WIN32 +#define MY_STD_CALL __stdcall +#else +#define MY_STD_CALL +#endif + #ifdef _MSC_VER #if _MSC_VER >= 1300 @@ -92,13 +116,11 @@ typedef int Bool; #endif #define MY_CDECL __cdecl -#define MY_STD_CALL __stdcall -#define MY_FAST_CALL MY_NO_INLINE __fastcall +#define MY_FAST_CALL __fastcall #else #define MY_CDECL -#define MY_STD_CALL #define MY_FAST_CALL #endif @@ -106,6 +128,16 @@ typedef int Bool; /* The following interfaces use first parameter as pointer to structure */ +typedef struct +{ + Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ +} IByteIn; + +typedef struct +{ + void (*Write)(void *p, Byte b); +} IByteOut; + typedef struct { SRes (*Read)(void *p, void *buf, size_t *size); @@ -140,7 +172,7 @@ typedef struct typedef struct { - SRes (*Look)(void *p, void **buf, size_t *size); + SRes (*Look)(void *p, const void **buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) > input(*size)) is not allowed (output(*size) < input(*size)) is allowed */ @@ -205,8 +237,22 @@ typedef struct #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) #define IAlloc_Free(p, a) (p)->Free((p), a) -#ifdef __cplusplus -} -#endif +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + +EXTERN_C_END #endif diff --git a/lzma/CMakeLists.txt b/lzma/CMakeLists.txt index 019383d42..beebb0fde 100644 --- a/lzma/CMakeLists.txt +++ b/lzma/CMakeLists.txt @@ -7,25 +7,25 @@ if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) set( LZMA_FILES - C/Archive/7z/7zDecode.c - C/Archive/7z/7zExtract.c - C/Archive/7z/7zHeader.c - C/Archive/7z/7zIn.c - C/Archive/7z/7zItem.c C/7zBuf.c C/7zCrc.c + C/7zCrcOpt.c + C/7zDec.c + C/7zIn.c C/7zStream.c - C/Alloc.c - C/Bcj2.c - C/Bra86.c - C/LzFind.c - C/LzFindMt.c - C/LzmaDec.c - C/LzmaEnc.c - C/LzmaLib.c ) + C/Bcj2.c + C/Bra.c + C/Bra86.c + C/CpuArch.c + C/LzFind.c + C/Lzma2Dec.c + C/LzmaDec.c + C/LzmaEnc.c ) if( WIN32 ) - set( LZMA_FILES ${LZMA_FILES} C/Threads.c ) + set( LZMA_FILES ${LZMA_FILES} C/LzFindMt.c C/Threads.c ) +else( WIN32 ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_ST" ) endif( WIN32 ) add_library( lzma ${LZMA_FILES} ) diff --git a/lzma/history.txt b/lzma/history.txt old mode 100644 new mode 100755 index 9bed5ebbe..50ff40f02 --- a/lzma/history.txt +++ b/lzma/history.txt @@ -1,6 +1,41 @@ HISTORY of the LZMA SDK ----------------------- +9.18 beta 2010-11-02 +------------------------- +- New small SFX module for installers (SfxSetup). + + +9.12 beta 2010-03-24 +------------------------- +- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work, + if more than 10 threads were used (or more than 20 threads in some modes). + + +9.11 beta 2010-03-15 +------------------------- +- PPMd compression method support + + +9.09 2009-12-12 +------------------------- +- The bug was fixed: + Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c + incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8. +- Some bugs were fixed + + +9.06 2009-08-17 +------------------------- +- Some changes in ANSI-C 7z Decoder interfaces. + + +9.04 2009-05-30 +------------------------- +- LZMA2 compression method support +- xz format support + + 4.65 2009-02-03 ------------------------- - Some minor fixes diff --git a/lzma/lzma.txt b/lzma/lzma.txt old mode 100644 new mode 100755 index d4f4af929..579f2ccd8 --- a/lzma/lzma.txt +++ b/lzma/lzma.txt @@ -1,4 +1,4 @@ -LZMA SDK 4.65 +LZMA SDK 9.20 ------------- LZMA SDK provides the documentation, samples, header files, libraries, @@ -20,6 +20,10 @@ LICENSE LZMA SDK is written and placed in the public domain by Igor Pavlov. +Some code in LZMA SDK is based on public domain code from another developers: + 1) PPMd var.H (2001): Dmitry Shkarin + 2) SHA-256: Wei Dai (Crypto++ library) + LZMA SDK Contents ----------------- @@ -33,7 +37,7 @@ LZMA SDK includes: UNIX/Linux version ------------------ To compile C++ version of file->file LZMA encoding, go to directory -C++/7zip/Compress/LZMA_Alone +CPP/7zip/Bundles/LzmaCon and call make to recompile it: make -f makefile.gcc clean all @@ -49,6 +53,7 @@ lzma.txt - LZMA SDK description (this file) 7zC.txt - 7z ANSI-C Decoder description methods.txt - Compression method IDs for .7z lzma.exe - Compiled file->file LZMA encoder/decoder for Windows +7zr.exe - 7-Zip with 7z/lzma/xz support. history.txt - history of the LZMA SDK @@ -66,7 +71,7 @@ C/ - C files LzmaEnc.* - LZMA encoding LzmaLib.* - LZMA Library for DLL calling Types.h - Basic types for another .c files - Threads.* - The code for multithreading. + Threads.* - The code for multithreading. LzmaLib - LZMA Library (.DLL for Windows) @@ -86,12 +91,6 @@ CPP/ -- CPP files Compress - files related to compression/decompression - Copy - Copy coder - RangeCoder - Range Coder (special code of compression/decompression) - LZMA - LZMA compression/decompression on C++ - LZMA_Alone - file->file LZMA compression/decompression - Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code - Archive - files related to archiving Common - common files for archive handling @@ -100,6 +99,7 @@ CPP/ -- CPP files Bundles - Modules that are bundles of other modules Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2 + LzmaCon - lzma.exe: LZMA compression/decompression Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2 Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2. @@ -369,8 +369,8 @@ Interface: propData - LZMA properties (5 bytes) propSize - size of propData buffer (5 bytes) finishMode - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). You can use LZMA_FINISH_END, when you know that current output buffer covers last bytes of stream. alloc - Memory allocator. @@ -431,7 +431,7 @@ Memory Requirements: { ... int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); ... } @@ -527,7 +527,8 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree }; LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); -If callback function return some error code, LzmaEnc_Encode also returns that code. +If callback function return some error code, LzmaEnc_Encode also returns that code +or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. Single-call RAM->RAM Compression @@ -549,8 +550,8 @@ Return code: -LZMA Defines ------------- +Defines +------- _LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. @@ -562,6 +563,9 @@ _LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is _LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type. +_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder. + + C++ LZMA Encoder/Decoder ~~~~~~~~~~~~~~~~~~~~~~~~ C++ LZMA code use COM-like interfaces. So if you want to use it, diff --git a/lzma/lzmalib.vcproj b/lzma/lzmalib.vcproj index 414e26f8d..3ad1ec149 100644 --- a/lzma/lzmalib.vcproj +++ b/lzma/lzmalib.vcproj @@ -294,16 +294,28 @@ RelativePath=".\C\7zCrc.c" > + + + + + + + + @@ -340,6 +356,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -352,10 +372,6 @@ RelativePath=".\C\7zVersion.h" > - - @@ -380,6 +396,10 @@ RelativePath=".\C\LzHash.h" > + + @@ -388,10 +408,6 @@ RelativePath=".\C\LzmaEnc.h" > - - @@ -401,50 +417,6 @@ > - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index a00626774..a7d173a4e 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -41,12 +41,8 @@ #include "i_system.h" #include "w_wad.h" -extern "C" { -#include "Archive/7z/7zHeader.h" -#include "Archive/7z/7zExtract.h" -#include "Archive/7z/7zIn.h" +#include "7z.h" #include "7zCrc.h" -} //----------------------------------------------------------------------- @@ -151,7 +147,7 @@ struct C7zArchive SRes Extract(UInt32 file_index, char *buffer) { size_t offset, out_size_processed; - SRes res = SzAr_Extract(&DB, &LookStream.s, file_index, + SRes res = SzArEx_Extract(&DB, &LookStream.s, file_index, &BlockIndex, &OutBuffer, &OutBufferSize, &offset, &out_size_processed, &g_Alloc, &g_Alloc); @@ -279,7 +275,27 @@ bool F7ZFile::Open(bool quiet) continue; } - FString name = file->Name; + const size_t nameLength = SzArEx_GetFileNameUtf16(&Archive->DB, i, NULL); + + if (0 == nameLength) + { + ++skipped; + continue; + } + + // Convert UTF-16 filename to plain ASCII + + UInt16* const nameUTF16 = static_cast(alloca(sizeof(UInt16) * nameLength)); + SzArEx_GetFileNameUtf16(&Archive->DB, i, nameUTF16); + + char* const nameASCII = static_cast(alloca(nameLength)); + + for (size_t c = 0; c < nameLength; ++c) + { + nameASCII[c] = static_cast(nameUTF16[c]); + } + + FString name = nameASCII; FixPathSeperator(name); name.ToLower(); From 94c4f38c584bc679f2c278843ae42f85f74a98c1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 28 Apr 2014 01:26:30 +0200 Subject: [PATCH 175/311] - added constants for sound channels 5-7. --- wadsrc/static/actors/constants.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index dee498b6a..a264b4627 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -221,7 +221,10 @@ enum CHAN_VOICE = 2, CHAN_ITEM = 3, CHAN_BODY = 4, - + CHAN_5 = 5, + CHAN_6 = 6, + CHAN_7 = 7, + // modifier flags CHAN_LISTENERZ = 8, CHAN_MAYBE_LOCAL = 16, From 64d4ddf559e7d66b20e11c1b3aeaeed361886dd7 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 28 Apr 2014 11:34:37 +0300 Subject: [PATCH 176/311] Fixed file list in VS2005 project of LZMA library --- lzma/lzmalib.vcproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lzma/lzmalib.vcproj b/lzma/lzmalib.vcproj index 3ad1ec149..b37a52970 100644 --- a/lzma/lzmalib.vcproj +++ b/lzma/lzmalib.vcproj @@ -322,6 +322,10 @@ RelativePath=".\C\Bra86.c" > + + @@ -342,10 +346,6 @@ RelativePath=".\C\LzmaEnc.c" > - - From 76fdb4905f37735956c1a03d7ad9e7e9a86762d4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 28 Apr 2014 13:06:05 +0300 Subject: [PATCH 177/311] Fixed compilation with updated LZMA library using Visual Studio --- lzma/C/CpuArch.c | 4 ++++ lzma/C/Threads.h | 7 +++++++ lzma/C/Types.h | 10 ---------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c index 36e7680d9..4b319fa88 100644 --- a/lzma/C/CpuArch.c +++ b/lzma/C/CpuArch.c @@ -3,6 +3,10 @@ #include "CpuArch.h" +#ifdef _WIN32 +#include +#endif + #ifdef MY_CPU_X86_OR_AMD64 #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) diff --git a/lzma/C/Threads.h b/lzma/C/Threads.h index 6a7afa829..b82214355 100644 --- a/lzma/C/Threads.h +++ b/lzma/C/Threads.h @@ -6,6 +6,13 @@ #include "Types.h" +#ifdef _WIN32 +#include +typedef DWORD WRes; +#else +typedef int WRes; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/lzma/C/Types.h b/lzma/C/Types.h index 834709bb9..284991104 100644 --- a/lzma/C/Types.h +++ b/lzma/C/Types.h @@ -6,10 +6,6 @@ #include -#ifdef _WIN32 -#include -#endif - #ifndef EXTERN_C_BEGIN #ifdef __cplusplus #define EXTERN_C_BEGIN extern "C" { @@ -42,12 +38,6 @@ EXTERN_C_BEGIN typedef int SRes; -#ifdef _WIN32 -typedef DWORD WRes; -#else -typedef int WRes; -#endif - #ifndef RINOK #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #endif From d6af8dc352f2f87bcbeda11f932a6fbc574fe883 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 3 May 2014 02:11:16 +1200 Subject: [PATCH 178/311] Added static RNGseed control --- src/d_main.cpp | 9 ++++++++- src/g_level.cpp | 6 +++++- src/m_random.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/m_random.h | 4 ++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 6c938ef53..f677f88b3 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1993,7 +1993,14 @@ static void D_DoomInit() SetLanguageIDs (); - rngseed = I_MakeRNGSeed(); + const char *v = Args->CheckValue("-rngseed"); + if (v) + { + rngseed = staticrngseed = atoi(v); + use_staticrng = true; + } + else + rngseed = I_MakeRNGSeed(); FRandom::StaticClearRandom (); Printf ("M_LoadDefaults: Load system defaults.\n"); diff --git a/src/g_level.cpp b/src/g_level.cpp index 65bde08d8..c721be4e1 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -408,7 +408,11 @@ void G_InitNew (const char *mapname, bool bTitleLevel) if (!savegamerestore) { - if (!netgame) + if (use_staticrng) + { + rngseed = staticrngseed; + } + else if (!netgame) { // [RH] Change the random seed for each new single player game rngseed = rngseed + 1; } diff --git a/src/m_random.cpp b/src/m_random.cpp index 763410111..f1e39faf9 100644 --- a/src/m_random.cpp +++ b/src/m_random.cpp @@ -96,6 +96,42 @@ FRandom M_Random; // Global seed. This is modified predictably to initialize every RNG. DWORD rngseed; +// Static RNG marker. This is only used when the RNG is set for each new game. +DWORD staticrngseed; +bool use_staticrng; + +// Allows checking or staticly setting the global seed. +CCMD(rngseed) +{ + if (argv.argc() == 1) + { + Printf("Usage: rngseed get|set|clear\n"); + return; + } + if (stricmp(argv[1], "get") == 0) + { + Printf("rngseed is %d\n", rngseed); + } + else if (stricmp(argv[1], "set") == 0) + { + if (argv.argc() == 2) + { + Printf("You need to specify a value to set\n"); + } + else + { + staticrngseed = atoi(argv[2]); + use_staticrng = true; + Printf("Static rngseed %d will be set for next game\n", staticrngseed); + } + } + else if (stricmp(argv[1], "clear") == 0) + { + use_staticrng = false; + Printf("Static rngseed cleared\n"); + } +} + // PRIVATE DATA DEFINITIONS ------------------------------------------------ FRandom *FRandom::RNGList; diff --git a/src/m_random.h b/src/m_random.h index 5b124c50e..b5e21c63c 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -215,6 +215,10 @@ private: extern DWORD rngseed; // The starting seed (not part of state) +extern DWORD staticrngseed; // Static rngseed that can be set by the user +extern bool use_staticrng; + + // M_Random can be used for numbers that do not affect gameplay extern FRandom M_Random; From 6183f8125fa4dc00db087b683bc08b8deb68e3d2 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 3 May 2014 02:48:52 +1200 Subject: [PATCH 179/311] Don't change RNG in demos incase they are static --- src/d_main.cpp | 1 + src/g_level.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index f677f88b3..5d36459db 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1998,6 +1998,7 @@ static void D_DoomInit() { rngseed = staticrngseed = atoi(v); use_staticrng = true; + Printf("D_DoomInit: Static RNGseed %d set.\n", rngseed); } else rngseed = I_MakeRNGSeed(); diff --git a/src/g_level.cpp b/src/g_level.cpp index c721be4e1..7b37ad471 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -408,13 +408,11 @@ void G_InitNew (const char *mapname, bool bTitleLevel) if (!savegamerestore) { - if (use_staticrng) + if (!netgame && !demorecording && !demoplayback) { - rngseed = staticrngseed; - } - else if (!netgame) - { // [RH] Change the random seed for each new single player game - rngseed = rngseed + 1; + // [RH] Change the random seed for each new single player game + // [ED850] The demo already sets the RNG. + rngseed = use_staticrng ? staticrngseed : (rngseed + 1); } FRandom::StaticClearRandom (); P_ClearACSVars(true); From 104a07d461bd8f75622a8674a7cb390174c41b9b Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 3 May 2014 03:24:51 +1200 Subject: [PATCH 180/311] Make sure use_staticrng is false if not needed --- src/d_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index 5d36459db..29049b10f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2001,7 +2001,11 @@ static void D_DoomInit() Printf("D_DoomInit: Static RNGseed %d set.\n", rngseed); } else + { rngseed = I_MakeRNGSeed(); + use_staticrng = false; + } + FRandom::StaticClearRandom (); Printf ("M_LoadDefaults: Load system defaults.\n"); From a9f1b54d2db91a3ff28f7198b4c8c5420dc73c42 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 3 May 2014 10:12:25 +0200 Subject: [PATCH 181/311] - fixed: since A_LightGoesOut alters a sector's floor plane it must also alter the TexZ for that sector's floor. --- src/g_strife/a_thingstoblowup.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 7d2c1ceee..d27260451 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -89,8 +89,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut) sec->SetLightLevel(0); - newheight = sec->FindLowestFloorSurrounding (&spot); + fixed_t oldtheight = sec->floorplane.Zat0(); + newheight = sec->FindLowestFloorSurrounding(&spot); sec->floorplane.d = sec->floorplane.PointToDist (spot, newheight); + fixed_t newtheight = sec->floorplane.Zat0(); + sec->ChangePlaneTexZ(sector_t::floor, newtheight - oldtheight); for (int i = 0; i < 8; ++i) { From 93aa1ea2c4da75918f19b97d9dfead98952b1bd5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 5 May 2014 11:24:20 +0200 Subject: [PATCH 182/311] fixed some issues with reviving monsters - fixed: Thing_Raise didn't properly set the spawn health. - fixed: Thing_Raise did not the CanRaise state flag. - fixed: Reviving a monster must also reset the damage type. - fixed: Thing_Raise reset the actor after calling the raise state, but it should be before, just as the Archvile code is doing. - consolidated some common code of Thing_Raise and Archvile resurrection into AActor methods. --- src/actor.h | 2 + src/p_enemy.cpp | 222 +++++++++++++++++++++-------------------------- src/p_mobj.cpp | 43 +++++++++ src/p_things.cpp | 36 ++------ 4 files changed, 152 insertions(+), 151 deletions(-) diff --git a/src/actor.h b/src/actor.h index 21057d86c..4b7696752 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1011,6 +1011,8 @@ public: bool isSlow(); void SetIdle(); void ClearCounters(); + FState *GetRaiseState(); + void Revive(); FState *FindState (FName label) const { diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 14c6b68aa..f84dd13aa 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2525,146 +2525,122 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) FBlockThingsIterator it(FBoundingBox(viletryx, viletryy, 32*FRACUNIT)); while ((corpsehit = it.Next())) { - if (!(corpsehit->flags & MF_CORPSE) ) - continue; // not a monster - - if (corpsehit->tics != -1 && // not lying still yet - !corpsehit->state->GetCanRaise()) // or not ready to be raised yet - continue; - - raisestate = corpsehit->FindState(NAME_Raise); - if (raisestate == NULL) - continue; // monster doesn't have a raise state - - if (corpsehit->IsKindOf(RUNTIME_CLASS(APlayerPawn))) - continue; // do not resurrect players - - // use the current actor's radius instead of the Arch Vile's default. - fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius; - - maxdist = corpsehit-> GetDefault()->radius + self->radius; - - if ( abs(corpsehit-> x - viletryx) > maxdist || - abs(corpsehit-> y - viletryy) > maxdist ) - continue; // not actually touching -#ifdef _3DFLOORS - // Let's check if there are floors in between the archvile and its target - sector_t *vilesec = self->Sector; - sector_t *corpsec = corpsehit->Sector; - // We only need to test if at least one of the sectors has a 3D floor. - sector_t *testsec = vilesec->e->XFloor.ffloors.Size() ? vilesec : - (vilesec != corpsec && corpsec->e->XFloor.ffloors.Size()) ? corpsec : NULL; - if (testsec) + FState *raisestate = corpsehit->GetRaiseState(); + if (raisestate != NULL) { - fixed_t zdist1, zdist2; - if (P_Find3DFloor(testsec, corpsehit->x, corpsehit->y, corpsehit->z, false, true, zdist1) - != P_Find3DFloor(testsec, self->x, self->y, self->z, false, true, zdist2)) + // use the current actor's radius instead of the Arch Vile's default. + fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius; + + maxdist = corpsehit->GetDefault()->radius + self->radius; + + if (abs(corpsehit->x - viletryx) > maxdist || + abs(corpsehit->y - viletryy) > maxdist) + continue; // not actually touching +#ifdef _3DFLOORS + // Let's check if there are floors in between the archvile and its target + sector_t *vilesec = self->Sector; + sector_t *corpsec = corpsehit->Sector; + // We only need to test if at least one of the sectors has a 3D floor. + sector_t *testsec = vilesec->e->XFloor.ffloors.Size() ? vilesec : + (vilesec != corpsec && corpsec->e->XFloor.ffloors.Size()) ? corpsec : NULL; + if (testsec) { - // Not on same floor - if (vilesec == corpsec || abs(zdist1 - self->z) > self->height) + fixed_t zdist1, zdist2; + if (P_Find3DFloor(testsec, corpsehit->x, corpsehit->y, corpsehit->z, false, true, zdist1) + != P_Find3DFloor(testsec, self->x, self->y, self->z, false, true, zdist2)) + { + // Not on same floor + if (vilesec == corpsec || abs(zdist1 - self->z) > self->height) continue; + } } - } #endif - corpsehit->velx = corpsehit->vely = 0; - // [RH] Check against real height and radius + corpsehit->velx = corpsehit->vely = 0; + // [RH] Check against real height and radius - fixed_t oldheight = corpsehit->height; - fixed_t oldradius = corpsehit->radius; - int oldflags = corpsehit->flags; + fixed_t oldheight = corpsehit->height; + fixed_t oldradius = corpsehit->radius; + int oldflags = corpsehit->flags; - corpsehit->flags |= MF_SOLID; - corpsehit->height = corpsehit->GetDefault()->height; - bool check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y); - corpsehit->flags = oldflags; - corpsehit->radius = oldradius; - corpsehit->height = oldheight; - if (!check) continue; + corpsehit->flags |= MF_SOLID; + corpsehit->height = corpsehit->GetDefault()->height; + bool check = P_CheckPosition(corpsehit, corpsehit->x, corpsehit->y); + corpsehit->flags = oldflags; + corpsehit->radius = oldradius; + corpsehit->height = oldheight; + if (!check) continue; - // got one! - temp = self->target; - self->target = corpsehit; - A_FaceTarget (self); - if (self->flags & MF_FRIENDLY) - { - // If this is a friendly Arch-Vile (which is turning the resurrected monster into its friend) - // and the Arch-Vile is currently targetting the resurrected monster the target must be cleared. - if (self->lastenemy == temp) self->lastenemy = NULL; - if (self->lastenemy == corpsehit) self->lastenemy = NULL; - if (temp == self->target) temp = NULL; - } - self->target = temp; - - // Make the state the monster enters customizable. - FState * state = self->FindState(NAME_Heal); - if (state != NULL) - { - self->SetState (state); - } - else if (usevilestates) - { - // For Dehacked compatibility this has to use the Arch Vile's - // heal state as a default if the actor doesn't define one itself. - const PClass *archvile = PClass::FindClass("Archvile"); - if (archvile != NULL) + // got one! + temp = self->target; + self->target = corpsehit; + A_FaceTarget(self); + if (self->flags & MF_FRIENDLY) { - self->SetState (archvile->ActorInfo->FindState(NAME_Heal)); + // If this is a friendly Arch-Vile (which is turning the resurrected monster into its friend) + // and the Arch-Vile is currently targetting the resurrected monster the target must be cleared. + if (self->lastenemy == temp) self->lastenemy = NULL; + if (self->lastenemy == corpsehit) self->lastenemy = NULL; + if (temp == self->target) temp = NULL; } - } - S_Sound (corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); - info = corpsehit->GetDefault (); - - if (corpsehit->state == corpsehit->FindState(NAME_GenericCrush)) - { - corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses - } - if (ib_compatflags & BCOMPATF_VILEGHOSTS) - { - corpsehit->height <<= 2; - // [GZ] This was a commented-out feature, so let's make use of it, - // but only for ghost monsters so that they are visibly different. - if (corpsehit->height == 0) + self->target = temp; + + // Make the state the monster enters customizable. + FState * state = self->FindState(NAME_Heal); + if (state != NULL) { - // Make raised corpses look ghostly - if (corpsehit->alpha > TRANSLUC50) + self->SetState(state); + } + else if (usevilestates) + { + // For Dehacked compatibility this has to use the Arch Vile's + // heal state as a default if the actor doesn't define one itself. + const PClass *archvile = PClass::FindClass("Archvile"); + if (archvile != NULL) { - corpsehit->alpha /= 2; - } - // This will only work if the render style is changed as well. - if (corpsehit->RenderStyle == LegacyRenderStyles[STYLE_Normal]) - { - corpsehit->RenderStyle = STYLE_Translucent; + self->SetState(archvile->ActorInfo->FindState(NAME_Heal)); } } - } - else - { - corpsehit->height = info->height; // [RH] Use real mobj height - corpsehit->radius = info->radius; // [RH] Use real radius - } - corpsehit->flags = info->flags; - corpsehit->flags2 = info->flags2; - corpsehit->flags3 = info->flags3; - corpsehit->flags4 = info->flags4; - corpsehit->flags5 = info->flags5; - corpsehit->flags6 = info->flags6; - corpsehit->flags7 = info->flags7; - corpsehit->health = corpsehit->SpawnHealth(); - corpsehit->target = NULL; - corpsehit->lastenemy = NULL; + S_Sound(corpsehit, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); + info = corpsehit->GetDefault(); - // [RH] If it's a monster, it gets to count as another kill - if (corpsehit->CountsAsKill()) - { - level.total_monsters++; + if (corpsehit->state == corpsehit->FindState(NAME_GenericCrush)) + { + corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses + } + if (ib_compatflags & BCOMPATF_VILEGHOSTS) + { + corpsehit->height <<= 2; + // [GZ] This was a commented-out feature, so let's make use of it, + // but only for ghost monsters so that they are visibly different. + if (corpsehit->height == 0) + { + // Make raised corpses look ghostly + if (corpsehit->alpha > TRANSLUC50) + { + corpsehit->alpha /= 2; + } + // This will only work if the render style is changed as well. + if (corpsehit->RenderStyle == LegacyRenderStyles[STYLE_Normal]) + { + corpsehit->RenderStyle = STYLE_Translucent; + } + } + } + else + { + corpsehit->height = info->height; // [RH] Use real mobj height + corpsehit->radius = info->radius; // [RH] Use real radius + } + + corpsehit->Revive(); + + // You are the Archvile's minion now, so hate what it hates + corpsehit->CopyFriendliness(self, false); + corpsehit->SetState(raisestate); + + return true; } - - // You are the Archvile's minion now, so hate what it hates - corpsehit->CopyFriendliness (self, false); - corpsehit->SetState (raisestate); - - return true; } } return false; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f519ba763..05eddf3ab 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6074,6 +6074,49 @@ int AActor::SpawnHealth() } } +FState *AActor::GetRaiseState() +{ + if (!(flags & MF_CORPSE)) + { + return NULL; // not a monster + } + + if (tics != -1 && // not lying still yet + state->GetCanRaise()) // or not ready to be raised yet + { + return NULL; + } + + if (IsKindOf(RUNTIME_CLASS(APlayerPawn))) + { + return NULL; // do not resurrect players + } + + return FindState(NAME_Raise); +} + +void AActor::Revive() +{ + AActor *info = GetDefault(); + flags = info->flags; + flags2 = info->flags2; + flags3 = info->flags3; + flags4 = info->flags4; + flags5 = info->flags5; + flags6 = info->flags6; + flags7 = info->flags7; + DamageType = info->DamageType; + health = SpawnHealth(); + target = NULL; + lastenemy = NULL; + + // [RH] If it's a monster, it gets to count as another kill + if (CountsAsKill()) + { + level.total_monsters++; + } +} + FDropItem *AActor::GetDropItems() { unsigned int index = GetClass()->Meta.GetMetaInt (ACMETA_DropItems) - 1; diff --git a/src/p_things.cpp b/src/p_things.cpp index 4828e8cbc..e62c65ae7 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -410,18 +410,11 @@ void P_RemoveThing(AActor * actor) bool P_Thing_Raise(AActor *thing) { - if (thing == NULL) - return false; // not valid - - if (!(thing->flags & MF_CORPSE) ) - return true; // not a corpse - - if (thing->tics != -1) - return true; // not lying still yet - - FState * RaiseState = thing->FindState(NAME_Raise); + FState * RaiseState = thing->GetRaiseState(); if (RaiseState == NULL) + { return true; // monster doesn't have a raise state + } AActor *info = thing->GetDefault (); @@ -443,25 +436,12 @@ bool P_Thing_Raise(AActor *thing) return false; } - S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); - - thing->SetState (RaiseState); - thing->flags = info->flags; - thing->flags2 = info->flags2; - thing->flags3 = info->flags3; - thing->flags4 = info->flags4; - thing->flags5 = info->flags5; - thing->flags6 = info->flags6; - thing->flags7 = info->flags7; - thing->health = info->health; - thing->target = NULL; - thing->lastenemy = NULL; - // [RH] If it's a monster, it gets to count as another kill - if (thing->CountsAsKill()) - { - level.total_monsters++; - } + S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); + + thing->Revive(); + + thing->SetState (RaiseState); return true; } From 90e9937b71b6d846edbd7ae245189e9aa3353039 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 5 May 2014 22:47:48 +1200 Subject: [PATCH 183/311] Stop NetUpdate from corrupting demo playback --- src/d_net.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d_net.cpp b/src/d_net.cpp index c912d29a2..170e9ed12 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1052,6 +1052,12 @@ void NetUpdate (void) if (singletics) return; // singletic update is synchronous + if (demoplayback) + { + nettics[0] = (maketic / ticdup); + return; // Don't touch netcmd data while playing a demo, as it'll already exist. + } + // If maketic didn't cross a ticdup boundary, only send packets // to players waiting for resends. resendOnly = (maketic / ticdup) == (maketic - i) / ticdup; From fcbb72a4d45760c3f4512cea6d535b7ef12ecb15 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 6 May 2014 09:59:56 +0200 Subject: [PATCH 184/311] - removed redundant variable. --- src/p_enemy.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index f84dd13aa..bdc72b0c8 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2520,7 +2520,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) fixed_t viletryx = self->x + FixedMul (absSpeed, xspeed[self->movedir]); fixed_t viletryy = self->y + FixedMul (absSpeed, yspeed[self->movedir]); AActor *corpsehit; - FState *raisestate; FBlockThingsIterator it(FBoundingBox(viletryx, viletryy, 32*FRACUNIT)); while ((corpsehit = it.Next())) From 890e9ecdddd36e1075098a3dcbaf0a93f73ddb51 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 7 May 2014 17:18:44 +0200 Subject: [PATCH 185/311] - typo in resurrection code. --- src/p_mobj.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 05eddf3ab..78b1124d4 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1,4 +1,5 @@ // Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ @@ -6082,7 +6083,7 @@ FState *AActor::GetRaiseState() } if (tics != -1 && // not lying still yet - state->GetCanRaise()) // or not ready to be raised yet + !state->GetCanRaise()) // or not ready to be raised yet { return NULL; } From 67ebbe3ed4bb2028c8850157d9e551569cc0aaba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 May 2014 09:15:56 +0200 Subject: [PATCH 186/311] made some changes to turn the CF_INTERPVIEW flag when changing angles into an op-in feature instead of making it automatic. --- src/p_acs.cpp | 8 ++++---- src/p_mobj.cpp | 8 ++++---- src/thingdef/thingdef_codeptr.cpp | 18 ++++++++++-------- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 3 ++- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index d70cc2c0b..8326d7b82 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8251,7 +8251,7 @@ scriptwait: { if (activator != NULL) { - activator->SetAngle(STACK(1) << 16); + activator->SetAngle(STACK(1) << 16, false); } } else @@ -8261,7 +8261,7 @@ scriptwait: while ( (actor = iterator.Next ()) ) { - actor->SetAngle(STACK(1) << 16); + actor->SetAngle(STACK(1) << 16, false); } } sp -= 2; @@ -8272,7 +8272,7 @@ scriptwait: { if (activator != NULL) { - activator->SetPitch(STACK(1) << 16); + activator->SetPitch(STACK(1) << 16, false); } } else @@ -8282,7 +8282,7 @@ scriptwait: while ( (actor = iterator.Next ()) ) { - actor->SetPitch(STACK(1) << 16); + actor->SetPitch(STACK(1) << 16, false); } } sp -= 2; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 69d4203fe..2bcae99b0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2962,24 +2962,24 @@ void AActor::SetShade (int r, int g, int b) fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b); } -void AActor::SetPitch(int p) +void AActor::SetPitch(int p, bool interpolate) { if (p != pitch) { pitch = p; - if (player != NULL) + if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; } } } -void AActor::SetAngle(angle_t ang) +void AActor::SetAngle(angle_t ang, bool interpolate) { if (ang != angle) { angle = ang; - if (player != NULL) + if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d48b18a2a..251a5de91 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3930,12 +3930,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MonsterRefire) // Set actor's angle (in degrees). // //=========================================================================== +enum +{ + SPF_FORCECLAMP = 1, // players always clamp + SPF_INTERPOLATE = 2, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) { - ACTION_PARAM_START(1); + ACTION_PARAM_START(2); ACTION_PARAM_ANGLE(angle, 0); - self->SetAngle(angle); + ACTION_PARAM_INT(flags, 1) + self->SetAngle(angle, !!(flags & SPF_INTERPOLATE)); } //=========================================================================== @@ -3946,11 +3953,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) // //=========================================================================== -enum -{ - SPF_FORCECLAMP = 1, // players always clamp -}; - DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) { ACTION_PARAM_START(2); @@ -3973,7 +3975,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) } pitch = clamp(pitch, min, max); } - self->SetPitch(pitch); + self->SetPitch(pitch, !!(flags & SPF_INTERPOLATE)); } //=========================================================================== diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 73119c941..1eb00440c 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -289,7 +289,7 @@ ACTOR Actor native //: Thinker action native A_DropWeaponPieces(class p1, class p2, class p3); action native A_PigPain (); action native A_MonsterRefire(int chance, state label); - action native A_SetAngle(float angle = 0); + action native A_SetAngle(float angle = 0, int flags = 0); action native A_SetPitch(float pitch, int flags = 0); action native A_ScaleVelocity(float scale); action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index dee498b6a..b252e3194 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -304,8 +304,9 @@ Const Int WARPF_STOP = 0x80; Const Int WARPF_TOFLOOR = 0x100; Const Int WARPF_TESTONLY = 0x200; -// flags for A_SetPitch +// flags for A_SetPitch/SetAngle const int SPF_FORCECLAMP = 1; +const int SPF_INTERPOLATE = 2; // flags for A_CheckLOF From 2223c12938ab24995a798443bee841b1fa249563 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 May 2014 09:43:58 +0200 Subject: [PATCH 187/311] - added new ChangeActorAngle/ChangeActorPitch ACS functions because the new required 'interpolate' parameter cannot be added to the existing SetActorAngle/SetActorPitch functions without breaking old scripts. --- src/actor.h | 4 +- src/p_acs.cpp | 106 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 36 deletions(-) diff --git a/src/actor.h b/src/actor.h index 4b7696752..0dd20c14f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -765,8 +765,8 @@ public: } // These also set CF_INTERPVIEW for players. - void SetPitch(int p); - void SetAngle(angle_t ang); + void SetPitch(int p, bool interpolate); + void SetAngle(angle_t ang, bool interpolate); const PClass *GetBloodType(int type = 0) const { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 198ba0cd0..50dd2733b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4263,6 +4263,18 @@ enum EACSFunctions ACSF_SetLineActivation, ACSF_GetLineActivation, ACSF_GetActorPowerupTics, + ACSF_ChangeActorAngle, + ACSF_ChangeActorPitch, // 80 + + /* Zandronum's - these must be skipped when we reach 99! + -100:ResetMap(0), + -101 : PlayerIsSpectator(1), + -102 : ConsolePlayerNumber(0), + -103 : GetTeamProperty(2), + -104 : GetPlayerLivesLeft(1), + -105 : SetPlayerLivesLeft(2), + -106 : KickFromGame(2), + */ // ZDaemon ACSF_GetTeamScore = 19620, // (int team) @@ -4522,6 +4534,50 @@ static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, an angle, distance, !!(flags & SDF_PERMANENT)); } +static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolate) +{ + if (tid == 0) + { + if (activator != NULL) + { + activator->SetAngle(angle << 16, interpolate); + } + } + else + { + FActorIterator iterator(tid); + AActor *actor; + + while ((actor = iterator.Next())) + { + actor->SetAngle(angle << 16, interpolate); + } + } +} + +static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolate) +{ + if (tid == 0) + { + if (activator != NULL) + { + activator->SetPitch(angle << 16, interpolate); + } + } + else + { + FActorIterator iterator(tid); + AActor *actor; + + while ((actor = iterator.Next())) + { + actor->SetPitch(angle << 16, interpolate); + } + } +} + + + int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth) { AActor *actor; @@ -5349,6 +5405,20 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) } break; + case ACSF_ChangeActorAngle: + if (argCount >= 2) + { + SetActorAngle(activator, args[0], args[1], argCount > 2 ? !!args[2] : false); + } + break; + + case ACSF_ChangeActorPitch: + if (argCount >= 2) + { + SetActorPitch(activator, args[0], args[1], argCount > 2 ? !!args[2] : false); + } + break; + default: break; } @@ -8323,44 +8393,12 @@ scriptwait: break; case PCD_SETACTORANGLE: // [GRB] - if (STACK(2) == 0) - { - if (activator != NULL) - { - activator->SetAngle(STACK(1) << 16, false); - } - } - else - { - FActorIterator iterator (STACK(2)); - AActor *actor; - - while ( (actor = iterator.Next ()) ) - { - actor->SetAngle(STACK(1) << 16, false); - } - } + SetActorAngle(activator, STACK(2), STACK(1), false); sp -= 2; break; case PCD_SETACTORPITCH: - if (STACK(2) == 0) - { - if (activator != NULL) - { - activator->SetPitch(STACK(1) << 16, false); - } - } - else - { - FActorIterator iterator (STACK(2)); - AActor *actor; - - while ( (actor = iterator.Next ()) ) - { - actor->SetPitch(STACK(1) << 16, false); - } - } + SetActorPitch(activator, STACK(2), STACK(1), false); sp -= 2; break; From ea7fb936a83d66d520ac45b110b0d74f9f29b136 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 May 2014 10:33:32 +0200 Subject: [PATCH 188/311] - fixed: memory allocation for file names in 7z archives was broken. Changing it to use TArray instead of alloca makes it work. --- src/resourcefiles/file_7z.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index a7d173a4e..53653bb59 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -264,6 +264,8 @@ bool F7ZFile::Open(bool quiet) Lumps = new F7ZLump[NumLumps]; F7ZLump *lump_p = Lumps; + TArray nameUTF16; + TArray nameASCII; for (DWORD i = 0; i < NumLumps; ++i) { CSzFileItem *file = &Archive->DB.db.Files[i]; @@ -283,20 +285,16 @@ bool F7ZFile::Open(bool quiet) continue; } - // Convert UTF-16 filename to plain ASCII - - UInt16* const nameUTF16 = static_cast(alloca(sizeof(UInt16) * nameLength)); - SzArEx_GetFileNameUtf16(&Archive->DB, i, nameUTF16); - - char* const nameASCII = static_cast(alloca(nameLength)); - + nameUTF16.Resize(nameLength); + nameASCII.Resize(nameLength); + SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]); for (size_t c = 0; c < nameLength; ++c) { nameASCII[c] = static_cast(nameUTF16[c]); } + FixPathSeperator(&nameASCII[0]); - FString name = nameASCII; - FixPathSeperator(name); + FString name = &nameASCII[0]; name.ToLower(); lump_p->LumpNameSetup(name); From 458e1b1be2a7e76045849050f32c76b2e5c28d44 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 May 2014 11:29:45 +0200 Subject: [PATCH 189/311] - changed sound lookup for ZSDF dialogues so that it first checks the svox/ namespace before using the global one. --- src/p_usdf.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index 6ea32b308..2ab52e380 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -310,12 +310,16 @@ class USDFParser : public UDMFParserBase case NAME_Voice: { - FString soundname = (namespace_bits == St? "svox/" : ""); const char * name = CheckString(key); if (name[0] != 0) { + FString soundname = "svox/"; soundname += name; node->SpeakerVoice = FSoundID(S_FindSound(soundname)); + if (node->SpeakerVoice == 0 && namespace_bits == Zd) + { + node->SpeakerVoice = FSoundID(S_FindSound(name)); + } } } break; From 65e8563cf44235725ef0f198f48956eca9f467cf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 11:33:59 +0200 Subject: [PATCH 190/311] replaced all character arrays for lump/texture names in the level_info_t and FLevelLocals structures with FStrings as first preparation for allowing long texture names. --- src/am_map.cpp | 10 ++++++++-- src/c_cmds.cpp | 11 +++++++++-- src/fragglescript/t_load.cpp | 5 +---- src/g_level.cpp | 32 ++++++++++++++------------------ src/g_level.h | 17 +++++++++-------- src/g_mapinfo.cpp | 32 +++++++++++++++----------------- src/menu/readthis.cpp | 6 +++--- src/p_acs.cpp | 6 ++---- src/textures/texturemanager.cpp | 2 +- src/v_draw.cpp | 4 ++-- src/version.h | 2 +- 11 files changed, 65 insertions(+), 62 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index e52d39211..904593dfb 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1316,8 +1316,14 @@ bool AM_clearMarks () void AM_LevelInit () { - const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)&level.info->mapbg[0]; - mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch); + if (level.info->MapBackground.Len() == 0) + { + mapback = TexMan.CheckForTexture("AUTOPAGE", FTexture::TEX_MiscPatch); + } + else + { + mapback = TexMan.CheckForTexture(level.info->MapBackground, FTexture::TEX_MiscPatch); + } AM_clearMarks(); diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 0e7adb8ef..7b6f1d195 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -946,8 +946,15 @@ CCMD(changesky) sky1name = argv[1]; if (sky1name[0] != 0) { - strncpy (level.skypic1, sky1name, 8); - sky1texture = TexMan.GetTexture (sky1name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + FTextureID newsky = TexMan.GetTexture(sky1name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + if (newsky.Exists()) + { + sky1texture = level.skytexture1 = newsky; + } + else + { + Printf("changesky: Texture '%s' not found\n", sky1name); + } } R_InitSkyMap (); } diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index d9b4f2d04..49458c4be 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -183,10 +183,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc) sc.MustGetStringName("="); sc.MustGetString(); - strncpy(level.skypic1, sc.String, 8); - strncpy(level.skypic2, sc.String, 8); - level.skypic1[8]=level.skypic2[8]=0; - sky2texture = sky1texture = TexMan.GetTexture (sc.String, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sky2texture = sky1texture = level.skytexture1 = level.skytexture2 = TexMan.GetTexture (sc.String, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); R_InitSkyMap (); } else if (sc.Compare("interpic")) diff --git a/src/g_level.cpp b/src/g_level.cpp index 7b37ad471..814bafcfb 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -870,8 +870,8 @@ void G_DoLoadLevel (int position, bool autosave) // DOOM determines the sky texture to be used // depending on the current episode and the game version. // [RH] Fetch sky parameters from FLevelLocals. - sky1texture = TexMan.GetTexture (level.skypic1, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); - sky2texture = TexMan.GetTexture (level.skypic2, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky1texture = level.skytexture1; + sky2texture = level.skytexture2; // [RH] Set up details about sky rendering R_InitSkyMap (); @@ -1222,15 +1222,16 @@ void G_InitLevelLocals () level.info = info; level.skyspeed1 = info->skyspeed1; level.skyspeed2 = info->skyspeed2; - strncpy (level.skypic2, info->skypic2, 8); + level.skytexture1 = TexMan.GetTexture(info->SkyPic1, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + level.skytexture2 = TexMan.GetTexture(info->SkyPic2, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); level.fadeto = info->fadeto; level.cdtrack = info->cdtrack; level.cdid = info->cdid; level.FromSnapshot = false; if (level.fadeto == 0) { - R_SetDefaultColormap (info->fadetable); - if (strnicmp (info->fadetable, "COLORMAP", 8) != 0) + R_SetDefaultColormap (info->FadeTable); + if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0) { level.flags |= LEVEL_HASFADETABLE; } @@ -1277,11 +1278,6 @@ void G_InitLevelLocals () level.nextmap[10] = 0; strncpy (level.secretmap, info->secretmap, 10); level.secretmap[10] = 0; - strncpy (level.skypic1, info->skypic1, 8); - level.skypic1[8] = 0; - if (!level.skypic2[0]) - strncpy (level.skypic2, level.skypic1, 8); - level.skypic2[8] = 0; compatflags.Callback(); compatflags2.Callback(); @@ -1406,18 +1402,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) if (!hubLoad) level.totaltime = i; - if (arc.IsStoring ()) + if (SaveVersion >= 4507) { - arc.WriteName (level.skypic1); - arc.WriteName (level.skypic2); + arc << level.skytexture1 << level.skytexture2; } else { - strncpy (level.skypic1, arc.ReadName(), 8); - strncpy (level.skypic2, arc.ReadName(), 8); - sky1texture = TexMan.GetTexture (level.skypic1, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); - sky2texture = TexMan.GetTexture (level.skypic2, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); - R_InitSkyMap (); + sky1texture = TexMan.GetTexture (arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky2texture = TexMan.GetTexture (arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + } + if (arc.IsLoading()) + { + R_InitSkyMap(); } G_AirControlChanged (); diff --git a/src/g_level.h b/src/g_level.h index 4a84e6871..43644a279 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -38,6 +38,7 @@ #include "doomdef.h" #include "sc_man.h" #include "s_sound.h" +#include "textures/textures.h" struct level_info_t; struct cluster_info_t; @@ -272,12 +273,12 @@ struct level_info_t char pname[9]; char nextmap[11]; char secretmap[11]; - char skypic1[9]; - char skypic2[9]; - char fadetable[9]; - char f1[9]; - char bordertexture[9]; - char mapbg[9]; + FString SkyPic1; + FString SkyPic2; + FString FadeTable; + FString F1Pic; + FString BorderTexture; + FString MapBackground; int cluster; int partime; @@ -406,8 +407,8 @@ struct FLevelLocals int cdtrack; unsigned int cdid; int nextmusic; // For MUSINFO purposes - char skypic1[9]; - char skypic2[9]; + FTextureID skytexture1; + FTextureID skytexture2; float skyspeed1; // Scrolling speed of sky textures, in pixels per ms float skyspeed2; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 04617a068..d8e12e9e4 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -94,8 +94,7 @@ level_info_t *FindLevelInfo (const char *mapname, bool allowdefault) { if (TheDefaultLevelInfo.LevelName.IsEmpty()) { - uppercopy(TheDefaultLevelInfo.skypic1, "SKY1"); - uppercopy(TheDefaultLevelInfo.skypic2, "SKY1"); + TheDefaultLevelInfo.SkyPic2 = TheDefaultLevelInfo.SkyPic1 = "SKY1"; TheDefaultLevelInfo.LevelName = "Unnamed"; } return &TheDefaultLevelInfo; @@ -226,13 +225,12 @@ void P_RemoveDefereds (void) void level_info_t::Reset() { mapname[0] = 0; - mapbg[0] = 0; + MapBackground = ""; levelnum = 0; pname[0] = 0; nextmap[0] = 0; secretmap[0] = 0; - strcpy (skypic1, "-NOFLAT-"); - strcpy (skypic2, "-NOFLAT-"); + SkyPic1 = SkyPic2 = "-NOFLAT-"; cluster = 0; partime = 0; sucktime = 0; @@ -243,10 +241,10 @@ void level_info_t::Reset() flags2 = LEVEL2_LAXMONSTERACTIVATION; Music = ""; LevelName = ""; - strcpy (fadetable, "COLORMAP"); + FadeTable = "COLORMAP"; WallHorizLight = -8; WallVertLight = +8; - f1[0] = 0; + F1Pic = ""; musicorder = 0; snapshot = NULL; snapshotVer = 0; @@ -271,7 +269,7 @@ void level_info_t::Reset() intermusicorder = 0; SoundInfo = ""; SndSeq = ""; - bordertexture[0] = 0; + BorderTexture = ""; teamdamage = 0.f; specialactions.Clear(); DefaultEnvironment = 0; @@ -850,7 +848,7 @@ DEFINE_MAP_OPTION(cluster, true) DEFINE_MAP_OPTION(sky1, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->skypic1); + parse.ParseLumpOrTextureName(info->SkyPic1); if (parse.CheckFloat()) { if (parse.HexenHack) @@ -864,7 +862,7 @@ DEFINE_MAP_OPTION(sky1, true) DEFINE_MAP_OPTION(sky2, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->skypic2); + parse.ParseLumpOrTextureName(info->SkyPic2); if (parse.CheckFloat()) { if (parse.HexenHack) @@ -879,7 +877,7 @@ DEFINE_MAP_OPTION(sky2, true) DEFINE_MAP_OPTION(skybox, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->skypic1); + parse.ParseLumpOrTextureName(info->SkyPic1); info->skyspeed1 = 0; } @@ -939,7 +937,7 @@ DEFINE_MAP_OPTION(intermusic, true) DEFINE_MAP_OPTION(fadetable, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->fadetable); + parse.ParseLumpOrTextureName(info->FadeTable); } DEFINE_MAP_OPTION(evenlighting, true) @@ -1122,13 +1120,13 @@ DEFINE_MAP_OPTION(slideshow, false) DEFINE_MAP_OPTION(bordertexture, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->bordertexture); + parse.ParseLumpOrTextureName(info->BorderTexture); } DEFINE_MAP_OPTION(f1, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->f1); + parse.ParseLumpOrTextureName(info->F1Pic); } DEFINE_MAP_OPTION(teamdamage, true) @@ -1141,7 +1139,7 @@ DEFINE_MAP_OPTION(teamdamage, true) DEFINE_MAP_OPTION(mapbackground, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->mapbg); + parse.ParseLumpOrTextureName(info->MapBackground); } DEFINE_MAP_OPTION(defaultenvironment, false) @@ -1789,9 +1787,9 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i ParseMapDefinition(*levelinfo); // When the second sky is -NOFLAT-, make it a copy of the first sky - if (strcmp (levelinfo->skypic2, "-NOFLAT-") == 0) + if (!levelinfo->SkyPic2.CompareNoCase("-NOFLAT-")) { - strcpy (levelinfo->skypic2, levelinfo->skypic1); + levelinfo->SkyPic2 = levelinfo->SkyPic1; } SetLevelNum (levelinfo, levelinfo->levelnum); // Wipe out matching levelnums from other maps. } diff --git a/src/menu/readthis.cpp b/src/menu/readthis.cpp index 197981ad3..a00843440 100644 --- a/src/menu/readthis.cpp +++ b/src/menu/readthis.cpp @@ -82,9 +82,9 @@ void DReadThisMenu::Drawer() fixed_t alpha; // Did the mapper choose a custom help page via MAPINFO? - if ((level.info != NULL) && level.info->f1[0] != 0) + if ((level.info != NULL) && level.info->F1Pic.Len() != 0) { - tex = TexMan.FindTexture(level.info->f1); + tex = TexMan.FindTexture(level.info->F1Pic); mScreen = 1; } @@ -122,7 +122,7 @@ bool DReadThisMenu::MenuEvent(int mkey, bool fromcontroller) S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); mScreen++; mInfoTic = gametic; - if ((level.info != NULL && level.info->f1[0] != 0) || mScreen > int(gameinfo.infoPages.Size())) + if ((level.info != NULL && level.info->F1Pic.Len() != 0) || mScreen > int(gameinfo.infoPages.Size())) { Close(); } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 50dd2733b..04aecaed1 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8348,13 +8348,11 @@ scriptwait: sky2name = FBehavior::StaticLookupString (STACK(1)); if (sky1name[0] != 0) { - strncpy (level.skypic1, sky1name, 8); - sky1texture = TexMan.GetTexture (sky1name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky1texture = level.skytexture1 = TexMan.GetTexture (sky1name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); } if (sky2name[0] != 0) { - strncpy (level.skypic2, sky2name, 8); - sky2texture = TexMan.GetTexture (sky2name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky2texture = level.skytexture2 = TexMan.GetTexture (sky2name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); } R_InitSkyMap (); sp -= 2; diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 48f3ff9e0..cdacb95bd 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1004,7 +1004,7 @@ void FTextureManager::Init() { if (wadlevelinfos[i].flags & LEVEL_DOUBLESKY) { - FTextureID picnum = CheckForTexture (wadlevelinfos[i].skypic1, FTexture::TEX_Wall, false); + FTextureID picnum = CheckForTexture (wadlevelinfos[i].SkyPic1, FTexture::TEX_Wall, false); if (picnum.isValid()) { Textures[picnum.GetIndex()].Texture->SetFrontSkyLayer (); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index cd07b44a1..8472637a2 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1444,9 +1444,9 @@ void V_DrawBorder (int x1, int y1, int x2, int y2) { FTextureID picnum; - if (level.info != NULL && level.info->bordertexture[0] != 0) + if (level.info != NULL && level.info->BorderTexture.Len() != 0) { - picnum = TexMan.CheckForTexture (level.info->bordertexture, FTexture::TEX_Flat); + picnum = TexMan.CheckForTexture (level.info->BorderTexture, FTexture::TEX_Flat); } else { diff --git a/src/version.h b/src/version.h index 27bfe1021..1b4457655 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4506 +#define SAVEVER 4507 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From fedf9c6a5ba40e4166b9da6874a7454a174d38fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 11:39:25 +0200 Subject: [PATCH 191/311] fixed: if we allow long names for the fade table we must also check for them when the colormap gets loaded. --- src/r_data/colormaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index c3004a4da..b7e1b904b 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -396,7 +396,7 @@ void R_SetDefaultColormap (const char *name) BYTE unremap[256]; BYTE remap[256]; - lump = Wads.CheckNumForName (name, ns_colormaps); + lump = Wads.CheckNumForFullName (name, true, ns_colormaps); if (lump == -1) lump = Wads.CheckNumForName (name, ns_global); From e718a72b4d3891f1207ab66fe081eb8c733af23b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 11:53:08 +0200 Subject: [PATCH 192/311] fixed: skies should be loaded into the FLevelLocals struct not into the global variables of the renderer. --- src/g_level.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 814bafcfb..47ad66998 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1408,8 +1408,8 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } else { - sky1texture = TexMan.GetTexture (arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); - sky2texture = TexMan.GetTexture (arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + level.skytexture1 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + level.skytexture2 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); } if (arc.IsLoading()) { From a05e62f3f7b4d690ebe5398a5c76c7c796bfad36 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 12:44:17 +0200 Subject: [PATCH 193/311] - changed storage of lump and texture names in gameinfo to allow long names (with the exception of view border elements.) --- src/c_console.cpp | 2 +- src/d_main.cpp | 4 ++-- src/g_shared/a_armor.cpp | 4 ++-- src/gi.cpp | 20 +++++++++----------- src/gi.h | 18 +++++++++--------- src/intermission/intermission.cpp | 2 +- src/v_draw.cpp | 2 +- src/wi_stuff.cpp | 4 ++-- src/win32/st_start.cpp | 4 ++-- 9 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index b21c8c3a6..396b2dfce 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -303,7 +303,7 @@ void C_InitConback() if (!conback.isValid()) { - conback = TexMan.GetTexture (gameinfo.titlePage, FTexture::TEX_MiscPatch); + conback = TexMan.GetTexture (gameinfo.TitlePage, FTexture::TEX_MiscPatch); conshade = MAKEARGB(175,0,0,0); conline = true; } diff --git a/src/d_main.cpp b/src/d_main.cpp index 9f332c68d..93e6368c1 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1234,7 +1234,7 @@ void D_DoAdvanceDemo (void) static char demoname[8] = "DEMO1"; static int democount = 0; static int pagecount; - const char *pagename = NULL; + FString pagename; advancedemo = false; @@ -1299,7 +1299,7 @@ void D_DoAdvanceDemo (void) default: case 0: gamestate = GS_DEMOSCREEN; - pagename = gameinfo.titlePage; + pagename = gameinfo.TitlePage; pagetic = (int)(gameinfo.titleTime * TICRATE); S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false); demosequence = 3; diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index 664a56307..6b90a6a78 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -42,9 +42,9 @@ void ABasicArmor::Tick () AbsorbCount = 0; if (!Icon.isValid()) { - const char *icon = gameinfo.ArmorIcon1; + FString icon = gameinfo.ArmorIcon1; - if (SavePercent >= gameinfo.Armor2Percent && gameinfo.ArmorIcon2[0] != 0) + if (SavePercent >= gameinfo.Armor2Percent && gameinfo.ArmorIcon2.Len() != 0) icon = gameinfo.ArmorIcon2; if (icon[0] != 0) diff --git a/src/gi.cpp b/src/gi.cpp index d9d58dc9e..851a61fb8 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -271,16 +271,14 @@ void FMapInfoParser::ParseGameInfo() else if(nextKey.CompareNoCase("armoricons") == 0) { sc.MustGetToken(TK_StringConst); - strncpy(gameinfo.ArmorIcon1, sc.String, 8); - gameinfo.ArmorIcon1[8] = 0; + gameinfo.ArmorIcon1 = sc.String; if (sc.CheckToken(',')) { sc.MustGetToken(TK_FloatConst); gameinfo.Armor2Percent = FLOAT2FIXED(sc.Float); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); - strncpy(gameinfo.ArmorIcon2, sc.String, 8); - gameinfo.ArmorIcon2[8] = 0; + gameinfo.ArmorIcon2 = sc.String; } } else if(nextKey.CompareNoCase("maparrow") == 0) @@ -295,7 +293,7 @@ void FMapInfoParser::ParseGameInfo() else gameinfo.mCheatMapArrow = ""; } // Insert valid keys here. - GAMEINFOKEY_CSTRING(titlePage, "titlePage", 8) + GAMEINFOKEY_STRING(TitlePage, "titlePage") GAMEINFOKEY_STRINGARRAY(creditPages, "addcreditPage", 8, false) GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true) GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false) @@ -306,17 +304,17 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_FLOAT(pageTime, "pageTime") GAMEINFOKEY_STRING(chatSound, "chatSound") GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic") - GAMEINFOKEY_CSTRING(finaleFlat, "finaleFlat", 8) + GAMEINFOKEY_STRING(FinaleFlat, "finaleFlat") GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true) GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false) GAMEINFOKEY_STRINGARRAY(infoPages, "infoPage", 8, true) - GAMEINFOKEY_CSTRING(PauseSign, "pausesign", 8) + GAMEINFOKEY_STRING(PauseSign, "pausesign") GAMEINFOKEY_STRING(quitSound, "quitSound") - GAMEINFOKEY_CSTRING(borderFlat, "borderFlat", 8) + GAMEINFOKEY_STRING(BorderFlat, "borderFlat") GAMEINFOKEY_FIXED(telefogheight, "telefogheight") GAMEINFOKEY_FIXED(gibfactor, "gibfactor") GAMEINFOKEY_INT(defKickback, "defKickback") - GAMEINFOKEY_CSTRING(SkyFlatName, "SkyFlatName", 8) + GAMEINFOKEY_STRING(SkyFlatName, "SkyFlatName") GAMEINFOKEY_STRING(translator, "translator") GAMEINFOKEY_COLOR(pickupcolor, "pickupcolor") GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor") @@ -336,7 +334,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime") GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime") GAMEINFOKEY_INT(defaultdropstyle, "defaultdropstyle") - GAMEINFOKEY_CSTRING(Endoom, "endoom", 8) + GAMEINFOKEY_STRING(Endoom, "endoom") GAMEINFOKEY_INT(player5start, "player5start") GAMEINFOKEY_STRINGARRAY(quitmessages, "addquitmessages", 0, false) GAMEINFOKEY_STRINGARRAY(quitmessages, "quitmessages", 0, true) @@ -347,7 +345,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_STRING(mFontColorHeader, "menufontcolor_header") GAMEINFOKEY_STRING(mFontColorHighlight, "menufontcolor_highlight") GAMEINFOKEY_STRING(mFontColorSelection, "menufontcolor_selection") - GAMEINFOKEY_CSTRING(mBackButton, "menubackbutton", 8) + GAMEINFOKEY_STRING(mBackButton, "menubackbutton") GAMEINFOKEY_INT(TextScreenX, "textscreenx") GAMEINFOKEY_INT(TextScreenY, "textscreeny") GAMEINFOKEY_STRING(DefaultEndSequence, "defaultendsequence") diff --git a/src/gi.h b/src/gi.h index 6b887e1dd..9965b1dd1 100644 --- a/src/gi.h +++ b/src/gi.h @@ -78,7 +78,7 @@ struct gameinfo_t EGameType gametype; FString ConfigName; - char titlePage[9]; + FString TitlePage; bool drawreadthis; bool noloopfinalemusic; bool intermissioncounter; @@ -98,13 +98,13 @@ struct gameinfo_t FString chatSound; FString finaleMusic; int finaleOrder; - char finaleFlat[9]; - char borderFlat[9]; - char SkyFlatName[9]; - char ArmorIcon1[9]; - char ArmorIcon2[9]; - char PauseSign[9]; - char Endoom[9]; + FString FinaleFlat; + FString BorderFlat; + FString SkyFlatName; + FString ArmorIcon1; + FString ArmorIcon2; + FString PauseSign; + FString Endoom; fixed_t Armor2Percent; FString quitSound; gameborder_t *border; @@ -133,7 +133,7 @@ struct gameinfo_t FName mFontColorHeader; FName mFontColorHighlight; FName mFontColorSelection; - char mBackButton[9]; + FString mBackButton; fixed_t gibfactor; int TextScreenX; int TextScreenY; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 91090e432..2a52df58a 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -104,7 +104,7 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) } else { - texname = gameinfo.titlePage; + texname = gameinfo.TitlePage.GetChars(); } } else if (*texname == '$') diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 8472637a2..ecd50ec73 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1450,7 +1450,7 @@ void V_DrawBorder (int x1, int y1, int x2, int y2) } else { - picnum = TexMan.CheckForTexture (gameinfo.borderFlat, FTexture::TEX_Flat); + picnum = TexMan.CheckForTexture (gameinfo.BorderFlat, FTexture::TEX_Flat); } if (picnum.isValid()) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 7aef939b1..0cf5e7b77 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -314,7 +314,7 @@ static bool IsExMy(const char * name) void WI_LoadBackground(bool isenterpic) { - const char * lumpname = NULL; + const char *lumpname; char buffer[10]; in_anim_t an; lnode_t pt; @@ -399,7 +399,7 @@ void WI_LoadBackground(bool isenterpic) default: // Strife doesn't have an intermission pic so choose something neutral. if (isenterpic) return; - lumpname = gameinfo.borderFlat; + lumpname = gameinfo.BorderFlat; break; } } diff --git a/src/win32/st_start.cpp b/src/win32/st_start.cpp index 7ffe846e6..04b52925e 100644 --- a/src/win32/st_start.cpp +++ b/src/win32/st_start.cpp @@ -1086,12 +1086,12 @@ void ST_Endoom() { if (showendoom == 0) exit(0); - if (gameinfo.Endoom[0] == 0) + if (gameinfo.Endoom.Len() == 0) { exit(0); } - int endoom_lump = Wads.CheckNumForName (gameinfo.Endoom); + int endoom_lump = Wads.CheckNumForFullName (gameinfo.Endoom, true); BYTE endoom_screen[4000]; BYTE *font; From a22670626c1b81a7bb97a2742741f50d7541cd75 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 13:40:02 +0200 Subject: [PATCH 194/311] - expanded names for view border elements. Also fixed the horribly bad implementation of custom borders which modified the DoomBorder elements without ever checking the game being used. --- src/g_shared/shared_sbar.cpp | 12 ++++++------ src/gi.cpp | 29 +++++++++++++---------------- src/gi.h | 33 +++++++++++++++++++++++++++++++-- src/v_draw.cpp | 14 +++++++------- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 547f6534e..7e8e660ee 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1090,12 +1090,12 @@ void DBaseStatusBar::RefreshBackground () const if (setblocks >= 10) { - const gameborder_t *border = gameinfo.border; - FTexture *p; - - p = TexMan[border->b]; - screen->FlatFill(0, y, x, y + p->GetHeight(), p, true); - screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true); + FTexture *p = TexMan[gameinfo.Border.b]; + if (p != NULL) + { + screen->FlatFill(0, y, x, y + p->GetHeight(), p, true); + screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true); + } } } } diff --git a/src/gi.cpp b/src/gi.cpp index 851a61fb8..8ab935854 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -51,7 +51,7 @@ const char *GameNames[17] = }; -static gameborder_t DoomBorder = +static staticgameborder_t DoomBorder = { 8, 8, "brdr_tl", "brdr_t", "brdr_tr", @@ -59,7 +59,7 @@ static gameborder_t DoomBorder = "brdr_bl", "brdr_b", "brdr_br" }; -static gameborder_t HereticBorder = +static staticgameborder_t HereticBorder = { 4, 16, "bordtl", "bordt", "bordtr", @@ -67,7 +67,7 @@ static gameborder_t HereticBorder = "bordbl", "bordb", "bordbr" }; -static gameborder_t StrifeBorder = +static staticgameborder_t StrifeBorder = { 8, 8, "brdr_tl", "brdr_t", "brdr_tr", @@ -231,40 +231,37 @@ void FMapInfoParser::ParseGameInfo() } else if(nextKey.CompareNoCase("border") == 0) { - if(sc.CheckToken(TK_Identifier)) + staticgameborder_t *b; + if (sc.CheckToken(TK_Identifier)) { switch(sc.MustMatchString(GameInfoBorders)) { default: - gameinfo.border = &DoomBorder; + b = &DoomBorder; break; case 1: - gameinfo.border = &HereticBorder; + b = &HereticBorder; break; case 2: - gameinfo.border = &StrifeBorder; + b = &StrifeBorder; break; } + gameinfo.Border = *b; } else { // border = {size, offset, tr, t, tl, r, l ,br, b, bl}; - char *graphics[8] = {DoomBorder.tr, DoomBorder.t, DoomBorder.tl, DoomBorder.r, DoomBorder.l, DoomBorder.br, DoomBorder.b, DoomBorder.bl}; + FString *graphics[8] = { &gameinfo.Border.tr, &gameinfo.Border.t, &gameinfo.Border.tl, &gameinfo.Border.r, &gameinfo.Border.l, &gameinfo.Border.br, &gameinfo.Border.b, &gameinfo.Border.bl }; sc.MustGetToken(TK_IntConst); - DoomBorder.offset = sc.Number; + gameinfo.Border.offset = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); - DoomBorder.size = sc.Number; + gameinfo.Border.size = sc.Number; for(int i = 0;i < 8;i++) { sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); - int len = int(strlen(sc.String)); - if(len > 8) - sc.ScriptError("Border graphic can not be more than 8 characters long.\n"); - memcpy(graphics[i], sc.String, len); - if(len < 8) // end with a null byte if the string is less than 8 chars. - graphics[i][len] = 0; + (*graphics[i]) = sc.String; } } } diff --git a/src/gi.h b/src/gi.h index 9965b1dd1..a1a03b2de 100644 --- a/src/gi.h +++ b/src/gi.h @@ -52,7 +52,7 @@ extern const char *GameNames[17]; -struct gameborder_t +struct staticgameborder_t { BYTE offset; BYTE size; @@ -66,6 +66,35 @@ struct gameborder_t char br[8]; }; +struct gameborder_t +{ + BYTE offset; + BYTE size; + FString tl; + FString t; + FString tr; + FString l; + FString r; + FString bl; + FString b; + FString br; + + gameborder_t &operator=(staticgameborder_t &other) + { + offset = other.offset; + size = other.size; + tl = other.tl; + t = other.t; + tr = other.tr; + l = other.l; + r = other.r; + bl = other.bl; + b = other.b; + br = other.br; + return *this; + } +}; + struct FGIFont { FName fontname; @@ -107,7 +136,7 @@ struct gameinfo_t FString Endoom; fixed_t Armor2Percent; FString quitSound; - gameborder_t *border; + gameborder_t Border; int telefogheight; int defKickback; FString translator; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index ecd50ec73..5db99e674 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1407,7 +1407,7 @@ void V_SetBorderNeedRefresh() void V_DrawFrame (int left, int top, int width, int height) { FTexture *p; - const gameborder_t *border = gameinfo.border; + const gameborder_t *border = &gameinfo.Border; // Sanity check for incomplete gameinfo if (border == NULL) return; @@ -1513,28 +1513,28 @@ static void V_DrawTopBorder () if (viewwidth == SCREENWIDTH) return; - offset = gameinfo.border->offset; + offset = gameinfo.Border.offset; if (viewwindowy < 34) { V_DrawBorder (0, 0, viewwindowx, 34); V_DrawBorder (viewwindowx, 0, viewwindowx + viewwidth, viewwindowy); V_DrawBorder (viewwindowx + viewwidth, 0, SCREENWIDTH, 34); - p = TexMan(gameinfo.border->t); + p = TexMan(gameinfo.Border.t); screen->FlatFill(viewwindowx, viewwindowy - p->GetHeight(), viewwindowx + viewwidth, viewwindowy, p, true); - p = TexMan(gameinfo.border->l); + p = TexMan(gameinfo.Border.l); screen->FlatFill(viewwindowx - p->GetWidth(), viewwindowy, viewwindowx, 35, p, true); - p = TexMan(gameinfo.border->r); + p = TexMan(gameinfo.Border.r); screen->FlatFill(viewwindowx + viewwidth, viewwindowy, viewwindowx + viewwidth + p->GetWidth(), 35, p, true); - p = TexMan(gameinfo.border->tl); + p = TexMan(gameinfo.Border.tl); screen->DrawTexture (p, viewwindowx - offset, viewwindowy - offset, TAG_DONE); - p = TexMan(gameinfo.border->tr); + p = TexMan(gameinfo.Border.tr); screen->DrawTexture (p, viewwindowx + viewwidth, viewwindowy - offset, TAG_DONE); } else From ebd6c18bef6ed7e2508d8ee14cb3b65d1fe587fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 15:32:54 +0200 Subject: [PATCH 195/311] - missed one texture name field in level_info_t. --- src/g_level.cpp | 4 ++-- src/g_level.h | 2 +- src/g_mapinfo.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 47ad66998..c3e78d223 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -656,7 +656,7 @@ void G_DoCompleted (void) AM_Stop (); wminfo.finished_ep = level.cluster - 1; - wminfo.LName0 = TexMan[TexMan.CheckForTexture(level.info->pname, FTexture::TEX_MiscPatch)]; + wminfo.LName0 = TexMan[TexMan.CheckForTexture(level.info->PName, FTexture::TEX_MiscPatch)]; wminfo.current = level.mapname; if (deathmatch && @@ -677,7 +677,7 @@ void G_DoCompleted (void) else { wminfo.next = nextinfo->mapname; - wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->pname, FTexture::TEX_MiscPatch)]; + wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->PName, FTexture::TEX_MiscPatch)]; } } diff --git a/src/g_level.h b/src/g_level.h index 43644a279..85a2ff0e4 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -270,9 +270,9 @@ struct level_info_t int levelnum; char mapname[9]; - char pname[9]; char nextmap[11]; char secretmap[11]; + FString PName; FString SkyPic1; FString SkyPic2; FString FadeTable; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index d8e12e9e4..c261e2f33 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -227,7 +227,7 @@ void level_info_t::Reset() mapname[0] = 0; MapBackground = ""; levelnum = 0; - pname[0] = 0; + PName = ""; nextmap[0] = 0; secretmap[0] = 0; SkyPic1 = SkyPic2 = "-NOFLAT-"; @@ -898,7 +898,7 @@ DEFINE_MAP_OPTION(outsidefog, true) DEFINE_MAP_OPTION(titlepatch, true) { parse.ParseAssign(); - parse.ParseLumpOrTextureName(info->pname); + parse.ParseLumpOrTextureName(info->PName); } DEFINE_MAP_OPTION(partime, true) From ca4179caa3486052a3faac818225cf3dd0d8849b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 20:51:16 +0200 Subject: [PATCH 196/311] - allow texture lookup by full path names. Due to technical limitations this may result in double textures if the same graphics lump is also referenced by its short texture name. --- src/g_shared/sbarinfo_commands.cpp | 2 +- src/resourcefiles/resourcefile.h | 3 ++ src/textures/animations.cpp | 4 +- src/textures/multipatchtexture.cpp | 16 +------- src/textures/texture.cpp | 2 + src/textures/texturemanager.cpp | 64 ++++++++++++++++++------------ src/textures/textures.h | 5 +-- src/v_font.cpp | 13 ------ src/w_wad.cpp | 31 +++++++++++++++ src/w_wad.h | 4 ++ 10 files changed, 84 insertions(+), 60 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index fcd9bae7d..a1912b21e 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -300,7 +300,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl if (flags & DI_ALTERNATEONFAIL) { - SetTruth(texture == NULL || !(texture->GetID().isValid()), block, statusBar); + SetTruth(texture == NULL || texture->UseType == FTexture::TEX_Null, block, statusBar); } } protected: diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index e531ddbb3..517b5eef4 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -6,6 +6,7 @@ #include "files.h" class FResourceFile; +class FTexture; struct FResourceLump { @@ -24,6 +25,7 @@ struct FResourceLump SBYTE RefCount; char * Cache; FResourceFile * Owner; + FTexture * LinkedTexture; int Namespace; FResourceLump() @@ -35,6 +37,7 @@ struct FResourceLump RefCount = 0; Namespace = 0; // ns_global *Name = 0; + LinkedTexture = NULL; } virtual ~FResourceLump(); diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 433baa874..3601646a0 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -551,7 +551,7 @@ void FTextureManager::ParseTime (FScanner &sc, DWORD &min, DWORD &max) void FTextureManager::ParseWarp(FScanner &sc) { - const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly; bool isflat = false; bool type2 = sc.Compare ("warp2"); // [GRB] sc.MustGetString (); @@ -616,7 +616,7 @@ void FTextureManager::ParseWarp(FScanner &sc) void FTextureManager::ParseCameraTexture(FScanner &sc) { - const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly; int width, height; int fitwidth, fitheight; FString picname; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 4f327309d..124add5db 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1001,21 +1001,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, i if (!texno.isValid()) { - int lumpnum = Wads.CheckNumForFullName(sc.String); - if (lumpnum >= 0) - { - texno = TexMan.FindTextureByLumpNum(lumpnum); - if (texno.isValid ()) - { - part.Texture = TexMan[texno]; - } - else - { - part.Texture = FTexture::CreateTexture("", lumpnum, usetype); - TexMan.AddTexture(part.Texture); - } - } - else if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) + if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) { int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); if (lumpnum >= 0) diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 0434aaaa4..f41f1902d 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -167,6 +167,8 @@ FTexture::FTexture (const char *name, int lumpnum) FTexture::~FTexture () { + FTexture *link = Wads.GetLinkedTexture(SourceLump); + if (link == this) Wads.SetLinkedTexture(SourceLump, NULL); KillNative(); } diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index cdacb95bd..0af15d7af 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -224,6 +224,35 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF return FTextureID(firstfound); } + + if (!(flags & TEXMAN_ShortNameOnly)) + { + // We intentionally only look for textures in subdirectories. + // Any graphic being placed in the zip's root directory can not be found by this. + if (strchr(name, '/')) + { + FTexture *const NO_TEXTURE = (FTexture*)-1; + int lump = Wads.CheckNumForFullName(name); + if (lump != NULL) + { + FTexture *tex = Wads.GetLinkedTexture(lump); + if (tex == NO_TEXTURE) return FTextureID(-1); + if (tex != NULL) return tex->id; + tex = FTexture::CreateTexture("", lump, FTexture::TEX_Override); + if (tex != NULL) + { + Wads.SetLinkedTexture(lump, tex); + return AddTexture(tex); + } + else + { + // mark this lump as having no valid texture so that we don't have to retry creating one later. + Wads.SetLinkedTexture(lump, NO_TEXTURE); + } + } + } + } + return FTextureID(-1); } @@ -273,30 +302,6 @@ int FTextureManager::ListTextures (const char *name, TArray &list) return list.Size(); } -//========================================================================== -// -// FTextureManager :: FindTextureByLumpNum -// -//========================================================================== - -FTextureID FTextureManager::FindTextureByLumpNum (int lumpnum) -{ - if (lumpnum < 0) - { - return FTextureID(-1); - } - // This can't use hashing because using ReplaceTexture would break the hash chains. :( - for(unsigned i = 0; i SourceLump == lumpnum) - { - return FTextureID(i); - } - } - return FTextureID(-1); -} - - //========================================================================== // // FTextureManager :: GetTextures @@ -1093,8 +1098,15 @@ void FTextureManager::WriteTexture (FArchive &arc, int picnum) pic = Textures[picnum].Texture; } - arc.WriteName (pic->Name); - arc.WriteCount (pic->UseType); + if (Wads.GetLinkedTexture(pic->SourceLump) == pic) + { + arc.WriteName(Wads.GetLumpFullName(pic->SourceLump)); + } + else + { + arc.WriteName(pic->Name); + } + arc.WriteCount(pic->UseType); } //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 2992d8a46..8c41ee844 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -217,7 +217,6 @@ public: virtual int GetSourceLump() { return SourceLump; } virtual FTexture *GetRedirect(bool wantwarped); virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override - FTextureID GetID() const { return id; } virtual void Unload () = 0; @@ -363,12 +362,12 @@ public: TEXMAN_TryAny = 1, TEXMAN_Overridable = 2, TEXMAN_ReturnFirst = 4, - TEXMAN_AllowSkins = 8 + TEXMAN_AllowSkins = 8, + TEXMAN_ShortNameOnly = 16 }; FTextureID CheckForTexture (const char *name, int usetype, BITFIELD flags=TEXMAN_TryAny); FTextureID GetTexture (const char *name, int usetype, BITFIELD flags=0); - FTextureID FindTextureByLumpNum (int lumpnum); int ListTextures (const char *name, TArray &list); void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false); diff --git a/src/v_font.cpp b/src/v_font.cpp index abd7f494c..5fc2994fb 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -2193,19 +2193,6 @@ void V_InitCustomFonts() FTexture **p = &lumplist[*(unsigned char*)sc.String]; sc.MustGetString(); FTextureID texid = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); - if (!texid.Exists()) - { - int lumpno = Wads.CheckNumForFullName (sc.String); - if (lumpno >= 0) - { - texid = TexMan.FindTextureByLumpNum(lumpno); - if (!texid.Exists()) - { - FTexture *tex = FTexture::CreateTexture("", lumpno, FTexture::TEX_MiscPatch); - texid = TexMan.AddTexture(tex); - } - } - } if (texid.Exists()) { *p = TexMan[texid]; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 11a9b4213..c351de6f8 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -548,6 +548,37 @@ int FWadCollection::GetNumForFullName (const char *name) return i; } +//========================================================================== +// +// link a texture with a given lump +// +//========================================================================== + +void FWadCollection::SetLinkedTexture(int lump, FTexture *tex) +{ + if ((size_t)lump < NumLumps) + { + FResourceLump *reslump = LumpInfo[lump].lump; + reslump->LinkedTexture = tex; + } +} + +//========================================================================== +// +// retrieve linked texture +// +//========================================================================== + +FTexture *FWadCollection::GetLinkedTexture(int lump) +{ + if ((size_t)lump < NumLumps) + { + FResourceLump *reslump = LumpInfo[lump].lump; + return reslump->LinkedTexture; + } + return NULL; +} + //========================================================================== // // W_LumpLength diff --git a/src/w_wad.h b/src/w_wad.h index e0b21b66c..530182147 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -29,6 +29,7 @@ class FResourceFile; struct FResourceLump; +class FTexture; struct wadinfo_t { @@ -171,6 +172,9 @@ public: int CheckNumForFullName (const char *name, int wadfile); int GetNumForFullName (const char *name); + void SetLinkedTexture(int lump, FTexture *tex); + FTexture *GetLinkedTexture(int lump); + void ReadLump (int lump, void *dest); FMemLump ReadLump (int lump); From 30f57c0b8e31dbc703d15180614837a43de08177 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 21:16:06 +0200 Subject: [PATCH 197/311] - added new renderstyles AddStencil and AddShaded. --- src/g_shared/a_artifacts.cpp | 16 ++++++++++++++-- src/namedef.h | 2 ++ src/p_acs.cpp | 2 ++ src/p_udmf.cpp | 6 ++++++ src/r_data/renderstyle.cpp | 28 ++++++++++++++++------------ src/r_data/renderstyle.h | 2 ++ src/thingdef/thingdef_properties.cpp | 4 ++-- 7 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 2ef2b03c5..8891c8674 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -605,7 +605,13 @@ void APowerInvisibility::DoEffect () case (NAME_Stencil): Owner->RenderStyle = STYLE_Stencil; break; - case (NAME_None): + case (NAME_AddStencil) : + Owner->RenderStyle = STYLE_AddStencil; + break; + case (NAME_TranslucentStencil) : + Owner->RenderStyle = STYLE_TranslucentStencil; + break; + case (NAME_None) : case (NAME_Cumulative): case (NAME_Translucent): Owner->RenderStyle = STYLE_Translucent; @@ -685,7 +691,13 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) case (NAME_Stencil): vis->RenderStyle = STYLE_Stencil; break; - case (NAME_None): + case (NAME_TranslucentStencil) : + vis->RenderStyle = STYLE_TranslucentStencil; + break; + case (NAME_AddStencil) : + vis->RenderStyle = STYLE_AddStencil; + break; + case (NAME_None) : case (NAME_Cumulative): case (NAME_Translucent): default: diff --git a/src/namedef.h b/src/namedef.h index 017f29932..ba6de104d 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -30,6 +30,7 @@ xx(Cumulative) xx(Fuzzy) xx(Opaque) xx(Stencil) +xx(AddStencil) // Render styles xx(Normal) @@ -37,6 +38,7 @@ xx(SoulTrans) xx(OptFuzzy) xx(Add) xx(Shaded) +xx(AddShaded) xx(TranslucentStencil) xx(Shadow) xx(Subtract) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 04aecaed1..2929bb74b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3542,6 +3542,8 @@ static const int LegacyRenderStyleIndices[] = 3, // STYLE_SoulTrans, 4, // STYLE_OptFuzzy, 5, // STYLE_Stencil, + 6, // STYLE_AddStencil + 7, // STYLE_AddShaded 64, // STYLE_Translucent 65, // STYLE_Add, 66, // STYLE_Shaded, diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 6af777b36..2fa968502 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -658,6 +658,9 @@ public: case NAME_Stencil: th->RenderStyle = STYLE_Stencil; break; + case NAME_AddStencil: + th->RenderStyle = STYLE_AddStencil; + break; case NAME_Translucent: th->RenderStyle = STYLE_Translucent; break; @@ -668,6 +671,9 @@ public: case NAME_Shaded: th->RenderStyle = STYLE_Shaded; break; + case NAME_AddShaded: + th->RenderStyle = STYLE_AddShaded; + break; case NAME_TranslucentStencil: th->RenderStyle = STYLE_TranslucentStencil; break; diff --git a/src/r_data/renderstyle.cpp b/src/r_data/renderstyle.cpp index 660cd8f09..81524aabb 100644 --- a/src/r_data/renderstyle.cpp +++ b/src/r_data/renderstyle.cpp @@ -47,18 +47,20 @@ CVAR (Int, r_drawfuzz, 1, CVAR_ARCHIVE) #ifndef __APPLE__ FRenderStyle LegacyRenderStyles[STYLE_Count] = { - /* STYLE_None */ {{ STYLEOP_None, STYLEALPHA_Zero, STYLEALPHA_Zero, 0 }}, - /* STYLE_Normal */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 }}, - /* STYLE_Fuzzy */ {{ STYLEOP_Fuzz, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }}, - /* STYLE_SoulTrans */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_TransSoulsAlpha }}, - /* STYLE_OptFuzzy */ {{ STYLEOP_FuzzOrAdd, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }}, - /* STYLE_Stencil */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 | STYLEF_ColorIsFixed }}, - /* STYLE_Translucent */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }}, - /* STYLE_Add */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0 }}, - /* STYLE_Shaded */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed }}, -/* STYLE_TranslucentStencil */{{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed }}, - /* STYLE_Shadow */ {{ STYLEOP_Shadow, 0, 0, 0 }}, - /* STYLE_Subtract*/ {{ STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0 }}, + { { STYLEOP_None, STYLEALPHA_Zero, STYLEALPHA_Zero, 0 } }, /* STYLE_None */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 } }, /* STYLE_Normal */ + { { STYLEOP_Fuzz, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_Fuzzy */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_TransSoulsAlpha } }, /* STYLE_SoulTrans */ + { { STYLEOP_FuzzOrAdd, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_OptFuzzy */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 | STYLEF_ColorIsFixed } }, /* STYLE_Stencil */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_Translucent */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0 } }, /* STYLE_Add */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed } }, /* STYLE_Shaded */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed } }, /* STYLE_TranslucentStencil */ + { { STYLEOP_Shadow, 0, 0, 0 } }, /* STYLE_Shadow */ + { { STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0 } }, /* STYLE_Subtract*/ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_ColorIsFixed } }, /* STYLE_AddStencil */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed } }, /* STYLE_AddShaded */ }; #else FRenderStyle LegacyRenderStyles[STYLE_Count]; @@ -77,6 +79,8 @@ static const BYTE Styles[STYLE_Count * 4] = STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed, STYLEOP_Shadow, 0, 0, 0, STYLEOP_RevSub, STYLEALPHA_Src, STYLEALPHA_One, 0, + STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_Alpha1 | STYLEF_ColorIsFixed, + STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, }; static struct LegacyInit diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index bd589e8c7..3d617eff2 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -50,6 +50,8 @@ enum ERenderStyle STYLE_TranslucentStencil, STYLE_Shadow, STYLE_Subtract, // Actually this is 'reverse subtract' but this is what normal people would expect by 'subtract'. + STYLE_AddStencil, // Fill image interior with alphacolor + STYLE_AddShaded, // Treat patch data as alpha values for alphacolor STYLE_Count }; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 4e4fb4218..3b61bedca 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -797,12 +797,12 @@ DEFINE_PROPERTY(renderstyle, S, Actor) PROP_STRING_PARM(str, 0); static const char * renderstyles[]={ "NONE", "NORMAL", "FUZZY", "SOULTRANS", "OPTFUZZY", "STENCIL", - "TRANSLUCENT", "ADD", "SHADED", "SHADOW", "SUBTRACT", NULL }; + "TRANSLUCENT", "ADD", "SHADED", "SHADOW", "SUBTRACT", "ADDSTENCIL", "ADDSHADED", NULL }; static const int renderstyle_values[]={ STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy, STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded, - STYLE_Shadow, STYLE_Subtract}; + STYLE_Shadow, STYLE_Subtract, STYLE_AddStencil, STYLE_AddShaded}; // make this work for old style decorations, too. if (!strnicmp(str, "style_", 6)) str+=6; From e49e926bd95a95f963859878fbb2d2fdc074b60d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 21:26:51 +0200 Subject: [PATCH 198/311] - added option to ASectorAction to remove itself upon triggering by setting the STANDSTILL flag on the map thing. --- src/g_shared/a_sectoraction.cpp | 84 +++++++++++++++++++-------------- src/r_defs.h | 5 +- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/g_shared/a_sectoraction.cpp b/src/g_shared/a_sectoraction.cpp index ed73b5ae7..570818e19 100644 --- a/src/g_shared/a_sectoraction.cpp +++ b/src/g_shared/a_sectoraction.cpp @@ -82,10 +82,22 @@ void ASectorAction::Deactivate (AActor *source) flags2 |= MF2_DORMANT; // Projectiles can trigger } -bool ASectorAction::TriggerAction (AActor *triggerer, int activationType) +bool ASectorAction::TriggerAction(AActor *triggerer, int activationType) +{ + if (DoTriggerAction(triggerer, activationType)) + { + if (flags4 & MF4_STANDSTILL) + { + Destroy(); + } + } + return false; +} + +bool ASectorAction::DoTriggerAction (AActor *triggerer, int activationType) { if (tracer != NULL) - return barrier_cast(tracer)->TriggerAction (triggerer, activationType); + return barrier_cast(tracer)->DoTriggerAction (triggerer, activationType); else return false; } @@ -93,7 +105,7 @@ bool ASectorAction::TriggerAction (AActor *triggerer, int activationType) bool ASectorAction::CheckTrigger (AActor *triggerer) const { if (special && - (triggerer->player || + ((triggerer->player && !(flags & MF_FRIENDLY)) || ((flags & MF_AMBUSH) && (triggerer->flags2 & MF2_MCROSS)) || ((flags2 & MF2_DORMANT) && (triggerer->flags2 & MF2_PCROSS)))) { @@ -110,16 +122,16 @@ class ASecActEnter : public ASectorAction { DECLARE_CLASS (ASecActEnter, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActEnter) -bool ASecActEnter::TriggerAction (AActor *triggerer, int activationType) +bool ASecActEnter::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_Enter) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when leaving sector -------------------------------------------- @@ -128,16 +140,16 @@ class ASecActExit : public ASectorAction { DECLARE_CLASS (ASecActExit, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActExit) -bool ASecActExit::TriggerAction (AActor *triggerer, int activationType) +bool ASecActExit::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_Exit) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when hitting sector's floor ------------------------------------ @@ -146,7 +158,7 @@ class ASecActHitFloor : public ASectorAction { DECLARE_CLASS (ASecActHitFloor, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; // Skull Tag uses 9999 for a special that is triggered whenever @@ -154,10 +166,10 @@ public: IMPLEMENT_CLASS (ASecActHitFloor) -bool ASecActHitFloor::TriggerAction (AActor *triggerer, int activationType) +bool ASecActHitFloor::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_HitFloor) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when hitting sector's ceiling ---------------------------------- @@ -166,16 +178,16 @@ class ASecActHitCeil : public ASectorAction { DECLARE_CLASS (ASecActHitCeil, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActHitCeil) -bool ASecActHitCeil::TriggerAction (AActor *triggerer, int activationType) +bool ASecActHitCeil::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_HitCeiling) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when using inside sector --------------------------------------- @@ -184,16 +196,16 @@ class ASecActUse : public ASectorAction { DECLARE_CLASS (ASecActUse, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActUse) -bool ASecActUse::TriggerAction (AActor *triggerer, int activationType) +bool ASecActUse::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_Use) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when using a sector's wall ------------------------------------- @@ -202,16 +214,16 @@ class ASecActUseWall : public ASectorAction { DECLARE_CLASS (ASecActUseWall, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActUseWall) -bool ASecActUseWall::TriggerAction (AActor *triggerer, int activationType) +bool ASecActUseWall::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_UseWall) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when eyes go below fake floor ---------------------------------- @@ -220,16 +232,16 @@ class ASecActEyesDive : public ASectorAction { DECLARE_CLASS (ASecActEyesDive, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActEyesDive) -bool ASecActEyesDive::TriggerAction (AActor *triggerer, int activationType) +bool ASecActEyesDive::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_EyesDive) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when eyes go above fake floor ---------------------------------- @@ -238,16 +250,16 @@ class ASecActEyesSurface : public ASectorAction { DECLARE_CLASS (ASecActEyesSurface, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActEyesSurface) -bool ASecActEyesSurface::TriggerAction (AActor *triggerer, int activationType) +bool ASecActEyesSurface::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_EyesSurface) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when eyes go below fake floor ---------------------------------- @@ -256,16 +268,16 @@ class ASecActEyesBelowC : public ASectorAction { DECLARE_CLASS (ASecActEyesBelowC, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActEyesBelowC) -bool ASecActEyesBelowC::TriggerAction (AActor *triggerer, int activationType) +bool ASecActEyesBelowC::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_EyesBelowC) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when eyes go above fake floor ---------------------------------- @@ -274,16 +286,16 @@ class ASecActEyesAboveC : public ASectorAction { DECLARE_CLASS (ASecActEyesAboveC, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActEyesAboveC) -bool ASecActEyesAboveC::TriggerAction (AActor *triggerer, int activationType) +bool ASecActEyesAboveC::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_EyesAboveC) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } // Triggered when eyes go below fake floor ---------------------------------- @@ -292,14 +304,14 @@ class ASecActHitFakeFloor : public ASectorAction { DECLARE_CLASS (ASecActHitFakeFloor, ASectorAction) public: - bool TriggerAction (AActor *triggerer, int activationType); + bool DoTriggerAction (AActor *triggerer, int activationType); }; IMPLEMENT_CLASS (ASecActHitFakeFloor) -bool ASecActHitFakeFloor::TriggerAction (AActor *triggerer, int activationType) +bool ASecActHitFakeFloor::DoTriggerAction (AActor *triggerer, int activationType) { bool didit = (activationType & SECSPAC_HitFakeFloor) ? CheckTrigger (triggerer) : false; - return didit | Super::TriggerAction (triggerer, activationType); + return didit | Super::DoTriggerAction (triggerer, activationType); } diff --git a/src/r_defs.h b/src/r_defs.h index c2f3e5b34..2e9c0876b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -198,9 +198,10 @@ public: void BeginPlay (); void Activate (AActor *source); void Deactivate (AActor *source); - virtual bool TriggerAction (AActor *triggerer, int activationType); + bool TriggerAction(AActor *triggerer, int activationType); protected: - bool CheckTrigger (AActor *triggerer) const; + virtual bool DoTriggerAction(AActor *triggerer, int activationType); + bool CheckTrigger(AActor *triggerer) const; }; class ASkyViewpoint; From 24886b6734523df3c5b8847afb3465465299f839 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 23:16:13 +0200 Subject: [PATCH 199/311] - removed the last static character arrays from FLevelLocals. --- src/c_cmds.cpp | 19 +++++--------- src/d_net.cpp | 2 +- src/fragglescript/t_load.cpp | 6 ++--- src/g_game.cpp | 8 +++--- src/g_hexen/a_heresiarch.cpp | 2 +- src/g_level.cpp | 41 +++++++++++++----------------- src/g_level.h | 6 ++--- src/g_shared/sbarinfo_commands.cpp | 2 +- src/g_shared/shared_sbar.cpp | 2 +- src/p_acs.cpp | 12 ++++----- src/p_lnspec.cpp | 10 ++++---- src/p_setup.cpp | 2 +- src/p_setup.h | 2 +- src/p_spec.h | 4 +-- src/st_stuff.cpp | 2 +- src/statistics.cpp | 5 ++-- src/win32/i_main.cpp | 6 +---- src/zstring.h | 4 +++ 18 files changed, 61 insertions(+), 74 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 7b6f1d195..89005dbc7 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -986,14 +986,10 @@ CCMD(nextmap) TEXTCOLOR_NORMAL " is for single-player only.\n"); return; } - char *next = NULL; - if (*level.nextmap) - next = level.nextmap; - - if (next != NULL && strncmp(next, "enDSeQ", 6)) + if (level.NextMap.Len() > 0 && level.NextMap.Compare("enDSeQ", 6)) { - G_DeferedInitNew(next); + G_DeferedInitNew(level.NextMap); } else { @@ -1016,12 +1012,9 @@ CCMD(nextsecret) } char *next = NULL; - if (*level.secretmap) - next = level.secretmap; - - if (next != NULL && strncmp(next, "enDSeQ", 6)) + if (level.NextSecretMap.Len() > 0 && level.NextSecretMap.Compare("enDSeQ", 6)) { - G_DeferedInitNew(next); + G_DeferedInitNew(level.NextSecretMap); } else { @@ -1107,8 +1100,8 @@ static void PrintSecretString(const char *string, bool thislevel) CCMD(secret) { - const char *mapname = argv.argc() < 2? level.mapname : argv[1]; - bool thislevel = !stricmp(mapname, level.mapname); + const char *mapname = argv.argc() < 2? level.MapName.GetChars() : argv[1]; + bool thislevel = !stricmp(mapname, level.MapName); bool foundsome = false; int lumpno=Wads.CheckNumForName("SECRETS"); diff --git a/src/d_net.cpp b/src/d_net.cpp index 170e9ed12..a2e0798b2 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2573,7 +2573,7 @@ static void RunScript(BYTE **stream, APlayerPawn *pawn, int snum, int argn, int arg[i] = argval; } } - P_StartScript(pawn, NULL, snum, level.mapname, arg, MIN(countof(arg), argn), ACS_NET | always); + P_StartScript(pawn, NULL, snum, level.MapName, arg, MIN(countof(arg), argn), ACS_NET | always); } void Net_SkipCommand (int type, BYTE **stream) diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 49458c4be..eedb68f7c 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -202,15 +202,13 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc) { sc.MustGetStringName("="); sc.MustGetString(); - strncpy(level.nextmap, sc.String, 8); - level.nextmap[8]=0; + level.NextMap = sc.String; } else if (sc.Compare("nextsecret")) { sc.MustGetStringName("="); sc.MustGetString(); - strncpy(level.secretmap, sc.String, 8); - level.secretmap[8]=0; + level.NextSecretMap = sc.String; } else if (sc.Compare("drown")) { diff --git a/src/g_game.cpp b/src/g_game.cpp index 7875d9c3b..045b331bf 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1621,7 +1621,7 @@ void G_DoReborn (int playernum, bool freshbot) { // Reload the level from scratch bool indemo = demoplayback; BackupSaveName = ""; - G_InitNew (level.mapname, false); + G_InitNew (level.MapName, false); demoplayback = indemo; // gameaction = ga_loadlevel; } @@ -2027,7 +2027,7 @@ static void PutSaveComment (FILE *file) // Get level name //strcpy (comment, level.level_name); - mysnprintf(comment, countof(comment), "%s - %s", level.mapname, level.LevelName.GetChars()); + mysnprintf(comment, countof(comment), "%s - %s", level.MapName.GetChars(), level.LevelName.GetChars()); len = (WORD)strlen (comment); comment[len] = '\n'; @@ -2088,7 +2088,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio M_AppendPNGText (stdfile, "Engine", GAMESIG); M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG); M_AppendPNGText (stdfile, "Title", description); - M_AppendPNGText (stdfile, "Current Map", level.mapname); + M_AppendPNGText (stdfile, "Current Map", level.MapName); PutSaveWads (stdfile); PutSaveComment (stdfile); @@ -2289,7 +2289,7 @@ void G_BeginRecording (const char *startmap) if (startmap == NULL) { - startmap = level.mapname; + startmap = level.MapName; } demo_p = demobuffer; diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index b5bbced2f..15e6da9c1 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -88,7 +88,7 @@ void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags) if (script != 0) { - P_StartScript (this, NULL, script, level.mapname, NULL, 0, 0); + P_StartScript (this, NULL, script, level.MapName, NULL, 0, 0); } } diff --git a/src/g_level.cpp b/src/g_level.cpp index c3e78d223..7cbbef6e0 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -445,10 +445,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) bglobal.Init (); } - if (mapname != level.mapname) - { - strcpy (level.mapname, mapname); - } + level.MapName = mapname; if (bTitleLevel) { gamestate = GS_TITLELEVEL; @@ -491,9 +488,9 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill { // end the game levelname = NULL; - if (!strncmp(level.nextmap, "enDSeQ",6)) + if (!level.NextMap.Compare("enDSeQ",6)) { - levelname = level.nextmap; // If there is already an end sequence please leave it alone! + nextlevel = level.NextMap; // If there is already an end sequence please leave it alone! } else { @@ -596,18 +593,18 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill const char *G_GetExitMap() { - return level.nextmap; + return level.NextMap; } const char *G_GetSecretExitMap() { - const char *nextmap = level.nextmap; + const char *nextmap = level.NextMap; - if (level.secretmap[0] != 0) + if (level.NextSecretMap.Len() > 0) { - if (P_CheckMapData(level.secretmap)) + if (P_CheckMapData(level.NextSecretMap)) { - nextmap = level.secretmap; + nextmap = level.NextSecretMap; } } return nextmap; @@ -641,7 +638,7 @@ void G_DoCompleted (void) if (gamestate == GS_TITLELEVEL) { - strncpy (level.mapname, nextlevel, 255); + level.MapName = nextlevel; G_DoLoadLevel (startpos, false); startpos = 0; viewactive = true; @@ -650,20 +647,20 @@ void G_DoCompleted (void) // [RH] Mark this level as having been visited if (!(level.flags & LEVEL_CHANGEMAPCHEAT)) - FindLevelInfo (level.mapname)->flags |= LEVEL_VISITED; + FindLevelInfo (level.MapName)->flags |= LEVEL_VISITED; if (automapactive) AM_Stop (); wminfo.finished_ep = level.cluster - 1; wminfo.LName0 = TexMan[TexMan.CheckForTexture(level.info->PName, FTexture::TEX_MiscPatch)]; - wminfo.current = level.mapname; + wminfo.current = level.MapName; if (deathmatch && (dmflags & DF_SAME_LEVEL) && !(level.flags & LEVEL_CHANGEMAPCHEAT)) { - wminfo.next = level.mapname; + wminfo.next = level.MapName; wminfo.LName1 = wminfo.LName0; } else @@ -850,7 +847,7 @@ void G_DoLoadLevel (int position, bool autosave) "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" "\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n" TEXTCOLOR_BOLD "%s - %s\n\n", - level.mapname, level.LevelName.GetChars()); + level.MapName.GetChars(), level.LevelName.GetChars()); if (wipegamestate == GS_LEVEL) wipegamestate = GS_FORCEWIPE; @@ -899,7 +896,7 @@ void G_DoLoadLevel (int position, bool autosave) } level.maptime = 0; - P_SetupLevel (level.mapname, position); + P_SetupLevel (level.MapName, position); AM_LevelInit(); @@ -1056,7 +1053,7 @@ void G_DoWorldDone (void) } else { - strncpy (level.mapname, nextlevel, 255); + level.MapName = nextlevel; } G_StartTravel (); G_DoLoadLevel (startpos, true); @@ -1217,7 +1214,7 @@ void G_InitLevelLocals () level.flags = 0; level.flags2 = 0; - info = FindLevelInfo (level.mapname); + info = FindLevelInfo (level.MapName); level.info = info; level.skyspeed1 = info->skyspeed1; @@ -1274,10 +1271,8 @@ void G_InitLevelLocals () level.musicorder = info->musicorder; level.LevelName = level.info->LookupLevelName(); - strncpy (level.nextmap, info->nextmap, 10); - level.nextmap[10] = 0; - strncpy (level.secretmap, info->secretmap, 10); - level.secretmap[10] = 0; + level.NextMap = info->nextmap; + level.NextSecretMap = info->secretmap; compatflags.Callback(); compatflags2.Callback(); diff --git a/src/g_level.h b/src/g_level.h index 85a2ff0e4..cd1e9e60d 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -391,9 +391,9 @@ struct FLevelLocals int levelnum; int lumpnum; FString LevelName; - char mapname[256]; // the lump name (E1M1, MAP01, etc) - char nextmap[11]; // go here when using the regular exit - char secretmap[11]; // map to go to when used secret exit + FString MapName; // the lump name (E1M1, MAP01, etc) + FString NextMap; // go here when using the regular exit + FString NextSecretMap; // map to go to when used secret exit EMapType maptype; DWORD flags; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index a1912b21e..629c31cb4 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -830,7 +830,7 @@ class CommandDrawString : public SBarInfoCommand if(level.lumpnum != cache) { cache = level.lumpnum; - str = level.mapname; + str = level.MapName; str.ToUpper(); RealignString(); } diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 7e8e660ee..6b2f609b7 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -131,7 +131,7 @@ void ST_FormatMapName(FString &mapname, const char *mapnamecolor) if (am_showmaplabel == 1 || (am_showmaplabel == 2 && !ishub)) { - mapname << level.mapname << ": "; + mapname << level.MapName << ": "; } mapname << mapnamecolor << level.LevelName; } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2929bb74b..bd8c53edf 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6981,7 +6981,7 @@ scriptwait: break; case PRINTNAME_LEVEL: - work += level.mapname; + work += level.MapName; break; case PRINTNAME_SKILL: @@ -8950,7 +8950,7 @@ EXTERN_CVAR (Bool, sv_cheats) int P_StartScript (AActor *who, line_t *where, int script, const char *map, const int *args, int argcount, int flags) { - if (map == NULL || 0 == strnicmp (level.mapname, map, 8)) + if (map == NULL || 0 == strnicmp (level.MapName, map, 8)) { FBehavior *module = NULL; const ScriptPtr *scriptdata; @@ -9003,17 +9003,17 @@ int P_StartScript (AActor *who, line_t *where, int script, const char *map, cons return false; } -void P_SuspendScript (int script, char *map) +void P_SuspendScript (int script, const char *map) { - if (strnicmp (level.mapname, map, 8)) + if (strnicmp (level.MapName, map, 8)) addDefered (FindLevelInfo (map), acsdefered_t::defsuspend, script, NULL, 0, NULL); else SetScriptState (script, DLevelScript::SCRIPT_Suspended); } -void P_TerminateScript (int script, char *map) +void P_TerminateScript (int script, const char *map) { - if (strnicmp (level.mapname, map, 8)) + if (strnicmp (level.MapName, map, 8)) addDefered (FindLevelInfo (map), acsdefered_t::defterminate, script, NULL, 0, NULL); else SetScriptState (script, DLevelScript::SCRIPT_PleaseRemove); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 12c877116..d94a16fbb 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1644,7 +1644,7 @@ FUNC(LS_ACS_Execute) if (arg1 == 0) { - mapname = level.mapname; + mapname = level.MapName; } else if ((info = FindLevelByNum(arg1)) != NULL) { @@ -1667,7 +1667,7 @@ FUNC(LS_ACS_ExecuteAlways) if (arg1 == 0) { - mapname = level.mapname; + mapname = level.MapName; } else if ((info = FindLevelByNum(arg1)) != NULL) { @@ -1707,7 +1707,7 @@ FUNC(LS_ACS_ExecuteWithResult) int args[4] = { arg1, arg2, arg3, arg4 }; int flags = (backSide ? ACS_BACKSIDE : 0) | ACS_ALWAYS | ACS_WANTRESULT; - return P_StartScript (it, ln, arg0, level.mapname, args, 4, flags); + return P_StartScript (it, ln, arg0, level.MapName, args, 4, flags); } FUNC(LS_ACS_Suspend) @@ -1716,7 +1716,7 @@ FUNC(LS_ACS_Suspend) level_info_t *info; if (arg1 == 0) - P_SuspendScript (arg0, level.mapname); + P_SuspendScript (arg0, level.MapName); else if ((info = FindLevelByNum (arg1)) ) P_SuspendScript (arg0, info->mapname); @@ -1729,7 +1729,7 @@ FUNC(LS_ACS_Terminate) level_info_t *info; if (arg1 == 0) - P_TerminateScript (arg0, level.mapname); + P_TerminateScript (arg0, level.MapName); else if ((info = FindLevelByNum (arg1)) ) P_TerminateScript (arg0, info->mapname); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c564d1aa7..4f1329f85 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3559,7 +3559,7 @@ void P_FreeExtraLevelData() // // [RH] position indicates the start spot to spawn at -void P_SetupLevel (char *lumpname, int position) +void P_SetupLevel (const char *lumpname, int position) { cycle_t times[20]; FMapThing *buildthings; diff --git a/src/p_setup.h b/src/p_setup.h index 4a41a76f9..ee26f4c57 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -103,7 +103,7 @@ bool P_CheckMapData(const char * mapname); // [RH] The only parameter used is mapname, so I removed playermask and skill. // On September 1, 1998, I added the position to indicate which set // of single-player start spots should be spawned in the level. -void P_SetupLevel (char *mapname, int position); +void P_SetupLevel (const char *mapname, int position); void P_FreeLevelData(); void P_FreeExtraLevelData(); diff --git a/src/p_spec.h b/src/p_spec.h index 57d216972..f8dad701b 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -902,8 +902,8 @@ bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int gro #define ACS_NET 8 int P_StartScript (AActor *who, line_t *where, int script, const char *map, const int *args, int argcount, int flags); -void P_SuspendScript (int script, char *map); -void P_TerminateScript (int script, char *map); +void P_SuspendScript (int script, const char *map); +void P_TerminateScript (int script, const char *map); void P_DoDeferedScripts (void); // diff --git a/src/st_stuff.cpp b/src/st_stuff.cpp index 8679e967c..84982300c 100644 --- a/src/st_stuff.cpp +++ b/src/st_stuff.cpp @@ -484,7 +484,7 @@ static bool Cht_ChangeStartSpot (cheatseq_t *cheat) { char cmd[64]; - mysnprintf (cmd, countof(cmd), "changemap %s %c", level.mapname, cheat->Args[0]); + mysnprintf (cmd, countof(cmd), "changemap %s %c", level.MapName.GetChars(), cheat->Args[0]); C_DoCommand (cmd); return true; } diff --git a/src/statistics.cpp b/src/statistics.cpp index 81cd88983..acd8440e8 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -408,12 +408,13 @@ static void StoreLevelStats() { for(i=0;i Date: Wed, 14 May 2014 00:52:16 +0200 Subject: [PATCH 200/311] - removed 8 character limit for map names. --- src/g_level.cpp | 26 +++++++++++---------- src/g_level.h | 10 ++++---- src/g_mapinfo.cpp | 59 +++++++++++++++++++++++------------------------ src/p_acs.cpp | 2 +- src/p_lnspec.cpp | 10 ++++---- src/p_setup.cpp | 5 ++-- src/zstring.cpp | 9 +++++++- src/zstring.h | 1 + 8 files changed, 66 insertions(+), 56 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 7cbbef6e0..74a92edb5 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -506,12 +506,14 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill if (nextredir != NULL) { nextinfo = nextredir; - levelname = nextinfo->mapname; } } + nextlevel = nextinfo->MapName; + } + else + { + nextlevel = levelname; } - - if (levelname != NULL) nextlevel = levelname; if (nextSkill != -1) NextSkill = nextSkill; @@ -673,7 +675,7 @@ void G_DoCompleted (void) } else { - wminfo.next = nextinfo->mapname; + wminfo.next = nextinfo->MapName; wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->PName, FTexture::TEX_MiscPatch)]; } } @@ -1271,8 +1273,8 @@ void G_InitLevelLocals () level.musicorder = info->musicorder; level.LevelName = level.info->LookupLevelName(); - level.NextMap = info->nextmap; - level.NextSecretMap = info->secretmap; + level.NextMap = info->NextMap; + level.NextSecretMap = info->NextSecretMap; compatflags.Callback(); compatflags2.Callback(); @@ -1616,7 +1618,7 @@ static void writeMapName (FArchive &arc, const char *name) static void writeSnapShot (FArchive &arc, level_info_t *i) { arc << i->snapshotVer; - writeMapName (arc, i->mapname); + writeMapName (arc, i->MapName); i->snapshot->Serialize (arc); } @@ -1654,7 +1656,7 @@ void G_WriteSnapshots (FILE *file) { arc = new FPNGChunkArchive (file, VIST_ID); } - writeMapName (*arc, wadlevelinfos[i].mapname); + writeMapName (*arc, wadlevelinfos[i].MapName); } } @@ -1793,7 +1795,7 @@ CCMD(listsnapshots) { unsigned int comp, uncomp; snapshot->GetSizes(comp, uncomp); - Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].mapname, comp, uncomp); + Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), comp, uncomp); } } } @@ -1805,7 +1807,7 @@ CCMD(listsnapshots) static void writeDefereds (FArchive &arc, level_info_t *i) { - writeMapName (arc, i->mapname); + writeMapName (arc, i->MapName); arc << i->defered; } @@ -1917,11 +1919,11 @@ CCMD(listmaps) for(unsigned i = 0; i < wadlevelinfos.Size(); i++) { level_info_t *info = &wadlevelinfos[i]; - MapData *map = P_OpenMapData(info->mapname, true); + MapData *map = P_OpenMapData(info->MapName, true); if (map != NULL) { - Printf("%s: '%s' (%s)\n", info->mapname, info->LookupLevelName().GetChars(), + Printf("%s: '%s' (%s)\n", info->MapName.GetChars(), info->LookupLevelName().GetChars(), Wads.GetWadName(Wads.GetLumpFile(map->lumpnum))); delete map; } diff --git a/src/g_level.h b/src/g_level.h index cd1e9e60d..ebd52c8f6 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -83,7 +83,7 @@ struct FMapInfoParser void ParseLumpOrTextureName(FString &name); void ParseCluster(); - void ParseNextMap(char *mapname); + void ParseNextMap(FString &mapname); level_info_t *ParseMapHeader(level_info_t &defaultinfo); void ParseMapDefinition(level_info_t &leveldef); void ParseGameInfo(); @@ -269,9 +269,9 @@ struct level_info_t { int levelnum; - char mapname[9]; - char nextmap[11]; - char secretmap[11]; + FString MapName; + FString NextMap; + FString NextSecretMap; FString PName; FString SkyPic1; FString SkyPic2; @@ -313,7 +313,7 @@ struct level_info_t // Redirection: If any player is carrying the specified item, then // you go to the RedirectMap instead of this one. FName RedirectType; - char RedirectMap[9]; + FString RedirectMapName; FString EnterPic; FString ExitPic; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index c261e2f33..874a659c6 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -71,9 +71,10 @@ extern TMap HexenMusic; static int FindWadLevelInfo (const char *name) { for (unsigned int i = 0; i < wadlevelinfos.Size(); i++) - if (!strnicmp (name, wadlevelinfos[i].mapname, 8)) + { + if (!wadlevelinfos[i].MapName.CompareNoCase(name)) return i; - + } return -1; } @@ -144,7 +145,7 @@ bool CheckWarpTransMap (FString &mapname, bool substitute) level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4])); if (lev != NULL) { - mapname = lev->mapname; + mapname = lev->MapName; return true; } else if (substitute) @@ -224,12 +225,12 @@ void P_RemoveDefereds (void) void level_info_t::Reset() { - mapname[0] = 0; + MapName = ""; MapBackground = ""; levelnum = 0; PName = ""; - nextmap[0] = 0; - secretmap[0] = 0; + NextMap = ""; + NextSecretMap = ""; SkyPic1 = SkyPic2 = "-NOFLAT-"; cluster = 0; partime = 0; @@ -262,7 +263,7 @@ void level_info_t::Reset() compatmask = compatmask2 = 0; Translator = ""; RedirectType = 0; - RedirectMap[0] = 0; + RedirectMapName = ""; EnterPic = ""; ExitPic = ""; InterMusic = ""; @@ -299,17 +300,17 @@ FString level_info_t::LookupLevelName() char checkstring[32]; // Strip out the header from the localized string - if (mapname[0] == 'E' && mapname[2] == 'M') + if (MapName.Len() > 3 && MapName[0] == 'E' && MapName[2] == 'M') { - mysnprintf (checkstring, countof(checkstring), "%s: ", mapname); + mysnprintf (checkstring, countof(checkstring), "%s: ", MapName); } - else if (mapname[0] == 'M' && mapname[1] == 'A' && mapname[2] == 'P') + else if (MapName.Len() > 3 && MapName[0] == 'M' && MapName[1] == 'A' && MapName[2] == 'P') { - mysnprintf (checkstring, countof(checkstring), "%d: ", atoi(mapname + 3)); + mysnprintf (checkstring, countof(checkstring), "%d: ", atoi(&MapName[3])); } - else if (mapname[0] == 'L' && mapname[1] == 'E' && mapname[2] == 'V' && mapname[3] == 'E' && mapname[4] == 'L') + else if (MapName.Len() > 5 && MapName[0] == 'L' && MapName[1] == 'E' && MapName[2] == 'V' && MapName[3] == 'E' && MapName[4] == 'L') { - mysnprintf (checkstring, countof(checkstring), "%d: ", atoi(mapname + 5)); + mysnprintf (checkstring, countof(checkstring), "%d: ", atoi(&MapName[5])); } thename = strstr (lookedup, checkstring); if (thename == NULL) @@ -372,9 +373,9 @@ level_info_t *level_info_t::CheckLevelRedirect () if (playeringame[i] && players[i].mo->FindInventory (type)) { // check for actual presence of the map. - if (P_CheckMapData(RedirectMap)) + if (P_CheckMapData(RedirectMapName)) { - return FindLevelInfo(RedirectMap); + return FindLevelInfo(RedirectMapName); } break; } @@ -391,7 +392,7 @@ level_info_t *level_info_t::CheckLevelRedirect () bool level_info_t::isValid() { - return mapname[0] != 0 || this == &TheDefaultLevelInfo; + return MapName.Len() != 0 || this == &TheDefaultLevelInfo; } //========================================================================== @@ -764,29 +765,27 @@ void FMapInfoParser::ParseCluster() // //========================================================================== -void FMapInfoParser::ParseNextMap(char *mapname) +void FMapInfoParser::ParseNextMap(FString &mapname) { if (sc.CheckNumber()) { if (HexenHack) { - mysnprintf (mapname, 9, "&wt@%02d", sc.Number); + mapname.Format("&wt@%02d", sc.Number); } else { - mysnprintf (mapname, 9, "MAP%02d", sc.Number); + mapname.Format("MAP%02d", sc.Number); } } else { - *mapname = 0; sc.MustGetString(); - strncpy (mapname, sc.String, 8); - mapname[8] = 0; + mapname = sc.String; FName seq = CheckEndSequence(); if (seq != NAME_None) { - mysnprintf(mapname, 11, "enDSeQ%04x", int(seq)); + mapname.Format("enDSeQ%04x", int(seq)); } } } @@ -807,19 +806,19 @@ DEFINE_MAP_OPTION(levelnum, true) DEFINE_MAP_OPTION(next, true) { parse.ParseAssign(); - parse.ParseNextMap(info->nextmap); + parse.ParseNextMap(info->NextMap); } DEFINE_MAP_OPTION(secretnext, true) { parse.ParseAssign(); - parse.ParseNextMap(info->secretmap); + parse.ParseNextMap(info->NextSecretMap); } DEFINE_MAP_OPTION(secret, true) // Just an alias for secretnext, for Vavoom compatibility { parse.ParseAssign(); - parse.ParseNextMap(info->secretmap); + parse.ParseNextMap(info->NextSecretMap); } DEFINE_MAP_OPTION(cluster, true) @@ -1072,7 +1071,7 @@ DEFINE_MAP_OPTION(redirect, true) parse.sc.MustGetString(); info->RedirectType = parse.sc.String; parse.ParseComma(); - parse.ParseLumpOrTextureName(info->RedirectMap); + parse.ParseNextMap(info->RedirectMapName); } DEFINE_MAP_OPTION(sndseq, true) @@ -1522,8 +1521,8 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) } - uppercopy (levelinfo->mapname, mapname); - levelinfo->mapname[8] = 0; + levelinfo->MapName = mapname; + levelinfo->MapName.ToUpper(); sc.MustGetString (); if (sc.String[0] == '$') { @@ -1543,7 +1542,7 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) // Set up levelnum now so that you can use Teleport_NewMap specials // to teleport to maps with standard names without needing a levelnum. - levelinfo->levelnum = GetDefaultLevelNum(levelinfo->mapname); + levelinfo->levelnum = GetDefaultLevelNum(levelinfo->MapName); // Does this map have a song defined via SNDINFO's $map command? // Set that as this map's default music if it does. diff --git a/src/p_acs.cpp b/src/p_acs.cpp index bd8c53edf..9469da06e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8942,7 +8942,7 @@ static void addDefered (level_info_t *i, acsdefered_t::EType type, int script, c def->playernum = -1; } i->defered = def; - DPrintf ("%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->mapname); + DPrintf ("%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->MapName.GetChars()); } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index d94a16fbb..7cb5ca7e6 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -863,7 +863,7 @@ FUNC(LS_Teleport_NewMap) if (info && CheckIfExitIsGood (it, info)) { - G_ChangeLevel(info->mapname, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); + G_ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); return true; } } @@ -1648,7 +1648,7 @@ FUNC(LS_ACS_Execute) } else if ((info = FindLevelByNum(arg1)) != NULL) { - mapname = info->mapname; + mapname = info->MapName; } else { @@ -1671,7 +1671,7 @@ FUNC(LS_ACS_ExecuteAlways) } else if ((info = FindLevelByNum(arg1)) != NULL) { - mapname = info->mapname; + mapname = info->MapName; } else { @@ -1718,7 +1718,7 @@ FUNC(LS_ACS_Suspend) if (arg1 == 0) P_SuspendScript (arg0, level.MapName); else if ((info = FindLevelByNum (arg1)) ) - P_SuspendScript (arg0, info->mapname); + P_SuspendScript (arg0, info->MapName); return true; } @@ -1731,7 +1731,7 @@ FUNC(LS_ACS_Terminate) if (arg1 == 0) P_TerminateScript (arg0, level.MapName); else if ((info = FindLevelByNum (arg1)) ) - P_TerminateScript (arg0, info->mapname); + P_TerminateScript (arg0, info->MapName); return true; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 4f1329f85..c2aa47faa 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -272,11 +272,12 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) FString fmt; int lump_wad; int lump_map; - int lump_name; + int lump_name = -1; // Check for both *.wad and *.map in order to load Build maps // as well. The higher one will take precedence. - lump_name = Wads.CheckNumForName(mapname); + // Names with more than 8 characters will only be checked as .wad and .map. + if (strlen(mapname) <= 8) lump_name = Wads.CheckNumForName(mapname); fmt.Format("maps/%s.wad", mapname); lump_wad = Wads.CheckNumForFullName(fmt); fmt.Format("maps/%s.map", mapname); diff --git a/src/zstring.cpp b/src/zstring.cpp index dc171f398..14d19f46f 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -349,7 +349,14 @@ FString &FString::AppendCStrPart (const char *tail, size_t tailLen) return *this; } -void FString::Truncate (long newlen) +FString &FString::CopyCStrPart(const char *tail, size_t tailLen) +{ + ReallocBuffer(tailLen); + StrCopy(Chars, tail, tailLen); + return *this; +} + +void FString::Truncate(long newlen) { if (newlen >= 0 && newlen < (long)Len()) { diff --git a/src/zstring.h b/src/zstring.h index 874417a09..1736f3421 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -167,6 +167,7 @@ public: FString &operator += (char tail); FString &operator += (const FName &name) { return *this += name.GetChars(); } FString &AppendCStrPart (const char *tail, size_t tailLen); + FString &CopyCStrPart(const char *tail, size_t tailLen); FString &operator << (const FString &tail) { return *this += tail; } FString &operator << (const char *tail) { return *this += tail; } From fdfcb728a970113548f6aafb425fc77eacecdfad Mon Sep 17 00:00:00 2001 From: Shawn Walker Date: Tue, 13 May 2014 22:50:39 -0700 Subject: [PATCH 201/311] - make it easier to spot patch definition errors in console log --- src/textures/multipatchtexture.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 124add5db..d72391341 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -47,6 +47,7 @@ #include "colormatcher.h" #include "v_palette.h" #include "v_video.h" +#include "v_text.h" #include "m_fixed.h" #include "textures/textures.h" #include "r_data/colormaps.h" @@ -275,7 +276,7 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; if (Parts[i].Texture == NULL) { - Printf ("Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); + Printf (TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); NumParts--; i--; } @@ -1018,7 +1019,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, i } if (part.Texture == NULL) { - if (!silent) Printf("Unknown patch '%s' in texture '%s'\n", sc.String, Name); + if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); } sc.MustGetStringName(","); sc.MustGetNumber(); From 8c052818b7acdc428a590a0c0cd8922d5c7aeb94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 10:27:40 +0200 Subject: [PATCH 202/311] - fixed: long texture name lookup did not work with TEXMAN_TryAny. --- src/textures/texturemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 0af15d7af..9ff67803d 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -220,8 +220,8 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF { if (firsttype == FTexture::TEX_Null) return FTextureID(0); if (firsttype == FTexture::TEX_FirstDefined && !(flags & TEXMAN_ReturnFirst)) return FTextureID(0); + return FTextureID(firstfound); } - return FTextureID(firstfound); } From 47a9dab56d74fe021f454bccec91e57715f6db94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 12:16:33 +0200 Subject: [PATCH 203/311] - allow setting sector planes' plane equations directly from UDMF. --- specs/udmf_zdoom.txt | 14 +++++++++- src/namedef.h | 9 ++++++ src/p_udmf.cpp | 65 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index d7face672..1128b2e55 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -37,7 +37,7 @@ In addition to the base specification ZDoom recognizes the following lumps between the TEXTMAP and ENDMAP lumps: BEHAVIOR = contains compiled ACS code - DIALOGUE = contains compiled Strife conversation scripts. + DIALOGUE = contains compiled Strife or USDF conversation scripts. ZNODES = Nodes (must be stored as extended GL nodes. Compression is allowed but deprecated for portability reasons.) BLOCKMAP = blockmap. It is recommended not to include this lump in UDMF maps. @@ -166,6 +166,14 @@ Note: All fields default to false unless mentioned otherwise. yscaleceiling = ; // Y texture scale of ceiling texture, Default = 1.0. rotationfloor = ; // Rotation of floor texture in degrees, Default = 0.0. rotationceiling = ; // Rotation of ceiling texture in degrees, Default = 0.0. + ceilingplane_a = ; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'. + ceilingplane_b = ; // 'heightceiling' will still be used to calculate texture alignment. + ceilingplane_c = ; // The plane equation will only be used if all 4 values are given. + ceilingplane_d = ; + floorplane_a = ; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'. + floorplane_b = ; // 'heightfloor' will still be used to calculate texture alignment. + floorplane_c = ; // The plane equation will only be used if all 4 values are given. + floorplane_d = ; lightfloor = ; // The floor's light level. Default is 0. lightceiling = ; // The ceiling's light level. Default is 0. lightfloorabsolute = ; // true = 'lightfloor' is an absolute value. Default is @@ -355,6 +363,10 @@ Added waterzone sector property. 1.22 12.04.2014 Added transparent line property (to be folded back to core UDMF standard), and health, score, renderstyle, fillcolor, alpha, scale, scalex, scaley, pitch and roll thing properties. +1.24 14.05.2014 +Added plane equations for sector slopes. (Please read carefully to ensure proper use!) +Changed language describing the DIALOGUE lump to mention USDF as an option. + =============================================================================== EOF =============================================================================== diff --git a/src/namedef.h b/src/namedef.h index ba6de104d..a4c8da638 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -488,6 +488,15 @@ xx(blockhitscan) xx(Renderstyle) +xx(ceilingplane_a) +xx(ceilingplane_b) +xx(ceilingplane_c) +xx(ceilingplane_d) +xx(floorplane_a) +xx(floorplane_b) +xx(floorplane_c) +xx(floorplane_d) + // USDF keywords xx(Amount) xx(Text) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 2fa968502..0c380160d 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1245,6 +1245,7 @@ public: int lightcolor = -1; int fadecolor = -1; int desaturation = -1; + int fplaneflags = 0, cplaneflags = 0; memset(sec, 0, sizeof(*sec)); sec->lightlevel = 160; @@ -1446,6 +1447,48 @@ public: Flag(sec->MoreFlags, SECF_UNDERWATER, key); break; + case NAME_floorplane_a: + fplaneflags |= 1; + sec->floorplane.a = CheckFixed(key); + break; + + case NAME_floorplane_b: + fplaneflags |= 2; + sec->floorplane.b = CheckFixed(key); + break; + + case NAME_floorplane_c: + fplaneflags |= 4; + sec->floorplane.c = CheckFixed(key); + sec->floorplane.ic = FixedDiv(FRACUNIT, sec->floorplane.c); + break; + + case NAME_floorplane_d: + fplaneflags |= 8; + sec->floorplane.d = CheckFixed(key); + break; + + case NAME_ceilingplane_a: + cplaneflags |= 1; + sec->ceilingplane.a = CheckFixed(key); + break; + + case NAME_ceilingplane_b: + cplaneflags |= 2; + sec->ceilingplane.b = CheckFixed(key); + break; + + case NAME_ceilingplane_c: + cplaneflags |= 4; + sec->ceilingplane.c = CheckFixed(key); + sec->ceilingplane.ic = FixedDiv(FRACUNIT, sec->ceilingplane.c); + break; + + case NAME_ceilingplane_d: + cplaneflags |= 8; + sec->ceilingplane.d = CheckFixed(key); + break; + default: break; } @@ -1457,12 +1500,22 @@ public: } sec->secretsector = !!(sec->special&SECRET_MASK); - sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); - sec->floorplane.c = FRACUNIT; - sec->floorplane.ic = FRACUNIT; - sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); - sec->ceilingplane.c = -FRACUNIT; - sec->ceilingplane.ic = -FRACUNIT; + + // Reset the planes to their defaults if not all of the plane equation's parameters were found. + if (fplaneflags != 15) + { + sec->floorplane.a = sec->floorplane.b = 0; + sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); + sec->floorplane.c = FRACUNIT; + sec->floorplane.ic = FRACUNIT; + } + if (cplaneflags != 15) + { + sec->ceilingplane.a = sec->ceilingplane.b = 0; + sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); + sec->ceilingplane.c = -FRACUNIT; + sec->ceilingplane.ic = -FRACUNIT; + } if (lightcolor == -1 && fadecolor == -1 && desaturation == -1) { From 388f09f786d5ab3927d3bb6d76895b043a18bdb6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 12:54:03 +0200 Subject: [PATCH 204/311] - fixed: In Heretic corpses do not get crunched to gibs, they just get their size reduced to 0. Handled by a new gameinfo flag. This also gets set for Chex quest which has the gib sprite replaced by something different. Using a Crush state will override this global flag. --- src/gi.cpp | 1 + src/gi.h | 1 + src/p_mobj.cpp | 10 ++++++++++ wadsrc/static/mapinfo/chex.txt | 1 + wadsrc/static/mapinfo/heretic.txt | 1 + 5 files changed, 14 insertions(+) diff --git a/src/gi.cpp b/src/gi.cpp index 8ab935854..4e64dd425 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -323,6 +323,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis") GAMEINFOKEY_BOOL(swapmenu, "swapmenu") + GAMEINFOKEY_BOOL(dontcrunchcorpses, "dontcrunchcorpses") GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter") GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast") GAMEINFOKEY_COLOR(dimcolor, "dimcolor") diff --git a/src/gi.h b/src/gi.h index a1a03b2de..bbfbe73ff 100644 --- a/src/gi.h +++ b/src/gi.h @@ -113,6 +113,7 @@ struct gameinfo_t bool intermissioncounter; bool nightmarefast; bool swapmenu; + bool dontcrunchcorpses; TArray creditPages; TArray finalePages; TArray infoPages; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c6a7fd35c..72679ef71 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1010,6 +1010,16 @@ bool AActor::Grind(bool items) if ((flags & MF_CORPSE) && !(flags3 & MF3_DONTGIB) && (health <= 0)) { FState * state = FindState(NAME_Crush); + + // In Heretic and Chex Quest we don't change the actor's sprite, just its size. + if (state == NULL && gameinfo.dontcrunchcorpses) + { + flags &= ~MF_SOLID; + flags3 |= MF3_DONTGIB; + height = radius = 0; + return false; + } + bool isgeneric = false; // ZDoom behavior differs from standard as crushed corpses cannot be raised. // The reason for the change was originally because of a problem with players, diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index edc5b4f29..e29eeeb4d 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -40,6 +40,7 @@ gameinfo definventorymaxamount = 25 defaultrespawntime = 12 defaultdropstyle = 1 + dontcrunchcorpses = 1 endoom = "ENDOOM" player5start = 4001 drawreadthis = true diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 196e81c50..d372466f5 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -56,6 +56,7 @@ gameinfo nightmarefast = true pausesign = "PAUSED" gibfactor = 0.5 + dontcrunchcorpses = true cursorpic = "herecurs" textscreenx = 20 textscreeny = 5 From 51ed68dc7243cf00c285526a8009a2fa2d4c427d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 13:02:04 +0200 Subject: [PATCH 205/311] - forgot to save this... --- wadsrc/static/mapinfo/chex.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index e29eeeb4d..1edaf9256 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -40,7 +40,7 @@ gameinfo definventorymaxamount = 25 defaultrespawntime = 12 defaultdropstyle = 1 - dontcrunchcorpses = 1 + dontcrunchcorpses = true endoom = "ENDOOM" player5start = 4001 drawreadthis = true From 85fb8c4326a0f5ca010f0495275d04ccd4d8860e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 13:04:47 +0200 Subject: [PATCH 206/311] - fixed: _M_X64 macro was misnamed _M_IX64. --- src/nodebuild.h | 2 +- src/x86.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nodebuild.h b/src/nodebuild.h index 81c7b1345..ce68c4682 100644 --- a/src/nodebuild.h +++ b/src/nodebuild.h @@ -347,7 +347,7 @@ inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const #ifdef DISABLE_SSE return ClassifyLine2 (node, v1, v2, sidev); #else -#if defined(__SSE2__) || defined(_M_IX64) +#if defined(__SSE2__) || defined(_M_X64) // If compiling with SSE2 support everywhere, just use the SSE2 version. return ClassifyLineSSE2 (node, v1, v2, sidev); #elif defined(_MSC_VER) && _MSC_VER < 1300 diff --git a/src/x86.cpp b/src/x86.cpp index ec36aae93..89d88333d 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -299,7 +299,7 @@ void DoBlending_SSE2(const PalEntry *from, PalEntry *to, int count, int r, int g } #endif -#if defined(__amd64__) || defined(_M_IX64) +#if defined(__amd64__) || defined(_M_X64) long long color; blending256 = _mm_set_epi64x(0x10001000100ll, 0x10001000100ll); From 802a47876602251c9c7ec6bd7f63da21c3d24165 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 14:03:15 +0200 Subject: [PATCH 207/311] - Heretic doesn't really need dontcrunchcorpses because there was already some alternative handling for that situation. --- wadsrc/static/mapinfo/heretic.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index d372466f5..196e81c50 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -56,7 +56,6 @@ gameinfo nightmarefast = true pausesign = "PAUSED" gibfactor = 0.5 - dontcrunchcorpses = true cursorpic = "herecurs" textscreenx = 20 textscreeny = 5 From 2944e4f6ae8601ca567baafbe9b6e80daae138a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 14:08:14 +0200 Subject: [PATCH 208/311] - fixed some Linux issues with recent changes. --- src/sdl/i_main.cpp | 6 +----- src/textures/texturemanager.cpp | 2 +- src/wi_stuff.cpp | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 1736305d8..db6979330 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -172,11 +172,7 @@ static int DoomSpecificInfo (char *buffer, char *end) } else { - char name[9]; - - strncpy (name, level.mapname, 8); - name[8] = 0; - p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", name); + p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", level.MapName); if (!viewactive) { diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 9ff67803d..aa9ef706b 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -233,7 +233,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF { FTexture *const NO_TEXTURE = (FTexture*)-1; int lump = Wads.CheckNumForFullName(name); - if (lump != NULL) + if (lump >= 0) { FTexture *tex = Wads.GetLinkedTexture(lump); if (tex == NO_TEXTURE) return FTextureID(-1); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 0cf5e7b77..982668566 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -314,7 +314,7 @@ static bool IsExMy(const char * name) void WI_LoadBackground(bool isenterpic) { - const char *lumpname; + const char *lumpname = NULL; char buffer[10]; in_anim_t an; lnode_t pt; From adcdc11360c9672105c9c8fabb989247d1f2cd40 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 15:44:05 +0200 Subject: [PATCH 209/311] - GCC compile fix. --- src/sdl/i_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index db6979330..3c721ae51 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -172,7 +172,7 @@ static int DoomSpecificInfo (char *buffer, char *end) } else { - p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", level.MapName); + p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", level.MapName.GetChars()); if (!viewactive) { From e3cd144af9692192accb853691a6ccf4a6d5ae2d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 14 May 2014 17:27:22 +0200 Subject: [PATCH 210/311] - one last GCC compile problem. --- src/g_mapinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 874a659c6..7203fdb51 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -302,7 +302,7 @@ FString level_info_t::LookupLevelName() // Strip out the header from the localized string if (MapName.Len() > 3 && MapName[0] == 'E' && MapName[2] == 'M') { - mysnprintf (checkstring, countof(checkstring), "%s: ", MapName); + mysnprintf (checkstring, countof(checkstring), "%s: ", MapName.GetChars()); } else if (MapName.Len() > 3 && MapName[0] == 'M' && MapName[1] == 'A' && MapName[2] == 'P') { From bf6a193e5bc3806131e0f7b9493274003c142bed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 15 May 2014 20:29:36 +0200 Subject: [PATCH 211/311] - fixed: The episode parser was still truncating its map names to 8 characters. --- src/g_level.h | 2 +- src/g_mapinfo.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/g_level.h b/src/g_level.h index ebd52c8f6..0cd366798 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -79,7 +79,7 @@ struct FMapInfoParser bool ParseLookupName(FString &dest); void ParseMusic(FString &name, int &order); - void ParseLumpOrTextureName(char *name); + //void ParseLumpOrTextureName(char *name); void ParseLumpOrTextureName(FString &name); void ParseCluster(); diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 7203fdb51..b7aa77e1c 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -622,12 +622,14 @@ bool FMapInfoParser::ParseLookupName(FString &dest) // //========================================================================== +/* void FMapInfoParser::ParseLumpOrTextureName(char *name) { sc.MustGetString(); uppercopy(name, sc.String); name[8]=0; } +*/ void FMapInfoParser::ParseLumpOrTextureName(FString &name) { @@ -1572,7 +1574,7 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) void FMapInfoParser::ParseEpisodeInfo () { unsigned int i; - char map[9]; + FString map; FString pic; FString name; bool remove = false; @@ -1583,15 +1585,14 @@ void FMapInfoParser::ParseEpisodeInfo () // Get map name sc.MustGetString (); - uppercopy (map, sc.String); - map[8] = 0; + map = sc.String; if (sc.CheckString ("teaser")) { sc.MustGetString (); if (gameinfo.flags & GI_SHAREWARE) { - uppercopy (map, sc.String); + map = sc.String; } } From 25f4af734fa73006fa48c6463ce09c9b84aa1368 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 16 May 2014 10:56:23 +0200 Subject: [PATCH 212/311] - fixed: ACS's check...Texture functions must use the same search flags as the texture initialization code in p_setup.cpp and p_udmf.cpp. It also should not create textures that don't exist yet. We are only doing a comparison so it's not relevant if the texture exists or not. --- src/p_acs.cpp | 4 +++- src/textures/texturemanager.cpp | 1 + src/textures/textures.h | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 9469da06e..981870a36 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3944,7 +3944,9 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b { return 0; } - FTexture *tex = TexMan.FindTexture(FBehavior::StaticLookupString(string)); + FTexture *tex = TexMan.FindTexture(FBehavior::StaticLookupString(string), FTexture::TEX_Flat, + FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_DontCreate); + if (tex == NULL) { // If the texture we want to check against doesn't exist, then // they're obviously not the same. diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index aa9ef706b..6fb963e42 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -238,6 +238,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF FTexture *tex = Wads.GetLinkedTexture(lump); if (tex == NO_TEXTURE) return FTextureID(-1); if (tex != NULL) return tex->id; + if (flags & TEXMAN_DontCreate) return FTextureID(-1); // we only want to check, there's no need to create a texture if we don't have one yet. tex = FTexture::CreateTexture("", lump, FTexture::TEX_Override); if (tex != NULL) { diff --git a/src/textures/textures.h b/src/textures/textures.h index 8c41ee844..15c9bce5c 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -363,7 +363,8 @@ public: TEXMAN_Overridable = 2, TEXMAN_ReturnFirst = 4, TEXMAN_AllowSkins = 8, - TEXMAN_ShortNameOnly = 16 + TEXMAN_ShortNameOnly = 16, + TEXMAN_DontCreate = 32 }; FTextureID CheckForTexture (const char *name, int usetype, BITFIELD flags=TEXMAN_TryAny); From d3dcc04666f8179b16ef4fd8624ac68ec441f3b8 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 17 May 2014 00:35:27 +1200 Subject: [PATCH 213/311] Fix nettic run-out at end of demo playback --- src/d_net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index a2e0798b2..f1b476108 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1054,7 +1054,7 @@ void NetUpdate (void) if (demoplayback) { - nettics[0] = (maketic / ticdup); + resendto[0] = nettics[0] = (maketic / ticdup); return; // Don't touch netcmd data while playing a demo, as it'll already exist. } From e92032e8ffe73da1ce3fe61c94fc2f7e447a09d7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 16 May 2014 22:48:37 +0200 Subject: [PATCH 214/311] - fixed: The map setup code was still truncating texture names in several places. --- src/doomdata.h | 8 ++++++++ src/p_setup.cpp | 50 ++++++++++++++++++++++++------------------------- src/p_udmf.cpp | 26 ++++++++++++------------- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index 9cedf8cdc..215c2a263 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -85,6 +85,14 @@ struct mapsidedef_t short sector; // Front sector, towards viewer. }; +struct intmapsidedef_t +{ + FString toptexture; + FString bottomtexture; + FString midtexture; +}; + + // A LineDef, as used for editing, and as input to the BSP builder. struct maplinedef_t { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c2aa47faa..a6462f31c 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -577,13 +577,11 @@ void MapData::GetChecksum(BYTE cksum[16]) // //=========================================================================== -static void SetTexture (side_t *side, int position, const char *name8, FMissingTextureTracker &track) +static void SetTexture (side_t *side, int position, const char *name, FMissingTextureTracker &track) { static const char *positionnames[] = { "top", "middle", "bottom" }; static const char *sidenames[] = { "first", "second" }; - char name[9]; - strncpy (name, name8, 8); - name[8] = 0; + FTextureID texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny); @@ -619,12 +617,17 @@ static void SetTexture (side_t *side, int position, const char *name8, FMissingT // //=========================================================================== -void SetTexture (sector_t *sector, int index, int position, const char *name8, FMissingTextureTracker &track) +void SetTexture (sector_t *sector, int index, int position, const char *name, FMissingTextureTracker &track, bool truncate) { static const char *positionnames[] = { "floor", "ceiling" }; - char name[9]; - strncpy (name, name8, 8); - name[8] = 0; + char name8[9]; + if (truncate) + { + strncpy(name8, name, 8); + name8[8] = 0; + name = name8; + } + FTextureID texture = TexMan.CheckForTexture (name, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny); @@ -674,11 +677,8 @@ static void SummarizeMissingTextures(const FMissingTextureTracker &missing) // //=========================================================================== -static void SetTexture (side_t *side, int position, DWORD *blend, char *name8) +static void SetTexture (side_t *side, int position, DWORD *blend, const char *name) { - char name[9]; - strncpy (name, name8, 8); - name[8] = 0; FTextureID texture; if ((*blend = R_ColormapNumForName (name)) == 0) { @@ -705,12 +705,9 @@ static void SetTexture (side_t *side, int position, DWORD *blend, char *name8) side->SetTexture(position, texture); } -static void SetTextureNoErr (side_t *side, int position, DWORD *color, char *name8, bool *validcolor, bool isFog) +static void SetTextureNoErr (side_t *side, int position, DWORD *color, const char *name, bool *validcolor, bool isFog) { - char name[9]; FTextureID texture; - strncpy (name, name8, 8); - name[8] = 0; *validcolor = false; texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny); @@ -1515,8 +1512,8 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->ceilingplane.d = ss->GetPlaneTexZ(sector_t::ceiling); ss->ceilingplane.c = -FRACUNIT; ss->ceilingplane.ic = -FRACUNIT; - SetTexture(ss, i, sector_t::floor, ms->floorpic, missingtex); - SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic, missingtex); + SetTexture(ss, i, sector_t::floor, ms->floorpic, missingtex, true); + SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic, missingtex, true); ss->lightlevel = LittleShort(ms->lightlevel); if (map->HasBehavior) ss->special = LittleShort(ms->special); @@ -2473,11 +2470,8 @@ int P_DetermineTranslucency (int lumpnum) return newcolor.r; } -void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &missingtex) +void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, intmapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &missingtex) { - char name[9]; - name[8] = 0; - switch (special) { case Transfer_Heights: // variable colormap via 242 linedef @@ -2503,7 +2497,6 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture, &foggood, true); SetTextureNoErr (sd, side_t::top, &color, msd->toptexture, &colorgood, false); - strncpy (name, msd->midtexture, 8); SetTexture(sd, side_t::mid, msd->midtexture, missingtex); if (colorgood | foggood) @@ -2534,8 +2527,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside case Sector_Set3DFloor: if (msd->toptexture[0]=='#') { - strncpy (name, msd->toptexture, 8); - sd->SetTexture(side_t::top, FNullTextureID() +(-strtol(name+1, NULL, 10))); // store the alpha as a negative texture index + sd->SetTexture(side_t::top, FNullTextureID() +(-strtol(&msd->toptexture[1], NULL, 10))); // store the alpha as a negative texture index // This will be sorted out by the 3D-floor code later. } else @@ -2629,7 +2621,13 @@ void P_LoadSideDefs2 (MapData *map, FMissingTextureTracker &missingtex) { sd->sector = sec = §ors[LittleShort(msd->sector)]; } - P_ProcessSideTextures(!map->HasBehavior, sd, sec, msd, + + intmapsidedef_t imsd; + imsd.toptexture.CopyCStrPart(msd->toptexture, 8); + imsd.midtexture.CopyCStrPart(msd->midtexture, 8); + imsd.bottomtexture.CopyCStrPart(msd->bottomtexture, 8); + + P_ProcessSideTextures(!map->HasBehavior, sd, sec, &imsd, sidetemp[i].a.special, sidetemp[i].a.tag, &sidetemp[i].a.alpha, missingtex); } delete[] msdf; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 0c380160d..19dfdf08c 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -118,8 +118,8 @@ enum // namespace for each game }; -void SetTexture (sector_t *sector, int index, int position, const char *name8, FMissingTextureTracker &); -void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &); +void SetTexture (sector_t *sector, int index, int position, const char *name, FMissingTextureTracker &, bool truncate); +void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, intmapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &); void P_AdjustLine (line_t *ld); void P_FinishLoadingLineDef(line_t *ld, int alpha); void SpawnMapThing(int index, FMapThing *mt, int position); @@ -394,7 +394,7 @@ class UDMFParser : public UDMFParserBase TArray ParsedLines; TArray ParsedSides; - TArray ParsedSideTextures; + TArray ParsedSideTextures; TArray ParsedSectors; TArray ParsedVertices; TArray ParsedVertexDatas; @@ -1089,14 +1089,14 @@ public: // //=========================================================================== - void ParseSidedef(side_t *sd, mapsidedef_t *sdt, int index) + void ParseSidedef(side_t *sd, intmapsidedef_t *sdt, int index) { fixed_t texofs[2]={0,0}; memset(sd, 0, sizeof(*sd)); - strncpy(sdt->bottomtexture, "-", 8); - strncpy(sdt->toptexture, "-", 8); - strncpy(sdt->midtexture, "-", 8); + sdt->bottomtexture = "-"; + sdt->toptexture = "-"; + sdt->midtexture = "-"; sd->SetTextureXScale(FRACUNIT); sd->SetTextureYScale(FRACUNIT); @@ -1115,15 +1115,15 @@ public: continue; case NAME_Texturetop: - strncpy(sdt->toptexture, CheckString(key), 8); + sdt->toptexture = CheckString(key); continue; case NAME_Texturebottom: - strncpy(sdt->bottomtexture, CheckString(key), 8); + sdt->bottomtexture = CheckString(key); continue; case NAME_Texturemiddle: - strncpy(sdt->midtexture, CheckString(key), 8); + sdt->midtexture = CheckString(key); continue; case NAME_Sector: @@ -1287,11 +1287,11 @@ public: continue; case NAME_Texturefloor: - SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex); + SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex, false); continue; case NAME_Textureceiling: - SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex); + SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex, false); continue; case NAME_Lightlevel: @@ -1799,7 +1799,7 @@ public: else if (sc.Compare("sidedef")) { side_t si; - mapsidedef_t st; + intmapsidedef_t st; ParseSidedef(&si, &st, ParsedSides.Size()); ParsedSides.Push(si); ParsedSideTextures.Push(st); From ff7913ace8156cd8bfda3533f3afcb77897d1646 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 17 May 2014 09:46:58 +0200 Subject: [PATCH 215/311] - fixed: When a level gets loaded the renderer's sky variables need to be set. --- src/g_level.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/g_level.cpp b/src/g_level.cpp index 74a92edb5..8c97a399c 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1410,6 +1410,8 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } if (arc.IsLoading()) { + sky1texture = level.skytexture1; + sky2texture = level.skytexture2; R_InitSkyMap(); } From 26b1abe3dab611001b49ce717853b0accd8c5516 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 18 May 2014 18:37:34 +1200 Subject: [PATCH 216/311] Fix netgame arbitration with long map lump names --- src/d_net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index f1b476108..1600d9102 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1385,7 +1385,7 @@ bool DoArbitrate (void *userdata) stream = &netbuffer[4]; s = ReadString (&stream); - startmap = FString(s, 8); + startmap = FString(s, strlen(s)); delete[] s; rngseed = ReadLong (&stream); C_ReadCVars (&stream); From cfef89486740cdfca0682dcc60caf2b3cdb5bbc9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 May 2014 09:41:13 +0200 Subject: [PATCH 217/311] This can be done better... --- src/d_net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 1600d9102..60a2b61c4 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1385,7 +1385,7 @@ bool DoArbitrate (void *userdata) stream = &netbuffer[4]; s = ReadString (&stream); - startmap = FString(s, strlen(s)); + startmap = s; delete[] s; rngseed = ReadLong (&stream); C_ReadCVars (&stream); From 4acc04ce68f37a1340de81f0d754fe8951fa47ca Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 18 May 2014 10:05:35 +0200 Subject: [PATCH 218/311] - don't truncate map names stored in demos. --- src/g_game.cpp | 28 +++++++++++++++++----------- src/version.h | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 045b331bf..65fa5733d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2302,11 +2302,10 @@ void G_BeginRecording (const char *startmap) WriteWord (DEMOGAMEVERSION, &demo_p); // Write ZDoom version *demo_p++ = 2; // Write minimum version needed to use this demo. *demo_p++ = 3; // (Useful?) - for (i = 0; i < 8; i++) // Write name of map demo was recorded on. - { - *demo_p++ = startmap[i]; - } - WriteLong (rngseed, &demo_p); // Write RNG seed + + strcpy((char*)demo_p, startmap); // Write name of map demo was recorded on. + demo_p += strlen(startmap) + 1; + WriteLong(rngseed, &demo_p); // Write RNG seed *demo_p++ = consoleplayer; FinishChunk (&demo_p); @@ -2385,7 +2384,7 @@ CCMD (timedemo) // [RH] Process all the information in a FORM ZDEM // until a BODY chunk is entered. -bool G_ProcessIFFDemo (char *mapname) +bool G_ProcessIFFDemo (FString &mapname) { bool headerHit = false; bool bodyHit = false; @@ -2441,9 +2440,16 @@ bool G_ProcessIFFDemo (char *mapname) Printf ("Demo requires a newer version of ZDoom!\n"); return true; } - memcpy (mapname, demo_p, 8); // Read map name - mapname[8] = 0; - demo_p += 8; + if (demover >= 0x21a) + { + mapname = (char*)demo_p; + demo_p += mapname.Len() + 1; + } + else + { + mapname = FString((char*)demo_p, 8); + demo_p += 8; + } rngseed = ReadLong (&demo_p); // Only reset the RNG if this demo is not in conjunction with a savegame. if (mapname[0] != 0) @@ -2525,7 +2531,7 @@ bool G_ProcessIFFDemo (char *mapname) void G_DoPlayDemo (void) { - char mapname[9]; + FString mapname; int demolump; gameaction = ga_nothing; @@ -2578,7 +2584,7 @@ void G_DoPlayDemo (void) // don't spend a lot of time in loadlevel precache = false; demonew = true; - if (mapname[0] != 0) + if (mapname.Len() != 0) { G_InitNew (mapname, false); } diff --git a/src/version.h b/src/version.h index 1b4457655..8e853057a 100644 --- a/src/version.h +++ b/src/version.h @@ -61,7 +61,7 @@ const char *GetVersionString(); // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x219 +#define DEMOGAMEVERSION 0x21A // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. From 59885b856deb34fe11928a3ca1277ad8315af028 Mon Sep 17 00:00:00 2001 From: Shawn Walker Date: Sun, 18 May 2014 15:38:46 -0700 Subject: [PATCH 219/311] - remove texture name length limits for udmf maps --- src/p_doors.cpp | 2 +- src/r_data/sprites.cpp | 6 +- src/textures/buildtexture.cpp | 2 +- src/textures/canvastexture.cpp | 3 +- src/textures/imgztexture.cpp | 1 - src/textures/multipatchtexture.cpp | 2666 ++++++++++++++-------------- src/textures/texture.cpp | 12 +- src/textures/texturemanager.cpp | 46 +- src/textures/textures.h | 6 +- src/textures/tgatexture.cpp | 1 - src/w_wad.cpp | 12 +- src/w_wad.h | 3 +- 12 files changed, 1383 insertions(+), 1377 deletions(-) diff --git a/src/p_doors.cpp b/src/p_doors.cpp index b530f688d..7c6952d7f 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -297,7 +297,7 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const continue; FTexture *tex = TexMan[line->sidedef[0]->GetTexture(side_t::top)]; - texname = tex? tex->Name : NULL; + texname = tex ? tex->Name.GetChars() : NULL; if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R') { switch (texname[3]) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 012abb2f6..604619403 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -249,6 +249,8 @@ static void R_InstallSprite (int num) // letter/number appended. // The rotation character can be 0 to signify no rotations. // +#define TEX_DWNAME(tex) MAKE_ID(tex->Name[0], tex->Name[1], tex->Name[2], tex->Name[3]) + void R_InitSpriteDefs () { struct Hasher @@ -272,7 +274,7 @@ void R_InitSpriteDefs () FTexture *tex = TexMan.ByIndex(i); if (tex->UseType == FTexture::TEX_Sprite && strlen(tex->Name) >= 6) { - size_t bucket = tex->dwName % smax; + size_t bucket = TEX_DWNAME(tex) % smax; hashes[i].Next = hashes[bucket].Head; hashes[bucket].Head = i; } @@ -352,7 +354,7 @@ void R_InitSpriteDefs () while (hash != -1) { FTexture *tex = TexMan[hash]; - if (tex->dwName == intname) + if (TEX_DWNAME(tex) == intname) { bool res = R_InstallSpriteLump (FTextureID(hash), tex->Name[4] - 'A', tex->Name[5], false); diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index e534ca9c8..ee5f66fab 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -78,7 +78,7 @@ FBuildTexture::FBuildTexture (int tilenum, const BYTE *pixels, int width, int he LeftOffset = left; TopOffset = top; CalcBitSize (); - mysnprintf (Name, countof(Name), "BTIL%04d", tilenum); + Name.Format("BTIL%04d", tilenum); UseType = TEX_Build; } diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index a6e1918df..8bfd1946b 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -41,8 +41,7 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) { - strncpy (Name, name, 8); - Name[8] = 0; + Name = name; Width = width; Height = height; LeftOffset = TopOffset = 0; diff --git a/src/textures/imgztexture.cpp b/src/textures/imgztexture.cpp index 36f954b95..153880d67 100644 --- a/src/textures/imgztexture.cpp +++ b/src/textures/imgztexture.cpp @@ -106,7 +106,6 @@ FIMGZTexture::FIMGZTexture (int lumpnum, WORD w, WORD h, SWORD l, SWORD t) : FTexture(NULL, lumpnum), Pixels(0), Spans(0) { Wads.GetLumpName (Name, lumpnum); - Name[8] = 0; Width = w; Height = h; LeftOffset = l; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index d72391341..c51f30168 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1,1332 +1,1336 @@ -/* -** multipatchtexture.cpp -** Texture class for standard Doom multipatch textures -** -**--------------------------------------------------------------------------- -** Copyright 2004-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** -*/ - -#include -#include "doomtype.h" -#include "files.h" -#include "w_wad.h" -#include "i_system.h" -#include "gi.h" -#include "st_start.h" -#include "sc_man.h" -#include "templates.h" -#include "r_data/r_translate.h" -#include "bitmap.h" -#include "colormatcher.h" -#include "v_palette.h" -#include "v_video.h" -#include "v_text.h" -#include "m_fixed.h" -#include "textures/textures.h" -#include "r_data/colormaps.h" - -// On the Alpha, accessing the shorts directly if they aren't aligned on a -// 4-byte boundary causes unaligned access warnings. Why it does this at -// all and only while initing the textures is beyond me. - -#ifdef ALPHA -#define SAFESHORT(s) ((short)(((BYTE *)&(s))[0] + ((BYTE *)&(s))[1] * 256)) -#else -#define SAFESHORT(s) LittleShort(s) -#endif - - - -//-------------------------------------------------------------------------- -// -// Data structures for the TEXTUREx lumps -// -//-------------------------------------------------------------------------- - -// -// Each texture is composed of one or more patches, with patches being lumps -// stored in the WAD. The lumps are referenced by number, and patched into -// the rectangular texture space using origin and possibly other attributes. -// -struct mappatch_t -{ - SWORD originx; - SWORD originy; - SWORD patch; - SWORD stepdir; - SWORD colormap; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct maptexture_t -{ +/* +** multipatchtexture.cpp +** Texture class for standard Doom multipatch textures +** +**--------------------------------------------------------------------------- +** Copyright 2004-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include +#include "doomtype.h" +#include "files.h" +#include "w_wad.h" +#include "i_system.h" +#include "gi.h" +#include "st_start.h" +#include "sc_man.h" +#include "templates.h" +#include "r_data/r_translate.h" +#include "bitmap.h" +#include "colormatcher.h" +#include "v_palette.h" +#include "v_video.h" +#include "v_text.h" +#include "m_fixed.h" +#include "textures/textures.h" +#include "r_data/colormaps.h" + +// On the Alpha, accessing the shorts directly if they aren't aligned on a +// 4-byte boundary causes unaligned access warnings. Why it does this at +// all and only while initing the textures is beyond me. + +#ifdef ALPHA +#define SAFESHORT(s) ((short)(((BYTE *)&(s))[0] + ((BYTE *)&(s))[1] * 256)) +#else +#define SAFESHORT(s) LittleShort(s) +#endif + + + +//-------------------------------------------------------------------------- +// +// Data structures for the TEXTUREx lumps +// +//-------------------------------------------------------------------------- + +// +// Each texture is composed of one or more patches, with patches being lumps +// stored in the WAD. The lumps are referenced by number, and patched into +// the rectangular texture space using origin and possibly other attributes. +// +struct mappatch_t +{ + SWORD originx; + SWORD originy; + SWORD patch; + SWORD stepdir; + SWORD colormap; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct maptexture_t +{ BYTE name[8]; - WORD Flags; // [RH] Was unused - BYTE ScaleX; // [RH] Scaling (8 is normal) - BYTE ScaleY; // [RH] Same as above - SWORD width; - SWORD height; - BYTE columndirectory[4]; // OBSOLETE - SWORD patchcount; - mappatch_t patches[1]; -}; - -#define MAPTEXF_WORLDPANNING 0x8000 - -// Strife uses versions of the above structures that remove all unused fields - -struct strifemappatch_t -{ - SWORD originx; - SWORD originy; - SWORD patch; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct strifemaptexture_t -{ - BYTE name[8]; - WORD Flags; // [RH] Was unused - BYTE ScaleX; // [RH] Scaling (8 is normal) - BYTE ScaleY; // [RH] Same as above - SWORD width; - SWORD height; - SWORD patchcount; - strifemappatch_t patches[1]; -}; - - -//========================================================================== -// -// In-memory representation of a single PNAMES lump entry -// -//========================================================================== - -struct FPatchLookup -{ - char Name[9]; - FTexture *Texture; -}; - - -//========================================================================== -// -// A texture defined in a TEXTURE1 or TEXTURE2 lump -// -//========================================================================== - -class FMultiPatchTexture : public FTexture -{ -public: - FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); - FMultiPatchTexture (FScanner &sc, int usetype); - ~FMultiPatchTexture (); - - const BYTE *GetColumn (unsigned int column, const Span **spans_out); - const BYTE *GetPixels (); - FTextureFormat GetFormat(); - bool UseBasePalette() ; - void Unload (); - virtual void SetFrontSkyLayer (); - - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - int GetSourceLump() { return DefinitionLump; } - FTexture *GetRedirect(bool wantwarped); - FTexture *GetRawTexture(); - -protected: - BYTE *Pixels; - Span **Spans; - int DefinitionLump; - - struct TexPart - { - SWORD OriginX, OriginY; - BYTE Rotate; - BYTE op; - FRemapTable *Translation; - PalEntry Blend; - FTexture *Texture; - fixed_t Alpha; - - TexPart(); - }; - - int NumParts; - TexPart *Parts; - bool bRedirect:1; - bool bTranslucentPatches:1; - - void MakeTexture (); - -private: - void CheckForHacks (); - void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); -}; - -//========================================================================== -// -// FMultiPatchTexture :: FMultiPatchTexture -// -//========================================================================== - -FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) -{ - union - { - const maptexture_t *d; - const strifemaptexture_t *s; - } - mtexture; - - union - { - const mappatch_t *d; - const strifemappatch_t *s; - } - mpatch; - - int i; - - mtexture.d = (const maptexture_t *)texdef; - bMultiPatch = true; - - if (strife) - { - NumParts = SAFESHORT(mtexture.s->patchcount); - } - else - { - NumParts = SAFESHORT(mtexture.d->patchcount); - } - - if (NumParts < 0) - { - I_FatalError ("Bad texture directory"); - } - - UseType = FTexture::TEX_Wall; - Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; - Width = SAFESHORT(mtexture.d->width); - Height = SAFESHORT(mtexture.d->height); - strncpy (Name, (const char *)mtexture.d->name, 8); - Name[8] = 0; - CalcBitSize (); - - xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; - yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT; - - if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) - { - bWorldPanning = true; - } - - if (strife) - { - mpatch.s = &mtexture.s->patches[0]; - } - else - { - mpatch.d = &mtexture.d->patches[0]; - } - - for (i = 0; i < NumParts; ++i) - { - if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) - { - I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", - maxpatchnum, Name, LittleShort(mpatch.d->patch)+1); - } - Parts[i].OriginX = LittleShort(mpatch.d->originx); - Parts[i].OriginY = LittleShort(mpatch.d->originy); - Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; - if (Parts[i].Texture == NULL) - { - Printf (TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); - NumParts--; - i--; - } - else - { - Parts[i].Texture->bKeepAround = true; - } - if (strife) - mpatch.s++; - else - mpatch.d++; - } - if (NumParts == 0) - { - Printf ("Texture %s is left without any patches\n", Name); - } - - CheckForHacks (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height) - { - bRedirect = true; - } - } - DefinitionLump = deflumpnum; -} - -//========================================================================== -// -// FMultiPatchTexture :: ~FMultiPatchTexture -// -//========================================================================== - -FMultiPatchTexture::~FMultiPatchTexture () -{ - Unload (); - if (Parts != NULL) - { - for(int i=0; iSetFrontSkyLayer (); - } - bNoRemap0 = true; -} - -//========================================================================== -// -// FMultiPatchTexture :: Unload -// -//========================================================================== - -void FMultiPatchTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } -} - -//========================================================================== -// -// FMultiPatchTexture :: GetPixels -// -//========================================================================== - -const BYTE *FMultiPatchTexture::GetPixels () -{ - if (bRedirect) - { - return Parts->Texture->GetPixels (); - } - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetColumn -// -//========================================================================== - -const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (bRedirect) - { - return Parts->Texture->GetColumn (column, spans_out); - } - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - - -//========================================================================== -// -// GetBlendMap -// -//========================================================================== - -BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) -{ - - switch (blend.a==0 ? int(blend) : -1) - { - case BLEND_ICEMAP: - return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; - - default: - if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size()) - { - return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap; - } - else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31) - { - return DesaturateColormap[blend - BLEND_DESATURATE1]; - } - else - { - blendwork[0]=0; - if (blend.a == 255) - { - for(int i=1;i<256;i++) - { - int rr = (blend.r * GPalette.BaseColors[i].r) / 255; - int gg = (blend.g * GPalette.BaseColors[i].g) / 255; - int bb = (blend.b * GPalette.BaseColors[i].b) / 255; - - blendwork[i] = ColorMatcher.Pick(rr, gg, bb); - } - return blendwork; - } - else if (blend.a != 0) - { - for(int i=1;i<256;i++) - { - int rr = (blend.r * blend.a + GPalette.BaseColors[i].r * (255-blend.a)) / 255; - int gg = (blend.g * blend.a + GPalette.BaseColors[i].g * (255-blend.a)) / 255; - int bb = (blend.b * blend.a + GPalette.BaseColors[i].b * (255-blend.a)) / 255; - - blendwork[i] = ColorMatcher.Pick(rr, gg, bb); - } - return blendwork; - } - } - } - return NULL; -} - -//========================================================================== -// -// FMultiPatchTexture :: MakeTexture -// -//========================================================================== - -void FMultiPatchTexture::MakeTexture () -{ - // Add a little extra space at the end if the texture's height is not - // a power of 2, in case somebody accidentally makes it repeat vertically. - int numpix = Width * Height + (1 << HeightBits) - Height; - BYTE blendwork[256]; - bool hasTranslucent = false; - - Pixels = new BYTE[numpix]; - memset (Pixels, 0, numpix); - - for (int i = 0; i < NumParts; ++i) - { - if (Parts[i].op != OP_COPY) - { - hasTranslucent = true; - } - } - - if (!hasTranslucent) - { - for (int i = 0; i < NumParts; ++i) - { - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - - BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL; - { - if (Parts[i].Blend != 0) - { - trans = GetBlendMap(Parts[i].Blend, blendwork); - } - Parts[i].Texture->CopyToBlock (Pixels, Width, Height, - Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans); - } - } - } - else - { - // In case there are translucent patches let's do the composition in - // True color to keep as much precision as possible before downconverting to the palette. - BYTE *buffer = new BYTE[Width * Height * 4]; - memset(buffer, 0, Width * Height * 4); - FillBuffer(buffer, Width * 4, Height, TEX_RGB); - for(int y = 0; y < Height; y++) - { - BYTE *in = buffer + Width * y * 4; - BYTE *out = Pixels + y; - for (int x = 0; x < Width; x++) - { - if (*out == 0 && in[3] != 0) - { - *out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3]; - } - out += Height; - in += 4; - } - } - delete [] buffer; - } -} - -//=========================================================================== -// -// FMultipatchTexture::CopyTrueColorPixels -// -// Preserves the palettes of each individual patch -// -//=========================================================================== - -int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) -{ - int retv = -1; - - if (bRedirect) - { // Redirect straight to the real texture's routine. - return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf); - } - - if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE))) - { // We are doing some sort of fancy stuff to the destination bitmap, so composite to - // a temporary bitmap, and copy that. - FBitmap tbmp; - if (tbmp.Create(Width, Height)) - { - retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0)); - bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height, - 4, tbmp.GetPitch(), rotate, CF_BGRA, inf); - } - return retv; - } - - // When compositing a multipatch texture with multipatch parts, - // drawing must be restricted to the actual area which is covered by this texture. - FClipRect saved_cr = bmp->GetClipRect(); - bmp->IntersectClipRect(x, y, Width, Height); - - if (inf != NULL && inf->op == OP_OVERWRITE) - { - bmp->Zero(); - } - - for(int i = 0; i < NumParts; i++) - { - int ret = -1; - FCopyInfo info; - - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - - memset (&info, 0, sizeof(info)); - info.alpha = Parts[i].Alpha; - info.invalpha = FRACUNIT - info.alpha; - info.op = ECopyOp(Parts[i].op); - PalEntry b = Parts[i].Blend; - if (b.a == 0 && b != BLEND_NONE) - { - info.blend = EBlend(b.d); - } - else if (b.a != 0) - { - if (b.a == 255) - { - info.blendcolor[0] = b.r * FRACUNIT / 255; - info.blendcolor[1] = b.g * FRACUNIT / 255; - info.blendcolor[2] = b.b * FRACUNIT / 255; - info.blend = BLEND_MODULATE; - } - else - { - fixed_t blendalpha = b.a * FRACUNIT / 255; - info.blendcolor[0] = b.r * blendalpha; - info.blendcolor[1] = b.g * blendalpha; - info.blendcolor[2] = b.b * blendalpha; - info.blendcolor[3] = FRACUNIT - blendalpha; - info.blend = BLEND_OVERLAY; - } - } - - if (Parts[i].Translation != NULL) - { // Using a translation forces downconversion to the base palette - ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation, &info); - } - else - { - ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info); - } - - if (ret > retv) retv = ret; - } - // Restore previous clipping rectangle. - bmp->SetClipRect(saved_cr); - return retv; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetFormat -// -// only returns 'paletted' if all patches use the base palette. -// -//========================================================================== - -FTextureFormat FMultiPatchTexture::GetFormat() -{ - if (bComplex) return TEX_RGB; - if (NumParts == 1) return Parts[0].Texture->GetFormat(); - return UseBasePalette() ? TEX_Pal : TEX_RGB; -} - - -//=========================================================================== -// -// FMultipatchTexture::UseBasePalette -// -// returns true if all patches in the texture use the unmodified base -// palette. -// -//=========================================================================== - -bool FMultiPatchTexture::UseBasePalette() -{ - if (bComplex) return false; - for(int i=0;iUseBasePalette()) return false; - } - return true; -} - -//========================================================================== -// -// FMultiPatchTexture :: CheckForHacks -// -//========================================================================== - -void FMultiPatchTexture::CheckForHacks () -{ - if (NumParts <= 0) - { - return; - } - - // Heretic sky textures are marked as only 128 pixels tall, - // even though they are really 200 pixels tall. - if (gameinfo.gametype == GAME_Heretic && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[4] == 0 && - Name[3] >= '1' && - Name[3] <= '3' && - Height == 128) - { - Height = 200; - HeightBits = 8; - return; - } - - // The Doom E1 sky has its patch's y offset at -8 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 1 && - Height == 128 && - Parts->OriginY == -8 && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[3] == '1' && - Name[4] == 0) - { - Parts->OriginY = 0; - return; - } - - // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 2 && - Height == 128 && - Parts[0].OriginY == -4 && - Parts[1].OriginY == -4 && - Name[0] == 'B' && - Name[1] == 'I' && - Name[2] == 'G' && - Name[3] == 'D' && - Name[4] == 'O' && - Name[5] == 'O' && - Name[6] == 'R' && - Name[7] == '7') - { - Parts[0].OriginY = 0; - Parts[1].OriginY = 0; - return; - } - - // [RH] Some wads (I forget which!) have single-patch textures 256 - // pixels tall that have patch lengths recorded as 0. I can't think of - // any good reason for them to do this, and since I didn't make note - // of which wad made me hack in support for them, the hack is gone - // because I've added support for DeePsea's true tall patches. - // - // Okay, I found a wad with crap patches: Pleiades.wad's sky patches almost - // fit this description and are a big mess, but they're not single patch! - if (Height == 256) - { - int i; - - // All patches must be at the top of the texture for this fix - for (i = 0; i < NumParts; ++i) - { - if (Parts[i].OriginY != 0) - { - break; - } - } - - if (i == NumParts) - { - for (i = 0; i < NumParts; ++i) - { - Parts[i].Texture->HackHack(256); - } - } - } -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRedirect -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRedirect(bool wantwarped) -{ - return bRedirect ? Parts->Texture : this; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRawTexture -// -// Doom ignored all compositing of mid-sided textures on two-sided lines. -// Since these textures had to be single-patch in Doom, that essentially -// means it ignores their Y offsets. -// -// If this texture is composed of only one patch, return that patch. -// Otherwise, return this texture, since Doom wouldn't have been able to -// draw it anyway. -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRawTexture() -{ - return NumParts == 1 ? Parts->Texture : this; -} - -//========================================================================== -// -// FMultiPatchTexture :: TexPart :: TexPart -// -//========================================================================== - -FMultiPatchTexture::TexPart::TexPart() -{ - OriginX = OriginY = 0; - Rotate = 0; - Texture = NULL; - Translation = NULL; - Blend = 0; - Alpha = FRACUNIT; - op = OP_COPY; -} - -//========================================================================== -// -// FTextureManager :: AddTexturesLump -// -//========================================================================== - -void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) -{ - FPatchLookup *patchlookup; - int i; - DWORD numpatches; - - if (firstdup == 0) - { - firstdup = (int)Textures.Size(); - } - - { - FWadLump pnames = Wads.OpenLumpNum (patcheslump); - - pnames >> numpatches; - - // Check whether the amount of names reported is correct. - if ((signed)numpatches < 0) - { - Printf("Corrupt PNAMES lump found (negative amount of entries reported)"); - return; - } - - // Check whether the amount of names reported is correct. - int lumplength = Wads.LumpLength(patcheslump); - if (numpatches > DWORD((lumplength-4)/8)) - { - Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", - numpatches, lumplength, (lumplength-4)/8); - // Truncate but continue reading. Who knows how many such lumps exist? - numpatches = (lumplength-4)/8; - } - - // Catalog the patches these textures use so we know which - // textures they represent. - patchlookup = (FPatchLookup *)alloca (numpatches * sizeof(*patchlookup)); - - for (DWORD i = 0; i < numpatches; ++i) - { - pnames.Read (patchlookup[i].Name, 8); - patchlookup[i].Name[8] = 0; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); - if (j.isValid()) - { - patchlookup[i].Texture = Textures[j.GetIndex()].Texture; - } - else - { - // Shareware Doom has the same PNAMES lump as the registered - // Doom, so printing warnings for patches that don't really - // exist isn't such a good idea. - //Printf ("Patch %s not found.\n", patchlookup[i].Name); - patchlookup[i].Texture = NULL; - } - } - } - - bool isStrife = false; - const DWORD *maptex, *directory; - DWORD maxoff; - int numtextures; - DWORD offset = 0; // Shut up, GCC! - - maptex = (const DWORD *)lumpdata; - numtextures = LittleLong(*maptex); - maxoff = lumpsize; - - if (maxoff < DWORD(numtextures+1)*4) - { - Printf ("Texture directory is too short"); - return; - } - - // Scan the texture lump to decide if it contains Doom or Strife textures - for (i = 0, directory = maptex+1; i < numtextures; ++i) - { - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory"); - return; - } - - maptexture_t *tex = (maptexture_t *)((BYTE *)maptex + offset); - - // There is bizzarely a Doom editing tool that writes to the - // first two elements of columndirectory, so I can't check those. - if (SAFESHORT(tex->patchcount) < 0 || - tex->columndirectory[2] != 0 || - tex->columndirectory[3] != 0) - { - isStrife = true; - break; - } - } - - - // Textures defined earlier in the lump take precedence over those defined later, - // but later TEXTUREx lumps take precedence over earlier ones. - for (i = 1, directory = maptex; i <= numtextures; ++i) - { - if (i == 1 && texture1) - { - // The very first texture is just a dummy. Copy its dimensions to texture 0. - // It still needs to be created in case someone uses it by name. - offset = LittleLong(directory[1]); - const maptexture_t *tex = (const maptexture_t *)((const BYTE *)maptex + offset); - FDummyTexture *tex0 = static_cast(Textures[0].Texture); - tex0->SetSize (SAFESHORT(tex->width), SAFESHORT(tex->height)); - } - - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory"); - return; - } - - // If this texture was defined already in this lump, skip it - // This could cause problems with animations that use the same name for intermediate - // textures. Should I be worried? - int j; - for (j = (int)Textures.Size() - 1; j >= firstdup; --j) - { - if (strnicmp (Textures[j].Texture->Name, (const char *)maptex + offset, 8) == 0) - break; - } - if (j + 1 == firstdup) - { - FMultiPatchTexture *tex = new FMultiPatchTexture ((const BYTE *)maptex + offset, patchlookup, numpatches, isStrife, deflumpnum); - if (i == 1 && texture1) - { - tex->UseType = FTexture::TEX_FirstDefined; - } - TexMan.AddTexture (tex); - StartScreen->Progress(); - } - } -} - - -//========================================================================== -// -// FTextureManager :: AddTexturesLumps -// -//========================================================================== - -void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) -{ - int firstdup = (int)Textures.Size(); - - if (lump1 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump1); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump1), lump1, patcheslump, firstdup, true); - } - if (lump2 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump2); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump2), lump2, patcheslump, firstdup, false); - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) -{ - FString patchname; - sc.MustGetString(); - - FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); - int Mirror = 0; - - if (!texno.isValid()) - { - if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) - { - int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); - if (lumpnum >= 0) - { - part.Texture = FTexture::CreateTexture(lumpnum, usetype); - TexMan.AddTexture(part.Texture); - } - } - } - else - { - part.Texture = TexMan[texno]; - bComplex |= part.Texture->bComplex; - } - if (part.Texture == NULL) - { - if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); - } - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginX = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginY = sc.Number; - - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("flipx")) - { - Mirror |= 1; - } - else if (sc.Compare("flipy")) - { - Mirror |= 2; - } - else if (sc.Compare("rotate")) - { - sc.MustGetNumber(); - sc.Number = (((sc.Number + 90)%360)-90); - if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) - { - sc.ScriptError("Rotation must be a multiple of 90 degrees."); - } - part.Rotate = (sc.Number / 90) & 3; - } - else if (sc.Compare("Translation")) - { - int match; - - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; - sc.MustGetString(); - - match = sc.MatchString(maps); - if (match >= 0) - { - part.Blend = BLEND_SPECIALCOLORMAP1 + match; - } - else if (sc.Compare("ICE")) - { - part.Blend = BLEND_ICEMAP; - } - else if (sc.Compare("DESATURATE")) - { - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); - } - else - { - sc.UnGet(); - part.Translation = new FRemapTable; - part.Translation->MakeIdentity(); - do - { - sc.MustGetString(); - part.Translation->AddToTranslation(sc.String); - } - while (sc.CheckString(",")); - } - - } - else if (sc.Compare("Colormap")) - { - float r1,g1,b1; - float r2,g2,b2; - - sc.MustGetFloat(); - r1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b1 = (float)sc.Float; - if (!sc.CheckString(",")) - { - part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); - } - else - { - sc.MustGetFloat(); - r2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b2 = (float)sc.Float; - part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); - } - } - else if (sc.Compare("Blend")) - { - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - - if (!sc.CheckNumber()) - { - sc.MustGetString(); - part.Blend = V_GetColor(NULL, sc.String); - } - else - { - int r,g,b; - - r = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - g = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - b = sc.Number; - sc.MustGetStringName(","); - part.Blend = MAKERGB(r, g, b); - } - // Blend.a may never be 0 here. - if (sc.CheckString(",")) - { - sc.MustGetFloat(); - if (sc.Float > 0.f) - part.Blend.a = clamp(int(sc.Float*255), 1, 254); - else - part.Blend = 0; - } - else part.Blend.a = 255; - } - else if (sc.Compare("alpha")) - { - sc.MustGetFloat(); - part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT); - // bComplex is not set because it is only needed when the style is not OP_COPY. - } - else if (sc.Compare("style")) - { - static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; - sc.MustGetString(); - part.op = sc.MustMatchString(styles); - bComplex |= (part.op != OP_COPY); - bTranslucentPatches = bComplex; - } - else if (sc.Compare("useoffsets")) - { - if (part.Texture != NULL) - { - part.OriginX -= part.Texture->LeftOffset; - part.OriginY -= part.Texture->TopOffset; - } - } - } - } - if (Mirror & 2) - { - part.Rotate = (part.Rotate + 2) & 3; - Mirror ^= 1; - } - if (Mirror & 1) - { - part.Rotate |= 4; - } -} - -//========================================================================== -// -// Constructor for text based multipatch definitions -// -//========================================================================== - -FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) -{ - TArray parts; - bool bSilent = false; - - bMultiPatch = true; - sc.SetCMode(true); - sc.MustGetString(); - const char* textureName = NULL; - if (sc.Compare("optional")) - { - bSilent = true; - sc.MustGetString(); - if (sc.Compare(",")) - { - // this is not right. Apparently a texture named 'optional' is being defined right now... - sc.UnGet(); - textureName = "optional"; - bSilent = false; - } - } - uppercopy(Name, !textureName ? sc.String : textureName); - Name[8] = 0; - sc.MustGetStringName(","); - sc.MustGetNumber(); - Width = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - Height = sc.Number; - UseType = usetype; - - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("XScale")) - { - sc.MustGetFloat(); - xScale = FLOAT2FIXED(sc.Float); - if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); - } - else if (sc.Compare("YScale")) - { - sc.MustGetFloat(); - yScale = FLOAT2FIXED(sc.Float); - if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); - } - else if (sc.Compare("WorldPanning")) - { - bWorldPanning = true; - } - else if (sc.Compare("NullTexture")) - { - UseType = FTexture::TEX_Null; - } - else if (sc.Compare("NoDecals")) - { - bNoDecals = true; - } - else if (sc.Compare("Patch")) - { - TexPart part; - ParsePatch(sc, part, bSilent, TEX_WallPatch); - if (part.Texture != NULL) parts.Push(part); - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Graphic")) - { - TexPart part; - ParsePatch(sc, part, bSilent, TEX_MiscPatch); - if (part.Texture != NULL) parts.Push(part); - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Offset")) - { - sc.MustGetNumber(); - LeftOffset = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - TopOffset = sc.Number; - } - else - { - sc.ScriptError("Unknown texture property '%s'", sc.String); - } - } - - NumParts = parts.Size(); - Parts = new TexPart[NumParts]; - memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); - - //CalcBitSize (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height && - Parts->Rotate == 0 && - !bComplex) - { - bRedirect = true; - } - } - } - - if (Width <= 0 || Height <= 0) - { - UseType = FTexture::TEX_Null; - Printf("Texture %s has invalid dimensions (%d, %d)\n", Name, Width, Height); - Width = Height = 1; - } - CalcBitSize (); - - - sc.SetCMode(false); -} - - - -void FTextureManager::ParseXTexture(FScanner &sc, int usetype) -{ - FTexture *tex = new FMultiPatchTexture(sc, usetype); - TexMan.AddTexture (tex); -} + WORD Flags; // [RH] Was unused + BYTE ScaleX; // [RH] Scaling (8 is normal) + BYTE ScaleY; // [RH] Same as above + SWORD width; + SWORD height; + BYTE columndirectory[4]; // OBSOLETE + SWORD patchcount; + mappatch_t patches[1]; +}; + +#define MAPTEXF_WORLDPANNING 0x8000 + +// Strife uses versions of the above structures that remove all unused fields + +struct strifemappatch_t +{ + SWORD originx; + SWORD originy; + SWORD patch; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct strifemaptexture_t +{ + BYTE name[8]; + WORD Flags; // [RH] Was unused + BYTE ScaleX; // [RH] Scaling (8 is normal) + BYTE ScaleY; // [RH] Same as above + SWORD width; + SWORD height; + SWORD patchcount; + strifemappatch_t patches[1]; +}; + + +//========================================================================== +// +// In-memory representation of a single PNAMES lump entry +// +//========================================================================== + +struct FPatchLookup +{ + FString Name; + FTexture *Texture; +}; + + +//========================================================================== +// +// A texture defined in a TEXTURE1 or TEXTURE2 lump +// +//========================================================================== + +class FMultiPatchTexture : public FTexture +{ +public: + FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); + FMultiPatchTexture (FScanner &sc, int usetype); + ~FMultiPatchTexture (); + + const BYTE *GetColumn (unsigned int column, const Span **spans_out); + const BYTE *GetPixels (); + FTextureFormat GetFormat(); + bool UseBasePalette() ; + void Unload (); + virtual void SetFrontSkyLayer (); + + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); + int GetSourceLump() { return DefinitionLump; } + FTexture *GetRedirect(bool wantwarped); + FTexture *GetRawTexture(); + +protected: + BYTE *Pixels; + Span **Spans; + int DefinitionLump; + + struct TexPart + { + SWORD OriginX, OriginY; + BYTE Rotate; + BYTE op; + FRemapTable *Translation; + PalEntry Blend; + FTexture *Texture; + fixed_t Alpha; + + TexPart(); + }; + + int NumParts; + TexPart *Parts; + bool bRedirect:1; + bool bTranslucentPatches:1; + + void MakeTexture (); + +private: + void CheckForHacks (); + void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); +}; + +//========================================================================== +// +// FMultiPatchTexture :: FMultiPatchTexture +// +//========================================================================== + +FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) +: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +{ + union + { + const maptexture_t *d; + const strifemaptexture_t *s; + } + mtexture; + + union + { + const mappatch_t *d; + const strifemappatch_t *s; + } + mpatch; + + int i; + + mtexture.d = (const maptexture_t *)texdef; + bMultiPatch = true; + + if (strife) + { + NumParts = SAFESHORT(mtexture.s->patchcount); + } + else + { + NumParts = SAFESHORT(mtexture.d->patchcount); + } + + if (NumParts < 0) + { + I_FatalError ("Bad texture directory"); + } + + UseType = FTexture::TEX_Wall; + Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; + Width = SAFESHORT(mtexture.d->width); + Height = SAFESHORT(mtexture.d->height); + Name = (char *)mtexture.d->name; + CalcBitSize (); + + xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; + yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT; + + if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) + { + bWorldPanning = true; + } + + if (strife) + { + mpatch.s = &mtexture.s->patches[0]; + } + else + { + mpatch.d = &mtexture.d->patches[0]; + } + + for (i = 0; i < NumParts; ++i) + { + if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) + { + I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", + maxpatchnum, Name, LittleShort(mpatch.d->patch)+1); + } + Parts[i].OriginX = LittleShort(mpatch.d->originx); + Parts[i].OriginY = LittleShort(mpatch.d->originy); + Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; + if (Parts[i].Texture == NULL) + { + Printf (TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); + NumParts--; + i--; + } + else + { + Parts[i].Texture->bKeepAround = true; + } + if (strife) + mpatch.s++; + else + mpatch.d++; + } + if (NumParts == 0) + { + Printf ("Texture %s is left without any patches\n", Name); + } + + CheckForHacks (); + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height) + { + bRedirect = true; + } + } + DefinitionLump = deflumpnum; +} + +//========================================================================== +// +// FMultiPatchTexture :: ~FMultiPatchTexture +// +//========================================================================== + +FMultiPatchTexture::~FMultiPatchTexture () +{ + Unload (); + if (Parts != NULL) + { + for(int i=0; iSetFrontSkyLayer (); + } + bNoRemap0 = true; +} + +//========================================================================== +// +// FMultiPatchTexture :: Unload +// +//========================================================================== + +void FMultiPatchTexture::Unload () +{ + if (Pixels != NULL) + { + delete[] Pixels; + Pixels = NULL; + } +} + +//========================================================================== +// +// FMultiPatchTexture :: GetPixels +// +//========================================================================== + +const BYTE *FMultiPatchTexture::GetPixels () +{ + if (bRedirect) + { + return Parts->Texture->GetPixels (); + } + if (Pixels == NULL) + { + MakeTexture (); + } + return Pixels; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetColumn +// +//========================================================================== + +const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out) +{ + if (bRedirect) + { + return Parts->Texture->GetColumn (column, spans_out); + } + if (Pixels == NULL) + { + MakeTexture (); + } + if ((unsigned)column >= (unsigned)Width) + { + if (WidthMask + 1 == Width) + { + column &= WidthMask; + } + else + { + column %= Width; + } + } + if (spans_out != NULL) + { + if (Spans == NULL) + { + Spans = CreateSpans (Pixels); + } + *spans_out = Spans[column]; + } + return Pixels + column*Height; +} + + +//========================================================================== +// +// GetBlendMap +// +//========================================================================== + +BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) +{ + + switch (blend.a==0 ? int(blend) : -1) + { + case BLEND_ICEMAP: + return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; + + default: + if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size()) + { + return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap; + } + else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31) + { + return DesaturateColormap[blend - BLEND_DESATURATE1]; + } + else + { + blendwork[0]=0; + if (blend.a == 255) + { + for(int i=1;i<256;i++) + { + int rr = (blend.r * GPalette.BaseColors[i].r) / 255; + int gg = (blend.g * GPalette.BaseColors[i].g) / 255; + int bb = (blend.b * GPalette.BaseColors[i].b) / 255; + + blendwork[i] = ColorMatcher.Pick(rr, gg, bb); + } + return blendwork; + } + else if (blend.a != 0) + { + for(int i=1;i<256;i++) + { + int rr = (blend.r * blend.a + GPalette.BaseColors[i].r * (255-blend.a)) / 255; + int gg = (blend.g * blend.a + GPalette.BaseColors[i].g * (255-blend.a)) / 255; + int bb = (blend.b * blend.a + GPalette.BaseColors[i].b * (255-blend.a)) / 255; + + blendwork[i] = ColorMatcher.Pick(rr, gg, bb); + } + return blendwork; + } + } + } + return NULL; +} + +//========================================================================== +// +// FMultiPatchTexture :: MakeTexture +// +//========================================================================== + +void FMultiPatchTexture::MakeTexture () +{ + // Add a little extra space at the end if the texture's height is not + // a power of 2, in case somebody accidentally makes it repeat vertically. + int numpix = Width * Height + (1 << HeightBits) - Height; + BYTE blendwork[256]; + bool hasTranslucent = false; + + Pixels = new BYTE[numpix]; + memset (Pixels, 0, numpix); + + for (int i = 0; i < NumParts; ++i) + { + if (Parts[i].op != OP_COPY) + { + hasTranslucent = true; + } + } + + if (!hasTranslucent) + { + for (int i = 0; i < NumParts; ++i) + { + if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. + + BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL; + { + if (Parts[i].Blend != 0) + { + trans = GetBlendMap(Parts[i].Blend, blendwork); + } + Parts[i].Texture->CopyToBlock (Pixels, Width, Height, + Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans); + } + } + } + else + { + // In case there are translucent patches let's do the composition in + // True color to keep as much precision as possible before downconverting to the palette. + BYTE *buffer = new BYTE[Width * Height * 4]; + memset(buffer, 0, Width * Height * 4); + FillBuffer(buffer, Width * 4, Height, TEX_RGB); + for(int y = 0; y < Height; y++) + { + BYTE *in = buffer + Width * y * 4; + BYTE *out = Pixels + y; + for (int x = 0; x < Width; x++) + { + if (*out == 0 && in[3] != 0) + { + *out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3]; + } + out += Height; + in += 4; + } + } + delete [] buffer; + } +} + +//=========================================================================== +// +// FMultipatchTexture::CopyTrueColorPixels +// +// Preserves the palettes of each individual patch +// +//=========================================================================== + +int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +{ + int retv = -1; + + if (bRedirect) + { // Redirect straight to the real texture's routine. + return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf); + } + + if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE))) + { // We are doing some sort of fancy stuff to the destination bitmap, so composite to + // a temporary bitmap, and copy that. + FBitmap tbmp; + if (tbmp.Create(Width, Height)) + { + retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0)); + bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height, + 4, tbmp.GetPitch(), rotate, CF_BGRA, inf); + } + return retv; + } + + // When compositing a multipatch texture with multipatch parts, + // drawing must be restricted to the actual area which is covered by this texture. + FClipRect saved_cr = bmp->GetClipRect(); + bmp->IntersectClipRect(x, y, Width, Height); + + if (inf != NULL && inf->op == OP_OVERWRITE) + { + bmp->Zero(); + } + + for(int i = 0; i < NumParts; i++) + { + int ret = -1; + FCopyInfo info; + + if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. + + memset (&info, 0, sizeof(info)); + info.alpha = Parts[i].Alpha; + info.invalpha = FRACUNIT - info.alpha; + info.op = ECopyOp(Parts[i].op); + PalEntry b = Parts[i].Blend; + if (b.a == 0 && b != BLEND_NONE) + { + info.blend = EBlend(b.d); + } + else if (b.a != 0) + { + if (b.a == 255) + { + info.blendcolor[0] = b.r * FRACUNIT / 255; + info.blendcolor[1] = b.g * FRACUNIT / 255; + info.blendcolor[2] = b.b * FRACUNIT / 255; + info.blend = BLEND_MODULATE; + } + else + { + fixed_t blendalpha = b.a * FRACUNIT / 255; + info.blendcolor[0] = b.r * blendalpha; + info.blendcolor[1] = b.g * blendalpha; + info.blendcolor[2] = b.b * blendalpha; + info.blendcolor[3] = FRACUNIT - blendalpha; + info.blend = BLEND_OVERLAY; + } + } + + if (Parts[i].Translation != NULL) + { // Using a translation forces downconversion to the base palette + ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation, &info); + } + else + { + ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info); + } + + if (ret > retv) retv = ret; + } + // Restore previous clipping rectangle. + bmp->SetClipRect(saved_cr); + return retv; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetFormat +// +// only returns 'paletted' if all patches use the base palette. +// +//========================================================================== + +FTextureFormat FMultiPatchTexture::GetFormat() +{ + if (bComplex) return TEX_RGB; + if (NumParts == 1) return Parts[0].Texture->GetFormat(); + return UseBasePalette() ? TEX_Pal : TEX_RGB; +} + + +//=========================================================================== +// +// FMultipatchTexture::UseBasePalette +// +// returns true if all patches in the texture use the unmodified base +// palette. +// +//=========================================================================== + +bool FMultiPatchTexture::UseBasePalette() +{ + if (bComplex) return false; + for(int i=0;iUseBasePalette()) return false; + } + return true; +} + +//========================================================================== +// +// FMultiPatchTexture :: CheckForHacks +// +//========================================================================== + +void FMultiPatchTexture::CheckForHacks () +{ + if (NumParts <= 0) + { + return; + } + + // Heretic sky textures are marked as only 128 pixels tall, + // even though they are really 200 pixels tall. + if (gameinfo.gametype == GAME_Heretic && + Name[0] == 'S' && + Name[1] == 'K' && + Name[2] == 'Y' && + Name[4] == 0 && + Name[3] >= '1' && + Name[3] <= '3' && + Height == 128) + { + Height = 200; + HeightBits = 8; + return; + } + + // The Doom E1 sky has its patch's y offset at -8 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + NumParts == 1 && + Height == 128 && + Parts->OriginY == -8 && + Name[0] == 'S' && + Name[1] == 'K' && + Name[2] == 'Y' && + Name[3] == '1' && + Name[4] == 0) + { + Parts->OriginY = 0; + return; + } + + // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + NumParts == 2 && + Height == 128 && + Parts[0].OriginY == -4 && + Parts[1].OriginY == -4 && + Name[0] == 'B' && + Name[1] == 'I' && + Name[2] == 'G' && + Name[3] == 'D' && + Name[4] == 'O' && + Name[5] == 'O' && + Name[6] == 'R' && + Name[7] == '7') + { + Parts[0].OriginY = 0; + Parts[1].OriginY = 0; + return; + } + + // [RH] Some wads (I forget which!) have single-patch textures 256 + // pixels tall that have patch lengths recorded as 0. I can't think of + // any good reason for them to do this, and since I didn't make note + // of which wad made me hack in support for them, the hack is gone + // because I've added support for DeePsea's true tall patches. + // + // Okay, I found a wad with crap patches: Pleiades.wad's sky patches almost + // fit this description and are a big mess, but they're not single patch! + if (Height == 256) + { + int i; + + // All patches must be at the top of the texture for this fix + for (i = 0; i < NumParts; ++i) + { + if (Parts[i].OriginY != 0) + { + break; + } + } + + if (i == NumParts) + { + for (i = 0; i < NumParts; ++i) + { + Parts[i].Texture->HackHack(256); + } + } + } +} + +//========================================================================== +// +// FMultiPatchTexture :: GetRedirect +// +//========================================================================== + +FTexture *FMultiPatchTexture::GetRedirect(bool wantwarped) +{ + return bRedirect ? Parts->Texture : this; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetRawTexture +// +// Doom ignored all compositing of mid-sided textures on two-sided lines. +// Since these textures had to be single-patch in Doom, that essentially +// means it ignores their Y offsets. +// +// If this texture is composed of only one patch, return that patch. +// Otherwise, return this texture, since Doom wouldn't have been able to +// draw it anyway. +// +//========================================================================== + +FTexture *FMultiPatchTexture::GetRawTexture() +{ + return NumParts == 1 ? Parts->Texture : this; +} + +//========================================================================== +// +// FMultiPatchTexture :: TexPart :: TexPart +// +//========================================================================== + +FMultiPatchTexture::TexPart::TexPart() +{ + OriginX = OriginY = 0; + Rotate = 0; + Texture = NULL; + Translation = NULL; + Blend = 0; + Alpha = FRACUNIT; + op = OP_COPY; +} + +//========================================================================== +// +// FTextureManager :: AddTexturesLump +// +//========================================================================== + +void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) +{ + FPatchLookup *patchlookup = NULL; + int i; + DWORD numpatches; + + if (firstdup == 0) + { + firstdup = (int)Textures.Size(); + } + + { + FWadLump pnames = Wads.OpenLumpNum (patcheslump); + + pnames >> numpatches; + + // Check whether the amount of names reported is correct. + if ((signed)numpatches < 0) + { + Printf("Corrupt PNAMES lump found (negative amount of entries reported)"); + return; + } + + // Check whether the amount of names reported is correct. + int lumplength = Wads.LumpLength(patcheslump); + if (numpatches > DWORD((lumplength-4)/8)) + { + Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", + numpatches, lumplength, (lumplength-4)/8); + // Truncate but continue reading. Who knows how many such lumps exist? + numpatches = (lumplength-4)/8; + } + + // Catalog the patches these textures use so we know which + // textures they represent. + patchlookup = new FPatchLookup[numpatches]; + for (DWORD i = 0; i < numpatches; ++i) + { + char pname[9]; + pnames.Read (pname, 8); + pname[8] = '\0'; + patchlookup[i].Name = pname; + FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); + if (j.isValid()) + { + patchlookup[i].Texture = Textures[j.GetIndex()].Texture; + } + else + { + // Shareware Doom has the same PNAMES lump as the registered + // Doom, so printing warnings for patches that don't really + // exist isn't such a good idea. + //Printf ("Patch %s not found.\n", patchlookup[i].Name); + patchlookup[i].Texture = NULL; + } + } + } + + bool isStrife = false; + const DWORD *maptex, *directory; + DWORD maxoff; + int numtextures; + DWORD offset = 0; // Shut up, GCC! + + maptex = (const DWORD *)lumpdata; + numtextures = LittleLong(*maptex); + maxoff = lumpsize; + + if (maxoff < DWORD(numtextures+1)*4) + { + Printf ("Texture directory is too short"); + delete[] patchlookup; + return; + } + + // Scan the texture lump to decide if it contains Doom or Strife textures + for (i = 0, directory = maptex+1; i < numtextures; ++i) + { + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf ("Bad texture directory"); + delete[] patchlookup; + return; + } + + maptexture_t *tex = (maptexture_t *)((BYTE *)maptex + offset); + + // There is bizzarely a Doom editing tool that writes to the + // first two elements of columndirectory, so I can't check those. + if (SAFESHORT(tex->patchcount) < 0 || + tex->columndirectory[2] != 0 || + tex->columndirectory[3] != 0) + { + isStrife = true; + break; + } + } + + + // Textures defined earlier in the lump take precedence over those defined later, + // but later TEXTUREx lumps take precedence over earlier ones. + for (i = 1, directory = maptex; i <= numtextures; ++i) + { + if (i == 1 && texture1) + { + // The very first texture is just a dummy. Copy its dimensions to texture 0. + // It still needs to be created in case someone uses it by name. + offset = LittleLong(directory[1]); + const maptexture_t *tex = (const maptexture_t *)((const BYTE *)maptex + offset); + FDummyTexture *tex0 = static_cast(Textures[0].Texture); + tex0->SetSize (SAFESHORT(tex->width), SAFESHORT(tex->height)); + } + + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf ("Bad texture directory"); + delete[] patchlookup; + return; + } + + // If this texture was defined already in this lump, skip it + // This could cause problems with animations that use the same name for intermediate + // textures. Should I be worried? + int j; + for (j = (int)Textures.Size() - 1; j >= firstdup; --j) + { + if (strnicmp (Textures[j].Texture->Name, (const char *)maptex + offset, 8) == 0) + break; + } + if (j + 1 == firstdup) + { + FMultiPatchTexture *tex = new FMultiPatchTexture ((const BYTE *)maptex + offset, patchlookup, numpatches, isStrife, deflumpnum); + if (i == 1 && texture1) + { + tex->UseType = FTexture::TEX_FirstDefined; + } + TexMan.AddTexture (tex); + StartScreen->Progress(); + } + } + delete[] patchlookup; +} + + +//========================================================================== +// +// FTextureManager :: AddTexturesLumps +// +//========================================================================== + +void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) +{ + int firstdup = (int)Textures.Size(); + + if (lump1 >= 0) + { + FMemLump texdir = Wads.ReadLump (lump1); + AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump1), lump1, patcheslump, firstdup, true); + } + if (lump2 >= 0) + { + FMemLump texdir = Wads.ReadLump (lump2); + AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump2), lump2, patcheslump, firstdup, false); + } +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) +{ + FString patchname; + sc.MustGetString(); + + FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); + int Mirror = 0; + + if (!texno.isValid()) + { + if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) + { + int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); + if (lumpnum >= 0) + { + part.Texture = FTexture::CreateTexture(lumpnum, usetype); + TexMan.AddTexture(part.Texture); + } + } + } + else + { + part.Texture = TexMan[texno]; + bComplex |= part.Texture->bComplex; + } + if (part.Texture == NULL) + { + if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); + } + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginX = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginY = sc.Number; + + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("flipx")) + { + Mirror |= 1; + } + else if (sc.Compare("flipy")) + { + Mirror |= 2; + } + else if (sc.Compare("rotate")) + { + sc.MustGetNumber(); + sc.Number = (((sc.Number + 90)%360)-90); + if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) + { + sc.ScriptError("Rotation must be a multiple of 90 degrees."); + } + part.Rotate = (sc.Number / 90) & 3; + } + else if (sc.Compare("Translation")) + { + int match; + + bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; + sc.MustGetString(); + + match = sc.MatchString(maps); + if (match >= 0) + { + part.Blend = BLEND_SPECIALCOLORMAP1 + match; + } + else if (sc.Compare("ICE")) + { + part.Blend = BLEND_ICEMAP; + } + else if (sc.Compare("DESATURATE")) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); + } + else + { + sc.UnGet(); + part.Translation = new FRemapTable; + part.Translation->MakeIdentity(); + do + { + sc.MustGetString(); + part.Translation->AddToTranslation(sc.String); + } + while (sc.CheckString(",")); + } + + } + else if (sc.Compare("Colormap")) + { + float r1,g1,b1; + float r2,g2,b2; + + sc.MustGetFloat(); + r1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b1 = (float)sc.Float; + if (!sc.CheckString(",")) + { + part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); + } + else + { + sc.MustGetFloat(); + r2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b2 = (float)sc.Float; + part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); + } + } + else if (sc.Compare("Blend")) + { + bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + + if (!sc.CheckNumber()) + { + sc.MustGetString(); + part.Blend = V_GetColor(NULL, sc.String); + } + else + { + int r,g,b; + + r = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + g = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + b = sc.Number; + sc.MustGetStringName(","); + part.Blend = MAKERGB(r, g, b); + } + // Blend.a may never be 0 here. + if (sc.CheckString(",")) + { + sc.MustGetFloat(); + if (sc.Float > 0.f) + part.Blend.a = clamp(int(sc.Float*255), 1, 254); + else + part.Blend = 0; + } + else part.Blend.a = 255; + } + else if (sc.Compare("alpha")) + { + sc.MustGetFloat(); + part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT); + // bComplex is not set because it is only needed when the style is not OP_COPY. + } + else if (sc.Compare("style")) + { + static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; + sc.MustGetString(); + part.op = sc.MustMatchString(styles); + bComplex |= (part.op != OP_COPY); + bTranslucentPatches = bComplex; + } + else if (sc.Compare("useoffsets")) + { + if (part.Texture != NULL) + { + part.OriginX -= part.Texture->LeftOffset; + part.OriginY -= part.Texture->TopOffset; + } + } + } + } + if (Mirror & 2) + { + part.Rotate = (part.Rotate + 2) & 3; + Mirror ^= 1; + } + if (Mirror & 1) + { + part.Rotate |= 4; + } +} + +//========================================================================== +// +// Constructor for text based multipatch definitions +// +//========================================================================== + +FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) +: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +{ + TArray parts; + bool bSilent = false; + + bMultiPatch = true; + sc.SetCMode(true); + sc.MustGetString(); + const char* textureName = NULL; + if (sc.Compare("optional")) + { + bSilent = true; + sc.MustGetString(); + if (sc.Compare(",")) + { + // this is not right. Apparently a texture named 'optional' is being defined right now... + sc.UnGet(); + textureName = "optional"; + bSilent = false; + } + } + Name = !textureName ? sc.String : textureName; + Name.ToUpper(); + sc.MustGetStringName(","); + sc.MustGetNumber(); + Width = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + Height = sc.Number; + UseType = usetype; + + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("XScale")) + { + sc.MustGetFloat(); + xScale = FLOAT2FIXED(sc.Float); + if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); + } + else if (sc.Compare("YScale")) + { + sc.MustGetFloat(); + yScale = FLOAT2FIXED(sc.Float); + if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); + } + else if (sc.Compare("WorldPanning")) + { + bWorldPanning = true; + } + else if (sc.Compare("NullTexture")) + { + UseType = FTexture::TEX_Null; + } + else if (sc.Compare("NoDecals")) + { + bNoDecals = true; + } + else if (sc.Compare("Patch")) + { + TexPart part; + ParsePatch(sc, part, bSilent, TEX_WallPatch); + if (part.Texture != NULL) parts.Push(part); + part.Texture = NULL; + part.Translation = NULL; + } + else if (sc.Compare("Graphic")) + { + TexPart part; + ParsePatch(sc, part, bSilent, TEX_MiscPatch); + if (part.Texture != NULL) parts.Push(part); + part.Texture = NULL; + part.Translation = NULL; + } + else if (sc.Compare("Offset")) + { + sc.MustGetNumber(); + LeftOffset = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + TopOffset = sc.Number; + } + else + { + sc.ScriptError("Unknown texture property '%s'", sc.String); + } + } + + NumParts = parts.Size(); + Parts = new TexPart[NumParts]; + memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); + + //CalcBitSize (); + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height && + Parts->Rotate == 0 && + !bComplex) + { + bRedirect = true; + } + } + } + + if (Width <= 0 || Height <= 0) + { + UseType = FTexture::TEX_Null; + Printf("Texture %s has invalid dimensions (%d, %d)\n", Name, Width, Height); + Width = Height = 1; + } + CalcBitSize (); + + + sc.SetCMode(false); +} + + + +void FTextureManager::ParseXTexture(FScanner &sc, int usetype) +{ + FTexture *tex = new FMultiPatchTexture(sc, usetype); + TexMan.AddTexture (tex); +} diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index f41f1902d..6ee6ccb0a 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -137,7 +137,10 @@ FTexture * FTexture::CreateTexture (int lumpnum, int usetype) FTexture * FTexture::CreateTexture (const char *name, int lumpnum, int usetype) { FTexture *tex = CreateTexture(lumpnum, usetype); - if (tex != NULL && name != NULL) uppercopy(tex->Name, name); + if (tex != NULL && name != NULL) { + tex->Name = name; + tex->Name.ToUpper(); + } return tex; } @@ -152,16 +155,16 @@ FTexture::FTexture (const char *name, int lumpnum) id.SetInvalid(); if (name != NULL) { - uppercopy(Name, name); + Name = name; + Name.ToUpper(); } else if (lumpnum < 0) { - *Name = 0; + Name = FString(); } else { Wads.GetLumpName (Name, lumpnum); - Name[8] = 0; } } @@ -574,7 +577,6 @@ FDummyTexture::FDummyTexture () HeightBits = 6; WidthBits = 6; WidthMask = 63; - Name[0] = 0; UseType = TEX_Null; } diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6fb963e42..2a10ce0df 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -373,7 +373,7 @@ FTextureID FTextureManager::AddTexture (FTexture *texture) // Later textures take precedence over earlier ones // Textures without name can't be looked for - if (texture->Name[0] != 0) + if (texture->Name[0] != '\0') { bucket = int(MakeKey (texture->Name) % HASH_SIZE); hash = HashFirst[bucket]; @@ -429,7 +429,7 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b FTexture *oldtexture = Textures[index].Texture; - strcpy (newtexture->Name, oldtexture->Name); + newtexture->Name = oldtexture->Name; newtexture->UseType = oldtexture->UseType; Textures[index].Texture = newtexture; @@ -488,9 +488,7 @@ void FTextureManager::AddGroup(int wadnum, int ns, int usetype) { int firsttx = Wads.GetFirstLump(wadnum); int lasttx = Wads.GetLastLump(wadnum); - char name[9]; - - name[8] = 0; + FString Name; // Go from first to last so that ANIMDEFS work as expected. However, // to avoid duplicates (and to keep earlier entries from overriding @@ -501,9 +499,9 @@ void FTextureManager::AddGroup(int wadnum, int ns, int usetype) { if (Wads.GetLumpNamespace(firsttx) == ns) { - Wads.GetLumpName (name, firsttx); + Wads.GetLumpName (Name, firsttx); - if (Wads.CheckNumForName (name, ns) == firsttx) + if (Wads.CheckNumForName (Name, ns) == firsttx) { CreateTexture (firsttx, usetype); } @@ -511,7 +509,7 @@ void FTextureManager::AddGroup(int wadnum, int ns, int usetype) } else if (ns == ns_flats && Wads.GetLumpFlags(firsttx) & LUMPF_MAYBEFLAT) { - if (Wads.CheckNumForName (name, ns) < firsttx) + if (Wads.CheckNumForName (Name, ns) < firsttx) { CreateTexture (firsttx, usetype); } @@ -531,7 +529,7 @@ void FTextureManager::AddHiresTextures (int wadnum) int firsttx = Wads.GetFirstLump(wadnum); int lasttx = Wads.GetLastLump(wadnum); - char name[9]; + FString Name; TArray tlist; if (firsttx == -1 || lasttx == -1) @@ -539,18 +537,16 @@ void FTextureManager::AddHiresTextures (int wadnum) return; } - name[8] = 0; - for (;firsttx <= lasttx; ++firsttx) { if (Wads.GetLumpNamespace(firsttx) == ns_hires) { - Wads.GetLumpName (name, firsttx); + Wads.GetLumpName (Name, firsttx); - if (Wads.CheckNumForName (name, ns_hires) == firsttx) + if (Wads.CheckNumForName (Name, ns_hires) == firsttx) { tlist.Clear(); - int amount = ListTextures(name, tlist); + int amount = ListTextures(Name, tlist); if (amount == 0) { // A texture with this name does not yet exist @@ -594,14 +590,13 @@ void FTextureManager::AddHiresTextures (int wadnum) void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) { int remapLump, lastLump; - char src[9]; + FString src; bool is32bit; int width, height; int type, mode; TArray tlist; lastLump = 0; - src[8] = '\0'; while ((remapLump = Wads.FindLump(lumpname, &lastLump)) != -1) { @@ -678,7 +673,7 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) FString base = ExtractFileBase(sc.String, false); if (!base.IsEmpty()) { - strncpy(src, base, 8); + src = base.Left(8); int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); @@ -701,7 +696,7 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(width, height); - memcpy(newtex->Name, src, sizeof(newtex->Name)); + newtex->Name = src; FTextureID oldtex = TexMan.CheckForTexture(src, FTexture::TEX_MiscPatch); if (oldtex.isValid()) @@ -757,7 +752,7 @@ void FTextureManager::AddPatches (int lumpnum) char name[9]; *file >> numpatches; - name[8] = 0; + name[8] = '\0'; for (i = 0; i < numpatches; ++i) { @@ -839,9 +834,8 @@ void FTextureManager::AddTexturesForWad(int wadnum) for (int i= firsttx; i <= lasttx; i++) { bool skin = false; - char name[9]; - Wads.GetLumpName(name, i); - name[8]=0; + FString Name; + Wads.GetLumpName(Name, i); // Ignore anything not in the global namespace int ns = Wads.GetLumpNamespace(i); @@ -867,20 +861,20 @@ void FTextureManager::AddTexturesForWad(int wadnum) if (Wads.CheckLumpName(i, "BEHAVIOR")) continue; // Don't bother looking at this lump if something later overrides it. - if (Wads.CheckNumForName(name, ns_graphics) != i) continue; + if (Wads.CheckNumForName(Name, ns_graphics) != i) continue; // skip this if it has already been added as a wall patch. - if (CheckForTexture(name, FTexture::TEX_WallPatch, 0).Exists()) continue; + if (CheckForTexture(Name, FTexture::TEX_WallPatch, 0).Exists()) continue; } else if (ns == ns_graphics) { // Don't bother looking this lump if something later overrides it. - if (Wads.CheckNumForName(name, ns_graphics) != i) continue; + if (Wads.CheckNumForName(Name, ns_graphics) != i) continue; } else if (ns >= ns_firstskin) { // Don't bother looking this lump if something later overrides it. - if (Wads.CheckNumForName(name, ns) != i) continue; + if (Wads.CheckNumForName(Name, ns) != i) continue; skin = true; } else continue; diff --git a/src/textures/textures.h b/src/textures/textures.h index 15c9bce5c..9dbd85a55 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -157,11 +157,7 @@ public: int SourceLump; FTextureID id; - union - { - char Name[9]; - DWORD dwName; // Used with sprites - }; + FString Name; BYTE UseType; // This texture's primary purpose BYTE bNoDecals:1; // Decals should not stick to texture diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index 374861699..cff89603c 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -145,7 +145,6 @@ FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) : FTexture(NULL, lumpnum), Pixels(0), Spans(0) { Wads.GetLumpName (Name, lumpnum); - Name[8] = 0; Width = hdr->width; Height = hdr->height; // Alpha channel is used only for 32 bit RGBA and paletted images with RGBA palettes. diff --git a/src/w_wad.cpp b/src/w_wad.cpp index c351de6f8..9455817db 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -492,7 +492,7 @@ int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int n return -1; } - i = FirstLumpIndex_FullName[MakeKey (name) % NumLumps]; + i = FirstLumpIndex_FullName[MakeKey(name) % NumLumps]; while (i != NULL_INDEX && stricmp(name, LumpInfo[i].lump->FullName)) { @@ -1015,6 +1015,16 @@ void FWadCollection::GetLumpName (char *to, int lump) const uppercopy (to, LumpInfo[lump].lump->Name); } +void FWadCollection::GetLumpName(FString &to, int lump) const +{ + if ((size_t)lump >= NumLumps) + to = FString(); + else { + to = LumpInfo[lump].lump->Name; + to.ToUpper(); + } +} + //========================================================================== // // FWadCollection :: GetLumpFullName diff --git a/src/w_wad.h b/src/w_wad.h index 530182147..0a95699f6 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -196,7 +196,8 @@ public: int GetLumpOffset (int lump); // [RH] Returns offset of lump in the wadfile int GetLumpFlags (int lump); // Return the flags for this lump void GetLumpName (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy - const char *GetLumpFullName (int lump) const; // [RH] Returns the lump's full name + void FWadCollection::GetLumpName(FString &to, int lump) const; + const char *GetLumpFullName(int lump) const; // [RH] Returns the lump's full name FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to From 582b1990b7f342601a1976c85d0ce2b25343458e Mon Sep 17 00:00:00 2001 From: Shawn Walker Date: Sun, 18 May 2014 16:00:31 -0700 Subject: [PATCH 220/311] - restore original line endings --- src/textures/multipatchtexture.cpp | 2670 ++++++++++++++-------------- 1 file changed, 1335 insertions(+), 1335 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index c51f30168..84e7385db 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1,1336 +1,1336 @@ -/* -** multipatchtexture.cpp -** Texture class for standard Doom multipatch textures -** -**--------------------------------------------------------------------------- -** Copyright 2004-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** -*/ - -#include -#include "doomtype.h" -#include "files.h" -#include "w_wad.h" -#include "i_system.h" -#include "gi.h" -#include "st_start.h" -#include "sc_man.h" -#include "templates.h" -#include "r_data/r_translate.h" -#include "bitmap.h" -#include "colormatcher.h" -#include "v_palette.h" -#include "v_video.h" -#include "v_text.h" -#include "m_fixed.h" -#include "textures/textures.h" -#include "r_data/colormaps.h" - -// On the Alpha, accessing the shorts directly if they aren't aligned on a -// 4-byte boundary causes unaligned access warnings. Why it does this at -// all and only while initing the textures is beyond me. - -#ifdef ALPHA -#define SAFESHORT(s) ((short)(((BYTE *)&(s))[0] + ((BYTE *)&(s))[1] * 256)) -#else -#define SAFESHORT(s) LittleShort(s) -#endif - - - -//-------------------------------------------------------------------------- -// -// Data structures for the TEXTUREx lumps -// -//-------------------------------------------------------------------------- - -// -// Each texture is composed of one or more patches, with patches being lumps -// stored in the WAD. The lumps are referenced by number, and patched into -// the rectangular texture space using origin and possibly other attributes. -// -struct mappatch_t -{ - SWORD originx; - SWORD originy; - SWORD patch; - SWORD stepdir; - SWORD colormap; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct maptexture_t -{ +/* +** multipatchtexture.cpp +** Texture class for standard Doom multipatch textures +** +**--------------------------------------------------------------------------- +** Copyright 2004-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include +#include "doomtype.h" +#include "files.h" +#include "w_wad.h" +#include "i_system.h" +#include "gi.h" +#include "st_start.h" +#include "sc_man.h" +#include "templates.h" +#include "r_data/r_translate.h" +#include "bitmap.h" +#include "colormatcher.h" +#include "v_palette.h" +#include "v_video.h" +#include "v_text.h" +#include "m_fixed.h" +#include "textures/textures.h" +#include "r_data/colormaps.h" + +// On the Alpha, accessing the shorts directly if they aren't aligned on a +// 4-byte boundary causes unaligned access warnings. Why it does this at +// all and only while initing the textures is beyond me. + +#ifdef ALPHA +#define SAFESHORT(s) ((short)(((BYTE *)&(s))[0] + ((BYTE *)&(s))[1] * 256)) +#else +#define SAFESHORT(s) LittleShort(s) +#endif + + + +//-------------------------------------------------------------------------- +// +// Data structures for the TEXTUREx lumps +// +//-------------------------------------------------------------------------- + +// +// Each texture is composed of one or more patches, with patches being lumps +// stored in the WAD. The lumps are referenced by number, and patched into +// the rectangular texture space using origin and possibly other attributes. +// +struct mappatch_t +{ + SWORD originx; + SWORD originy; + SWORD patch; + SWORD stepdir; + SWORD colormap; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct maptexture_t +{ BYTE name[8]; - WORD Flags; // [RH] Was unused - BYTE ScaleX; // [RH] Scaling (8 is normal) - BYTE ScaleY; // [RH] Same as above - SWORD width; - SWORD height; - BYTE columndirectory[4]; // OBSOLETE - SWORD patchcount; - mappatch_t patches[1]; -}; - -#define MAPTEXF_WORLDPANNING 0x8000 - -// Strife uses versions of the above structures that remove all unused fields - -struct strifemappatch_t -{ - SWORD originx; - SWORD originy; - SWORD patch; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct strifemaptexture_t -{ - BYTE name[8]; - WORD Flags; // [RH] Was unused - BYTE ScaleX; // [RH] Scaling (8 is normal) - BYTE ScaleY; // [RH] Same as above - SWORD width; - SWORD height; - SWORD patchcount; - strifemappatch_t patches[1]; -}; - - -//========================================================================== -// -// In-memory representation of a single PNAMES lump entry -// -//========================================================================== - -struct FPatchLookup -{ - FString Name; - FTexture *Texture; -}; - - -//========================================================================== -// -// A texture defined in a TEXTURE1 or TEXTURE2 lump -// -//========================================================================== - -class FMultiPatchTexture : public FTexture -{ -public: - FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); - FMultiPatchTexture (FScanner &sc, int usetype); - ~FMultiPatchTexture (); - - const BYTE *GetColumn (unsigned int column, const Span **spans_out); - const BYTE *GetPixels (); - FTextureFormat GetFormat(); - bool UseBasePalette() ; - void Unload (); - virtual void SetFrontSkyLayer (); - - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - int GetSourceLump() { return DefinitionLump; } - FTexture *GetRedirect(bool wantwarped); - FTexture *GetRawTexture(); - -protected: - BYTE *Pixels; - Span **Spans; - int DefinitionLump; - - struct TexPart - { - SWORD OriginX, OriginY; - BYTE Rotate; - BYTE op; - FRemapTable *Translation; - PalEntry Blend; - FTexture *Texture; - fixed_t Alpha; - - TexPart(); - }; - - int NumParts; - TexPart *Parts; - bool bRedirect:1; - bool bTranslucentPatches:1; - - void MakeTexture (); - -private: - void CheckForHacks (); - void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); -}; - -//========================================================================== -// -// FMultiPatchTexture :: FMultiPatchTexture -// -//========================================================================== - -FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) -{ - union - { - const maptexture_t *d; - const strifemaptexture_t *s; - } - mtexture; - - union - { - const mappatch_t *d; - const strifemappatch_t *s; - } - mpatch; - - int i; - - mtexture.d = (const maptexture_t *)texdef; - bMultiPatch = true; - - if (strife) - { - NumParts = SAFESHORT(mtexture.s->patchcount); - } - else - { - NumParts = SAFESHORT(mtexture.d->patchcount); - } - - if (NumParts < 0) - { - I_FatalError ("Bad texture directory"); - } - - UseType = FTexture::TEX_Wall; - Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; - Width = SAFESHORT(mtexture.d->width); - Height = SAFESHORT(mtexture.d->height); - Name = (char *)mtexture.d->name; - CalcBitSize (); - - xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; - yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT; - - if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) - { - bWorldPanning = true; - } - - if (strife) - { - mpatch.s = &mtexture.s->patches[0]; - } - else - { - mpatch.d = &mtexture.d->patches[0]; - } - - for (i = 0; i < NumParts; ++i) - { - if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) - { - I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", - maxpatchnum, Name, LittleShort(mpatch.d->patch)+1); - } - Parts[i].OriginX = LittleShort(mpatch.d->originx); - Parts[i].OriginY = LittleShort(mpatch.d->originy); - Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; - if (Parts[i].Texture == NULL) - { - Printf (TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); - NumParts--; - i--; - } - else - { - Parts[i].Texture->bKeepAround = true; - } - if (strife) - mpatch.s++; - else - mpatch.d++; - } - if (NumParts == 0) - { - Printf ("Texture %s is left without any patches\n", Name); - } - - CheckForHacks (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height) - { - bRedirect = true; - } - } - DefinitionLump = deflumpnum; -} - -//========================================================================== -// -// FMultiPatchTexture :: ~FMultiPatchTexture -// -//========================================================================== - -FMultiPatchTexture::~FMultiPatchTexture () -{ - Unload (); - if (Parts != NULL) - { - for(int i=0; iSetFrontSkyLayer (); - } - bNoRemap0 = true; -} - -//========================================================================== -// -// FMultiPatchTexture :: Unload -// -//========================================================================== - -void FMultiPatchTexture::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } -} - -//========================================================================== -// -// FMultiPatchTexture :: GetPixels -// -//========================================================================== - -const BYTE *FMultiPatchTexture::GetPixels () -{ - if (bRedirect) - { - return Parts->Texture->GetPixels (); - } - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetColumn -// -//========================================================================== - -const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - if (bRedirect) - { - return Parts->Texture->GetColumn (column, spans_out); - } - if (Pixels == NULL) - { - MakeTexture (); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - - -//========================================================================== -// -// GetBlendMap -// -//========================================================================== - -BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) -{ - - switch (blend.a==0 ? int(blend) : -1) - { - case BLEND_ICEMAP: - return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; - - default: - if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size()) - { - return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap; - } - else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31) - { - return DesaturateColormap[blend - BLEND_DESATURATE1]; - } - else - { - blendwork[0]=0; - if (blend.a == 255) - { - for(int i=1;i<256;i++) - { - int rr = (blend.r * GPalette.BaseColors[i].r) / 255; - int gg = (blend.g * GPalette.BaseColors[i].g) / 255; - int bb = (blend.b * GPalette.BaseColors[i].b) / 255; - - blendwork[i] = ColorMatcher.Pick(rr, gg, bb); - } - return blendwork; - } - else if (blend.a != 0) - { - for(int i=1;i<256;i++) - { - int rr = (blend.r * blend.a + GPalette.BaseColors[i].r * (255-blend.a)) / 255; - int gg = (blend.g * blend.a + GPalette.BaseColors[i].g * (255-blend.a)) / 255; - int bb = (blend.b * blend.a + GPalette.BaseColors[i].b * (255-blend.a)) / 255; - - blendwork[i] = ColorMatcher.Pick(rr, gg, bb); - } - return blendwork; - } - } - } - return NULL; -} - -//========================================================================== -// -// FMultiPatchTexture :: MakeTexture -// -//========================================================================== - -void FMultiPatchTexture::MakeTexture () -{ - // Add a little extra space at the end if the texture's height is not - // a power of 2, in case somebody accidentally makes it repeat vertically. - int numpix = Width * Height + (1 << HeightBits) - Height; - BYTE blendwork[256]; - bool hasTranslucent = false; - - Pixels = new BYTE[numpix]; - memset (Pixels, 0, numpix); - - for (int i = 0; i < NumParts; ++i) - { - if (Parts[i].op != OP_COPY) - { - hasTranslucent = true; - } - } - - if (!hasTranslucent) - { - for (int i = 0; i < NumParts; ++i) - { - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - - BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL; - { - if (Parts[i].Blend != 0) - { - trans = GetBlendMap(Parts[i].Blend, blendwork); - } - Parts[i].Texture->CopyToBlock (Pixels, Width, Height, - Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans); - } - } - } - else - { - // In case there are translucent patches let's do the composition in - // True color to keep as much precision as possible before downconverting to the palette. - BYTE *buffer = new BYTE[Width * Height * 4]; - memset(buffer, 0, Width * Height * 4); - FillBuffer(buffer, Width * 4, Height, TEX_RGB); - for(int y = 0; y < Height; y++) - { - BYTE *in = buffer + Width * y * 4; - BYTE *out = Pixels + y; - for (int x = 0; x < Width; x++) - { - if (*out == 0 && in[3] != 0) - { - *out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3]; - } - out += Height; - in += 4; - } - } - delete [] buffer; - } -} - -//=========================================================================== -// -// FMultipatchTexture::CopyTrueColorPixels -// -// Preserves the palettes of each individual patch -// -//=========================================================================== - -int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) -{ - int retv = -1; - - if (bRedirect) - { // Redirect straight to the real texture's routine. - return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf); - } - - if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE))) - { // We are doing some sort of fancy stuff to the destination bitmap, so composite to - // a temporary bitmap, and copy that. - FBitmap tbmp; - if (tbmp.Create(Width, Height)) - { - retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0)); - bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height, - 4, tbmp.GetPitch(), rotate, CF_BGRA, inf); - } - return retv; - } - - // When compositing a multipatch texture with multipatch parts, - // drawing must be restricted to the actual area which is covered by this texture. - FClipRect saved_cr = bmp->GetClipRect(); - bmp->IntersectClipRect(x, y, Width, Height); - - if (inf != NULL && inf->op == OP_OVERWRITE) - { - bmp->Zero(); - } - - for(int i = 0; i < NumParts; i++) - { - int ret = -1; - FCopyInfo info; - - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - - memset (&info, 0, sizeof(info)); - info.alpha = Parts[i].Alpha; - info.invalpha = FRACUNIT - info.alpha; - info.op = ECopyOp(Parts[i].op); - PalEntry b = Parts[i].Blend; - if (b.a == 0 && b != BLEND_NONE) - { - info.blend = EBlend(b.d); - } - else if (b.a != 0) - { - if (b.a == 255) - { - info.blendcolor[0] = b.r * FRACUNIT / 255; - info.blendcolor[1] = b.g * FRACUNIT / 255; - info.blendcolor[2] = b.b * FRACUNIT / 255; - info.blend = BLEND_MODULATE; - } - else - { - fixed_t blendalpha = b.a * FRACUNIT / 255; - info.blendcolor[0] = b.r * blendalpha; - info.blendcolor[1] = b.g * blendalpha; - info.blendcolor[2] = b.b * blendalpha; - info.blendcolor[3] = FRACUNIT - blendalpha; - info.blend = BLEND_OVERLAY; - } - } - - if (Parts[i].Translation != NULL) - { // Using a translation forces downconversion to the base palette - ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation, &info); - } - else - { - ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info); - } - - if (ret > retv) retv = ret; - } - // Restore previous clipping rectangle. - bmp->SetClipRect(saved_cr); - return retv; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetFormat -// -// only returns 'paletted' if all patches use the base palette. -// -//========================================================================== - -FTextureFormat FMultiPatchTexture::GetFormat() -{ - if (bComplex) return TEX_RGB; - if (NumParts == 1) return Parts[0].Texture->GetFormat(); - return UseBasePalette() ? TEX_Pal : TEX_RGB; -} - - -//=========================================================================== -// -// FMultipatchTexture::UseBasePalette -// -// returns true if all patches in the texture use the unmodified base -// palette. -// -//=========================================================================== - -bool FMultiPatchTexture::UseBasePalette() -{ - if (bComplex) return false; - for(int i=0;iUseBasePalette()) return false; - } - return true; -} - -//========================================================================== -// -// FMultiPatchTexture :: CheckForHacks -// -//========================================================================== - -void FMultiPatchTexture::CheckForHacks () -{ - if (NumParts <= 0) - { - return; - } - - // Heretic sky textures are marked as only 128 pixels tall, - // even though they are really 200 pixels tall. - if (gameinfo.gametype == GAME_Heretic && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[4] == 0 && - Name[3] >= '1' && - Name[3] <= '3' && - Height == 128) - { - Height = 200; - HeightBits = 8; - return; - } - - // The Doom E1 sky has its patch's y offset at -8 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 1 && - Height == 128 && - Parts->OriginY == -8 && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[3] == '1' && - Name[4] == 0) - { - Parts->OriginY = 0; - return; - } - - // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 2 && - Height == 128 && - Parts[0].OriginY == -4 && - Parts[1].OriginY == -4 && - Name[0] == 'B' && - Name[1] == 'I' && - Name[2] == 'G' && - Name[3] == 'D' && - Name[4] == 'O' && - Name[5] == 'O' && - Name[6] == 'R' && - Name[7] == '7') - { - Parts[0].OriginY = 0; - Parts[1].OriginY = 0; - return; - } - - // [RH] Some wads (I forget which!) have single-patch textures 256 - // pixels tall that have patch lengths recorded as 0. I can't think of - // any good reason for them to do this, and since I didn't make note - // of which wad made me hack in support for them, the hack is gone - // because I've added support for DeePsea's true tall patches. - // - // Okay, I found a wad with crap patches: Pleiades.wad's sky patches almost - // fit this description and are a big mess, but they're not single patch! - if (Height == 256) - { - int i; - - // All patches must be at the top of the texture for this fix - for (i = 0; i < NumParts; ++i) - { - if (Parts[i].OriginY != 0) - { - break; - } - } - - if (i == NumParts) - { - for (i = 0; i < NumParts; ++i) - { - Parts[i].Texture->HackHack(256); - } - } - } -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRedirect -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRedirect(bool wantwarped) -{ - return bRedirect ? Parts->Texture : this; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRawTexture -// -// Doom ignored all compositing of mid-sided textures on two-sided lines. -// Since these textures had to be single-patch in Doom, that essentially -// means it ignores their Y offsets. -// -// If this texture is composed of only one patch, return that patch. -// Otherwise, return this texture, since Doom wouldn't have been able to -// draw it anyway. -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRawTexture() -{ - return NumParts == 1 ? Parts->Texture : this; -} - -//========================================================================== -// -// FMultiPatchTexture :: TexPart :: TexPart -// -//========================================================================== - -FMultiPatchTexture::TexPart::TexPart() -{ - OriginX = OriginY = 0; - Rotate = 0; - Texture = NULL; - Translation = NULL; - Blend = 0; - Alpha = FRACUNIT; - op = OP_COPY; -} - -//========================================================================== -// -// FTextureManager :: AddTexturesLump -// -//========================================================================== - -void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) -{ - FPatchLookup *patchlookup = NULL; - int i; - DWORD numpatches; - - if (firstdup == 0) - { - firstdup = (int)Textures.Size(); - } - - { - FWadLump pnames = Wads.OpenLumpNum (patcheslump); - - pnames >> numpatches; - - // Check whether the amount of names reported is correct. - if ((signed)numpatches < 0) - { - Printf("Corrupt PNAMES lump found (negative amount of entries reported)"); - return; - } - - // Check whether the amount of names reported is correct. - int lumplength = Wads.LumpLength(patcheslump); - if (numpatches > DWORD((lumplength-4)/8)) - { - Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", - numpatches, lumplength, (lumplength-4)/8); - // Truncate but continue reading. Who knows how many such lumps exist? - numpatches = (lumplength-4)/8; - } - - // Catalog the patches these textures use so we know which - // textures they represent. - patchlookup = new FPatchLookup[numpatches]; - for (DWORD i = 0; i < numpatches; ++i) - { - char pname[9]; - pnames.Read (pname, 8); - pname[8] = '\0'; - patchlookup[i].Name = pname; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); - if (j.isValid()) - { - patchlookup[i].Texture = Textures[j.GetIndex()].Texture; - } - else - { - // Shareware Doom has the same PNAMES lump as the registered - // Doom, so printing warnings for patches that don't really - // exist isn't such a good idea. - //Printf ("Patch %s not found.\n", patchlookup[i].Name); - patchlookup[i].Texture = NULL; - } - } - } - - bool isStrife = false; - const DWORD *maptex, *directory; - DWORD maxoff; - int numtextures; - DWORD offset = 0; // Shut up, GCC! - - maptex = (const DWORD *)lumpdata; - numtextures = LittleLong(*maptex); - maxoff = lumpsize; - - if (maxoff < DWORD(numtextures+1)*4) - { - Printf ("Texture directory is too short"); - delete[] patchlookup; - return; - } - - // Scan the texture lump to decide if it contains Doom or Strife textures - for (i = 0, directory = maptex+1; i < numtextures; ++i) - { - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory"); - delete[] patchlookup; - return; - } - - maptexture_t *tex = (maptexture_t *)((BYTE *)maptex + offset); - - // There is bizzarely a Doom editing tool that writes to the - // first two elements of columndirectory, so I can't check those. - if (SAFESHORT(tex->patchcount) < 0 || - tex->columndirectory[2] != 0 || - tex->columndirectory[3] != 0) - { - isStrife = true; - break; - } - } - - - // Textures defined earlier in the lump take precedence over those defined later, - // but later TEXTUREx lumps take precedence over earlier ones. - for (i = 1, directory = maptex; i <= numtextures; ++i) - { - if (i == 1 && texture1) - { - // The very first texture is just a dummy. Copy its dimensions to texture 0. - // It still needs to be created in case someone uses it by name. - offset = LittleLong(directory[1]); - const maptexture_t *tex = (const maptexture_t *)((const BYTE *)maptex + offset); - FDummyTexture *tex0 = static_cast(Textures[0].Texture); - tex0->SetSize (SAFESHORT(tex->width), SAFESHORT(tex->height)); - } - - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory"); - delete[] patchlookup; - return; - } - - // If this texture was defined already in this lump, skip it - // This could cause problems with animations that use the same name for intermediate - // textures. Should I be worried? - int j; - for (j = (int)Textures.Size() - 1; j >= firstdup; --j) - { - if (strnicmp (Textures[j].Texture->Name, (const char *)maptex + offset, 8) == 0) - break; - } - if (j + 1 == firstdup) - { - FMultiPatchTexture *tex = new FMultiPatchTexture ((const BYTE *)maptex + offset, patchlookup, numpatches, isStrife, deflumpnum); - if (i == 1 && texture1) - { - tex->UseType = FTexture::TEX_FirstDefined; - } - TexMan.AddTexture (tex); - StartScreen->Progress(); - } - } - delete[] patchlookup; -} - - -//========================================================================== -// -// FTextureManager :: AddTexturesLumps -// -//========================================================================== - -void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) -{ - int firstdup = (int)Textures.Size(); - - if (lump1 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump1); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump1), lump1, patcheslump, firstdup, true); - } - if (lump2 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump2); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump2), lump2, patcheslump, firstdup, false); - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) -{ - FString patchname; - sc.MustGetString(); - - FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); - int Mirror = 0; - - if (!texno.isValid()) - { - if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) - { - int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); - if (lumpnum >= 0) - { - part.Texture = FTexture::CreateTexture(lumpnum, usetype); - TexMan.AddTexture(part.Texture); - } - } - } - else - { - part.Texture = TexMan[texno]; - bComplex |= part.Texture->bComplex; - } - if (part.Texture == NULL) - { - if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); - } - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginX = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginY = sc.Number; - - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("flipx")) - { - Mirror |= 1; - } - else if (sc.Compare("flipy")) - { - Mirror |= 2; - } - else if (sc.Compare("rotate")) - { - sc.MustGetNumber(); - sc.Number = (((sc.Number + 90)%360)-90); - if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) - { - sc.ScriptError("Rotation must be a multiple of 90 degrees."); - } - part.Rotate = (sc.Number / 90) & 3; - } - else if (sc.Compare("Translation")) - { - int match; - - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; - sc.MustGetString(); - - match = sc.MatchString(maps); - if (match >= 0) - { - part.Blend = BLEND_SPECIALCOLORMAP1 + match; - } - else if (sc.Compare("ICE")) - { - part.Blend = BLEND_ICEMAP; - } - else if (sc.Compare("DESATURATE")) - { - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); - } - else - { - sc.UnGet(); - part.Translation = new FRemapTable; - part.Translation->MakeIdentity(); - do - { - sc.MustGetString(); - part.Translation->AddToTranslation(sc.String); - } - while (sc.CheckString(",")); - } - - } - else if (sc.Compare("Colormap")) - { - float r1,g1,b1; - float r2,g2,b2; - - sc.MustGetFloat(); - r1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b1 = (float)sc.Float; - if (!sc.CheckString(",")) - { - part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); - } - else - { - sc.MustGetFloat(); - r2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b2 = (float)sc.Float; - part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); - } - } - else if (sc.Compare("Blend")) - { - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - - if (!sc.CheckNumber()) - { - sc.MustGetString(); - part.Blend = V_GetColor(NULL, sc.String); - } - else - { - int r,g,b; - - r = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - g = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - b = sc.Number; - sc.MustGetStringName(","); - part.Blend = MAKERGB(r, g, b); - } - // Blend.a may never be 0 here. - if (sc.CheckString(",")) - { - sc.MustGetFloat(); - if (sc.Float > 0.f) - part.Blend.a = clamp(int(sc.Float*255), 1, 254); - else - part.Blend = 0; - } - else part.Blend.a = 255; - } - else if (sc.Compare("alpha")) - { - sc.MustGetFloat(); - part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT); - // bComplex is not set because it is only needed when the style is not OP_COPY. - } - else if (sc.Compare("style")) - { - static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; - sc.MustGetString(); - part.op = sc.MustMatchString(styles); - bComplex |= (part.op != OP_COPY); - bTranslucentPatches = bComplex; - } - else if (sc.Compare("useoffsets")) - { - if (part.Texture != NULL) - { - part.OriginX -= part.Texture->LeftOffset; - part.OriginY -= part.Texture->TopOffset; - } - } - } - } - if (Mirror & 2) - { - part.Rotate = (part.Rotate + 2) & 3; - Mirror ^= 1; - } - if (Mirror & 1) - { - part.Rotate |= 4; - } -} - -//========================================================================== -// -// Constructor for text based multipatch definitions -// -//========================================================================== - -FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) -{ - TArray parts; - bool bSilent = false; - - bMultiPatch = true; - sc.SetCMode(true); - sc.MustGetString(); - const char* textureName = NULL; - if (sc.Compare("optional")) - { - bSilent = true; - sc.MustGetString(); - if (sc.Compare(",")) - { - // this is not right. Apparently a texture named 'optional' is being defined right now... - sc.UnGet(); - textureName = "optional"; - bSilent = false; - } - } - Name = !textureName ? sc.String : textureName; - Name.ToUpper(); - sc.MustGetStringName(","); - sc.MustGetNumber(); - Width = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - Height = sc.Number; - UseType = usetype; - - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("XScale")) - { - sc.MustGetFloat(); - xScale = FLOAT2FIXED(sc.Float); - if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); - } - else if (sc.Compare("YScale")) - { - sc.MustGetFloat(); - yScale = FLOAT2FIXED(sc.Float); - if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); - } - else if (sc.Compare("WorldPanning")) - { - bWorldPanning = true; - } - else if (sc.Compare("NullTexture")) - { - UseType = FTexture::TEX_Null; - } - else if (sc.Compare("NoDecals")) - { - bNoDecals = true; - } - else if (sc.Compare("Patch")) - { - TexPart part; - ParsePatch(sc, part, bSilent, TEX_WallPatch); - if (part.Texture != NULL) parts.Push(part); - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Graphic")) - { - TexPart part; - ParsePatch(sc, part, bSilent, TEX_MiscPatch); - if (part.Texture != NULL) parts.Push(part); - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Offset")) - { - sc.MustGetNumber(); - LeftOffset = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - TopOffset = sc.Number; - } - else - { - sc.ScriptError("Unknown texture property '%s'", sc.String); - } - } - - NumParts = parts.Size(); - Parts = new TexPart[NumParts]; - memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); - - //CalcBitSize (); - - // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height && - Parts->Rotate == 0 && - !bComplex) - { - bRedirect = true; - } - } - } - - if (Width <= 0 || Height <= 0) - { - UseType = FTexture::TEX_Null; - Printf("Texture %s has invalid dimensions (%d, %d)\n", Name, Width, Height); - Width = Height = 1; - } - CalcBitSize (); - - - sc.SetCMode(false); -} - - - -void FTextureManager::ParseXTexture(FScanner &sc, int usetype) -{ - FTexture *tex = new FMultiPatchTexture(sc, usetype); - TexMan.AddTexture (tex); -} + WORD Flags; // [RH] Was unused + BYTE ScaleX; // [RH] Scaling (8 is normal) + BYTE ScaleY; // [RH] Same as above + SWORD width; + SWORD height; + BYTE columndirectory[4]; // OBSOLETE + SWORD patchcount; + mappatch_t patches[1]; +}; + +#define MAPTEXF_WORLDPANNING 0x8000 + +// Strife uses versions of the above structures that remove all unused fields + +struct strifemappatch_t +{ + SWORD originx; + SWORD originy; + SWORD patch; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct strifemaptexture_t +{ + BYTE name[8]; + WORD Flags; // [RH] Was unused + BYTE ScaleX; // [RH] Scaling (8 is normal) + BYTE ScaleY; // [RH] Same as above + SWORD width; + SWORD height; + SWORD patchcount; + strifemappatch_t patches[1]; +}; + + +//========================================================================== +// +// In-memory representation of a single PNAMES lump entry +// +//========================================================================== + +struct FPatchLookup +{ + FString Name; + FTexture *Texture; +}; + + +//========================================================================== +// +// A texture defined in a TEXTURE1 or TEXTURE2 lump +// +//========================================================================== + +class FMultiPatchTexture : public FTexture +{ +public: + FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); + FMultiPatchTexture (FScanner &sc, int usetype); + ~FMultiPatchTexture (); + + const BYTE *GetColumn (unsigned int column, const Span **spans_out); + const BYTE *GetPixels (); + FTextureFormat GetFormat(); + bool UseBasePalette() ; + void Unload (); + virtual void SetFrontSkyLayer (); + + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); + int GetSourceLump() { return DefinitionLump; } + FTexture *GetRedirect(bool wantwarped); + FTexture *GetRawTexture(); + +protected: + BYTE *Pixels; + Span **Spans; + int DefinitionLump; + + struct TexPart + { + SWORD OriginX, OriginY; + BYTE Rotate; + BYTE op; + FRemapTable *Translation; + PalEntry Blend; + FTexture *Texture; + fixed_t Alpha; + + TexPart(); + }; + + int NumParts; + TexPart *Parts; + bool bRedirect:1; + bool bTranslucentPatches:1; + + void MakeTexture (); + +private: + void CheckForHacks (); + void ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype); +}; + +//========================================================================== +// +// FMultiPatchTexture :: FMultiPatchTexture +// +//========================================================================== + +FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) +: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +{ + union + { + const maptexture_t *d; + const strifemaptexture_t *s; + } + mtexture; + + union + { + const mappatch_t *d; + const strifemappatch_t *s; + } + mpatch; + + int i; + + mtexture.d = (const maptexture_t *)texdef; + bMultiPatch = true; + + if (strife) + { + NumParts = SAFESHORT(mtexture.s->patchcount); + } + else + { + NumParts = SAFESHORT(mtexture.d->patchcount); + } + + if (NumParts < 0) + { + I_FatalError ("Bad texture directory"); + } + + UseType = FTexture::TEX_Wall; + Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; + Width = SAFESHORT(mtexture.d->width); + Height = SAFESHORT(mtexture.d->height); + Name = (char *)mtexture.d->name; + CalcBitSize (); + + xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; + yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT; + + if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) + { + bWorldPanning = true; + } + + if (strife) + { + mpatch.s = &mtexture.s->patches[0]; + } + else + { + mpatch.d = &mtexture.d->patches[0]; + } + + for (i = 0; i < NumParts; ++i) + { + if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) + { + I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", + maxpatchnum, Name, LittleShort(mpatch.d->patch)+1); + } + Parts[i].OriginX = LittleShort(mpatch.d->originx); + Parts[i].OriginY = LittleShort(mpatch.d->originy); + Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; + if (Parts[i].Texture == NULL) + { + Printf(TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); + NumParts--; + i--; + } + else + { + Parts[i].Texture->bKeepAround = true; + } + if (strife) + mpatch.s++; + else + mpatch.d++; + } + if (NumParts == 0) + { + Printf ("Texture %s is left without any patches\n", Name); + } + + CheckForHacks (); + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height) + { + bRedirect = true; + } + } + DefinitionLump = deflumpnum; +} + +//========================================================================== +// +// FMultiPatchTexture :: ~FMultiPatchTexture +// +//========================================================================== + +FMultiPatchTexture::~FMultiPatchTexture () +{ + Unload (); + if (Parts != NULL) + { + for(int i=0; iSetFrontSkyLayer (); + } + bNoRemap0 = true; +} + +//========================================================================== +// +// FMultiPatchTexture :: Unload +// +//========================================================================== + +void FMultiPatchTexture::Unload () +{ + if (Pixels != NULL) + { + delete[] Pixels; + Pixels = NULL; + } +} + +//========================================================================== +// +// FMultiPatchTexture :: GetPixels +// +//========================================================================== + +const BYTE *FMultiPatchTexture::GetPixels () +{ + if (bRedirect) + { + return Parts->Texture->GetPixels (); + } + if (Pixels == NULL) + { + MakeTexture (); + } + return Pixels; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetColumn +// +//========================================================================== + +const BYTE *FMultiPatchTexture::GetColumn (unsigned int column, const Span **spans_out) +{ + if (bRedirect) + { + return Parts->Texture->GetColumn (column, spans_out); + } + if (Pixels == NULL) + { + MakeTexture (); + } + if ((unsigned)column >= (unsigned)Width) + { + if (WidthMask + 1 == Width) + { + column &= WidthMask; + } + else + { + column %= Width; + } + } + if (spans_out != NULL) + { + if (Spans == NULL) + { + Spans = CreateSpans (Pixels); + } + *spans_out = Spans[column]; + } + return Pixels + column*Height; +} + + +//========================================================================== +// +// GetBlendMap +// +//========================================================================== + +BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) +{ + + switch (blend.a==0 ? int(blend) : -1) + { + case BLEND_ICEMAP: + return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; + + default: + if (blend >= BLEND_SPECIALCOLORMAP1 && blend < BLEND_SPECIALCOLORMAP1 + SpecialColormaps.Size()) + { + return SpecialColormaps[blend - BLEND_SPECIALCOLORMAP1].Colormap; + } + else if (blend >= BLEND_DESATURATE1 && blend <= BLEND_DESATURATE31) + { + return DesaturateColormap[blend - BLEND_DESATURATE1]; + } + else + { + blendwork[0]=0; + if (blend.a == 255) + { + for(int i=1;i<256;i++) + { + int rr = (blend.r * GPalette.BaseColors[i].r) / 255; + int gg = (blend.g * GPalette.BaseColors[i].g) / 255; + int bb = (blend.b * GPalette.BaseColors[i].b) / 255; + + blendwork[i] = ColorMatcher.Pick(rr, gg, bb); + } + return blendwork; + } + else if (blend.a != 0) + { + for(int i=1;i<256;i++) + { + int rr = (blend.r * blend.a + GPalette.BaseColors[i].r * (255-blend.a)) / 255; + int gg = (blend.g * blend.a + GPalette.BaseColors[i].g * (255-blend.a)) / 255; + int bb = (blend.b * blend.a + GPalette.BaseColors[i].b * (255-blend.a)) / 255; + + blendwork[i] = ColorMatcher.Pick(rr, gg, bb); + } + return blendwork; + } + } + } + return NULL; +} + +//========================================================================== +// +// FMultiPatchTexture :: MakeTexture +// +//========================================================================== + +void FMultiPatchTexture::MakeTexture () +{ + // Add a little extra space at the end if the texture's height is not + // a power of 2, in case somebody accidentally makes it repeat vertically. + int numpix = Width * Height + (1 << HeightBits) - Height; + BYTE blendwork[256]; + bool hasTranslucent = false; + + Pixels = new BYTE[numpix]; + memset (Pixels, 0, numpix); + + for (int i = 0; i < NumParts; ++i) + { + if (Parts[i].op != OP_COPY) + { + hasTranslucent = true; + } + } + + if (!hasTranslucent) + { + for (int i = 0; i < NumParts; ++i) + { + if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. + + BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL; + { + if (Parts[i].Blend != 0) + { + trans = GetBlendMap(Parts[i].Blend, blendwork); + } + Parts[i].Texture->CopyToBlock (Pixels, Width, Height, + Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans); + } + } + } + else + { + // In case there are translucent patches let's do the composition in + // True color to keep as much precision as possible before downconverting to the palette. + BYTE *buffer = new BYTE[Width * Height * 4]; + memset(buffer, 0, Width * Height * 4); + FillBuffer(buffer, Width * 4, Height, TEX_RGB); + for(int y = 0; y < Height; y++) + { + BYTE *in = buffer + Width * y * 4; + BYTE *out = Pixels + y; + for (int x = 0; x < Width; x++) + { + if (*out == 0 && in[3] != 0) + { + *out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3]; + } + out += Height; + in += 4; + } + } + delete [] buffer; + } +} + +//=========================================================================== +// +// FMultipatchTexture::CopyTrueColorPixels +// +// Preserves the palettes of each individual patch +// +//=========================================================================== + +int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +{ + int retv = -1; + + if (bRedirect) + { // Redirect straight to the real texture's routine. + return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf); + } + + if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE))) + { // We are doing some sort of fancy stuff to the destination bitmap, so composite to + // a temporary bitmap, and copy that. + FBitmap tbmp; + if (tbmp.Create(Width, Height)) + { + retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0)); + bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height, + 4, tbmp.GetPitch(), rotate, CF_BGRA, inf); + } + return retv; + } + + // When compositing a multipatch texture with multipatch parts, + // drawing must be restricted to the actual area which is covered by this texture. + FClipRect saved_cr = bmp->GetClipRect(); + bmp->IntersectClipRect(x, y, Width, Height); + + if (inf != NULL && inf->op == OP_OVERWRITE) + { + bmp->Zero(); + } + + for(int i = 0; i < NumParts; i++) + { + int ret = -1; + FCopyInfo info; + + if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. + + memset (&info, 0, sizeof(info)); + info.alpha = Parts[i].Alpha; + info.invalpha = FRACUNIT - info.alpha; + info.op = ECopyOp(Parts[i].op); + PalEntry b = Parts[i].Blend; + if (b.a == 0 && b != BLEND_NONE) + { + info.blend = EBlend(b.d); + } + else if (b.a != 0) + { + if (b.a == 255) + { + info.blendcolor[0] = b.r * FRACUNIT / 255; + info.blendcolor[1] = b.g * FRACUNIT / 255; + info.blendcolor[2] = b.b * FRACUNIT / 255; + info.blend = BLEND_MODULATE; + } + else + { + fixed_t blendalpha = b.a * FRACUNIT / 255; + info.blendcolor[0] = b.r * blendalpha; + info.blendcolor[1] = b.g * blendalpha; + info.blendcolor[2] = b.b * blendalpha; + info.blendcolor[3] = FRACUNIT - blendalpha; + info.blend = BLEND_OVERLAY; + } + } + + if (Parts[i].Translation != NULL) + { // Using a translation forces downconversion to the base palette + ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation, &info); + } + else + { + ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info); + } + + if (ret > retv) retv = ret; + } + // Restore previous clipping rectangle. + bmp->SetClipRect(saved_cr); + return retv; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetFormat +// +// only returns 'paletted' if all patches use the base palette. +// +//========================================================================== + +FTextureFormat FMultiPatchTexture::GetFormat() +{ + if (bComplex) return TEX_RGB; + if (NumParts == 1) return Parts[0].Texture->GetFormat(); + return UseBasePalette() ? TEX_Pal : TEX_RGB; +} + + +//=========================================================================== +// +// FMultipatchTexture::UseBasePalette +// +// returns true if all patches in the texture use the unmodified base +// palette. +// +//=========================================================================== + +bool FMultiPatchTexture::UseBasePalette() +{ + if (bComplex) return false; + for(int i=0;iUseBasePalette()) return false; + } + return true; +} + +//========================================================================== +// +// FMultiPatchTexture :: CheckForHacks +// +//========================================================================== + +void FMultiPatchTexture::CheckForHacks () +{ + if (NumParts <= 0) + { + return; + } + + // Heretic sky textures are marked as only 128 pixels tall, + // even though they are really 200 pixels tall. + if (gameinfo.gametype == GAME_Heretic && + Name[0] == 'S' && + Name[1] == 'K' && + Name[2] == 'Y' && + Name[4] == 0 && + Name[3] >= '1' && + Name[3] <= '3' && + Height == 128) + { + Height = 200; + HeightBits = 8; + return; + } + + // The Doom E1 sky has its patch's y offset at -8 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + NumParts == 1 && + Height == 128 && + Parts->OriginY == -8 && + Name[0] == 'S' && + Name[1] == 'K' && + Name[2] == 'Y' && + Name[3] == '1' && + Name[4] == 0) + { + Parts->OriginY = 0; + return; + } + + // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + NumParts == 2 && + Height == 128 && + Parts[0].OriginY == -4 && + Parts[1].OriginY == -4 && + Name[0] == 'B' && + Name[1] == 'I' && + Name[2] == 'G' && + Name[3] == 'D' && + Name[4] == 'O' && + Name[5] == 'O' && + Name[6] == 'R' && + Name[7] == '7') + { + Parts[0].OriginY = 0; + Parts[1].OriginY = 0; + return; + } + + // [RH] Some wads (I forget which!) have single-patch textures 256 + // pixels tall that have patch lengths recorded as 0. I can't think of + // any good reason for them to do this, and since I didn't make note + // of which wad made me hack in support for them, the hack is gone + // because I've added support for DeePsea's true tall patches. + // + // Okay, I found a wad with crap patches: Pleiades.wad's sky patches almost + // fit this description and are a big mess, but they're not single patch! + if (Height == 256) + { + int i; + + // All patches must be at the top of the texture for this fix + for (i = 0; i < NumParts; ++i) + { + if (Parts[i].OriginY != 0) + { + break; + } + } + + if (i == NumParts) + { + for (i = 0; i < NumParts; ++i) + { + Parts[i].Texture->HackHack(256); + } + } + } +} + +//========================================================================== +// +// FMultiPatchTexture :: GetRedirect +// +//========================================================================== + +FTexture *FMultiPatchTexture::GetRedirect(bool wantwarped) +{ + return bRedirect ? Parts->Texture : this; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetRawTexture +// +// Doom ignored all compositing of mid-sided textures on two-sided lines. +// Since these textures had to be single-patch in Doom, that essentially +// means it ignores their Y offsets. +// +// If this texture is composed of only one patch, return that patch. +// Otherwise, return this texture, since Doom wouldn't have been able to +// draw it anyway. +// +//========================================================================== + +FTexture *FMultiPatchTexture::GetRawTexture() +{ + return NumParts == 1 ? Parts->Texture : this; +} + +//========================================================================== +// +// FMultiPatchTexture :: TexPart :: TexPart +// +//========================================================================== + +FMultiPatchTexture::TexPart::TexPart() +{ + OriginX = OriginY = 0; + Rotate = 0; + Texture = NULL; + Translation = NULL; + Blend = 0; + Alpha = FRACUNIT; + op = OP_COPY; +} + +//========================================================================== +// +// FTextureManager :: AddTexturesLump +// +//========================================================================== + +void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) +{ + FPatchLookup *patchlookup = NULL; + int i; + DWORD numpatches; + + if (firstdup == 0) + { + firstdup = (int)Textures.Size(); + } + + { + FWadLump pnames = Wads.OpenLumpNum (patcheslump); + + pnames >> numpatches; + + // Check whether the amount of names reported is correct. + if ((signed)numpatches < 0) + { + Printf("Corrupt PNAMES lump found (negative amount of entries reported)"); + return; + } + + // Check whether the amount of names reported is correct. + int lumplength = Wads.LumpLength(patcheslump); + if (numpatches > DWORD((lumplength-4)/8)) + { + Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", + numpatches, lumplength, (lumplength-4)/8); + // Truncate but continue reading. Who knows how many such lumps exist? + numpatches = (lumplength-4)/8; + } + + // Catalog the patches these textures use so we know which + // textures they represent. + patchlookup = new FPatchLookup[numpatches]; + for (DWORD i = 0; i < numpatches; ++i) + { + char pname[9]; + pnames.Read(pname, 8); + pname[8] = '\0'; + patchlookup[i].Name = pname; + FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); + if (j.isValid()) + { + patchlookup[i].Texture = Textures[j.GetIndex()].Texture; + } + else + { + // Shareware Doom has the same PNAMES lump as the registered + // Doom, so printing warnings for patches that don't really + // exist isn't such a good idea. + //Printf ("Patch %s not found.\n", patchlookup[i].Name); + patchlookup[i].Texture = NULL; + } + } + } + + bool isStrife = false; + const DWORD *maptex, *directory; + DWORD maxoff; + int numtextures; + DWORD offset = 0; // Shut up, GCC! + + maptex = (const DWORD *)lumpdata; + numtextures = LittleLong(*maptex); + maxoff = lumpsize; + + if (maxoff < DWORD(numtextures+1)*4) + { + Printf ("Texture directory is too short"); + delete[] patchlookup; + return; + } + + // Scan the texture lump to decide if it contains Doom or Strife textures + for (i = 0, directory = maptex+1; i < numtextures; ++i) + { + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf ("Bad texture directory"); + delete[] patchlookup; + return; + } + + maptexture_t *tex = (maptexture_t *)((BYTE *)maptex + offset); + + // There is bizzarely a Doom editing tool that writes to the + // first two elements of columndirectory, so I can't check those. + if (SAFESHORT(tex->patchcount) < 0 || + tex->columndirectory[2] != 0 || + tex->columndirectory[3] != 0) + { + isStrife = true; + break; + } + } + + + // Textures defined earlier in the lump take precedence over those defined later, + // but later TEXTUREx lumps take precedence over earlier ones. + for (i = 1, directory = maptex; i <= numtextures; ++i) + { + if (i == 1 && texture1) + { + // The very first texture is just a dummy. Copy its dimensions to texture 0. + // It still needs to be created in case someone uses it by name. + offset = LittleLong(directory[1]); + const maptexture_t *tex = (const maptexture_t *)((const BYTE *)maptex + offset); + FDummyTexture *tex0 = static_cast(Textures[0].Texture); + tex0->SetSize (SAFESHORT(tex->width), SAFESHORT(tex->height)); + } + + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf ("Bad texture directory"); + delete[] patchlookup; + return; + } + + // If this texture was defined already in this lump, skip it + // This could cause problems with animations that use the same name for intermediate + // textures. Should I be worried? + int j; + for (j = (int)Textures.Size() - 1; j >= firstdup; --j) + { + if (strnicmp (Textures[j].Texture->Name, (const char *)maptex + offset, 8) == 0) + break; + } + if (j + 1 == firstdup) + { + FMultiPatchTexture *tex = new FMultiPatchTexture ((const BYTE *)maptex + offset, patchlookup, numpatches, isStrife, deflumpnum); + if (i == 1 && texture1) + { + tex->UseType = FTexture::TEX_FirstDefined; + } + TexMan.AddTexture (tex); + StartScreen->Progress(); + } + } + delete[] patchlookup; +} + + +//========================================================================== +// +// FTextureManager :: AddTexturesLumps +// +//========================================================================== + +void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) +{ + int firstdup = (int)Textures.Size(); + + if (lump1 >= 0) + { + FMemLump texdir = Wads.ReadLump (lump1); + AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump1), lump1, patcheslump, firstdup, true); + } + if (lump2 >= 0) + { + FMemLump texdir = Wads.ReadLump (lump2); + AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump2), lump2, patcheslump, firstdup, false); + } +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, int usetype) +{ + FString patchname; + sc.MustGetString(); + + FTextureID texno = TexMan.CheckForTexture(sc.String, usetype); + int Mirror = 0; + + if (!texno.isValid()) + { + if (strlen(sc.String) <= 8 && !strpbrk(sc.String, "./")) + { + int lumpnum = Wads.CheckNumForName(sc.String, usetype == TEX_MiscPatch? ns_graphics : ns_patches); + if (lumpnum >= 0) + { + part.Texture = FTexture::CreateTexture(lumpnum, usetype); + TexMan.AddTexture(part.Texture); + } + } + } + else + { + part.Texture = TexMan[texno]; + bComplex |= part.Texture->bComplex; + } + if (part.Texture == NULL) + { + if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); + } + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginX = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginY = sc.Number; + + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("flipx")) + { + Mirror |= 1; + } + else if (sc.Compare("flipy")) + { + Mirror |= 2; + } + else if (sc.Compare("rotate")) + { + sc.MustGetNumber(); + sc.Number = (((sc.Number + 90)%360)-90); + if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) + { + sc.ScriptError("Rotation must be a multiple of 90 degrees."); + } + part.Rotate = (sc.Number / 90) & 3; + } + else if (sc.Compare("Translation")) + { + int match; + + bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; + sc.MustGetString(); + + match = sc.MatchString(maps); + if (match >= 0) + { + part.Blend = BLEND_SPECIALCOLORMAP1 + match; + } + else if (sc.Compare("ICE")) + { + part.Blend = BLEND_ICEMAP; + } + else if (sc.Compare("DESATURATE")) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); + } + else + { + sc.UnGet(); + part.Translation = new FRemapTable; + part.Translation->MakeIdentity(); + do + { + sc.MustGetString(); + part.Translation->AddToTranslation(sc.String); + } + while (sc.CheckString(",")); + } + + } + else if (sc.Compare("Colormap")) + { + float r1,g1,b1; + float r2,g2,b2; + + sc.MustGetFloat(); + r1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b1 = (float)sc.Float; + if (!sc.CheckString(",")) + { + part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); + } + else + { + sc.MustGetFloat(); + r2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b2 = (float)sc.Float; + part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); + } + } + else if (sc.Compare("Blend")) + { + bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + + if (!sc.CheckNumber()) + { + sc.MustGetString(); + part.Blend = V_GetColor(NULL, sc.String); + } + else + { + int r,g,b; + + r = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + g = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + b = sc.Number; + sc.MustGetStringName(","); + part.Blend = MAKERGB(r, g, b); + } + // Blend.a may never be 0 here. + if (sc.CheckString(",")) + { + sc.MustGetFloat(); + if (sc.Float > 0.f) + part.Blend.a = clamp(int(sc.Float*255), 1, 254); + else + part.Blend = 0; + } + else part.Blend.a = 255; + } + else if (sc.Compare("alpha")) + { + sc.MustGetFloat(); + part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT); + // bComplex is not set because it is only needed when the style is not OP_COPY. + } + else if (sc.Compare("style")) + { + static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; + sc.MustGetString(); + part.op = sc.MustMatchString(styles); + bComplex |= (part.op != OP_COPY); + bTranslucentPatches = bComplex; + } + else if (sc.Compare("useoffsets")) + { + if (part.Texture != NULL) + { + part.OriginX -= part.Texture->LeftOffset; + part.OriginY -= part.Texture->TopOffset; + } + } + } + } + if (Mirror & 2) + { + part.Rotate = (part.Rotate + 2) & 3; + Mirror ^= 1; + } + if (Mirror & 1) + { + part.Rotate |= 4; + } +} + +//========================================================================== +// +// Constructor for text based multipatch definitions +// +//========================================================================== + +FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) +: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +{ + TArray parts; + bool bSilent = false; + + bMultiPatch = true; + sc.SetCMode(true); + sc.MustGetString(); + const char* textureName = NULL; + if (sc.Compare("optional")) + { + bSilent = true; + sc.MustGetString(); + if (sc.Compare(",")) + { + // this is not right. Apparently a texture named 'optional' is being defined right now... + sc.UnGet(); + textureName = "optional"; + bSilent = false; + } + } + Name = !textureName ? sc.String : textureName; + Name.ToUpper(); + sc.MustGetStringName(","); + sc.MustGetNumber(); + Width = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + Height = sc.Number; + UseType = usetype; + + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("XScale")) + { + sc.MustGetFloat(); + xScale = FLOAT2FIXED(sc.Float); + if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); + } + else if (sc.Compare("YScale")) + { + sc.MustGetFloat(); + yScale = FLOAT2FIXED(sc.Float); + if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); + } + else if (sc.Compare("WorldPanning")) + { + bWorldPanning = true; + } + else if (sc.Compare("NullTexture")) + { + UseType = FTexture::TEX_Null; + } + else if (sc.Compare("NoDecals")) + { + bNoDecals = true; + } + else if (sc.Compare("Patch")) + { + TexPart part; + ParsePatch(sc, part, bSilent, TEX_WallPatch); + if (part.Texture != NULL) parts.Push(part); + part.Texture = NULL; + part.Translation = NULL; + } + else if (sc.Compare("Graphic")) + { + TexPart part; + ParsePatch(sc, part, bSilent, TEX_MiscPatch); + if (part.Texture != NULL) parts.Push(part); + part.Texture = NULL; + part.Translation = NULL; + } + else if (sc.Compare("Offset")) + { + sc.MustGetNumber(); + LeftOffset = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + TopOffset = sc.Number; + } + else + { + sc.ScriptError("Unknown texture property '%s'", sc.String); + } + } + + NumParts = parts.Size(); + Parts = new TexPart[NumParts]; + memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); + + //CalcBitSize (); + + // If this texture is just a wrapper around a single patch, we can simply + // forward GetPixels() and GetColumn() calls to that patch. + if (NumParts == 1) + { + if (Parts->OriginX == 0 && Parts->OriginY == 0 && + Parts->Texture->GetWidth() == Width && + Parts->Texture->GetHeight() == Height && + Parts->Rotate == 0 && + !bComplex) + { + bRedirect = true; + } + } + } + + if (Width <= 0 || Height <= 0) + { + UseType = FTexture::TEX_Null; + Printf("Texture %s has invalid dimensions (%d, %d)\n", Name, Width, Height); + Width = Height = 1; + } + CalcBitSize (); + + + sc.SetCMode(false); +} + + + +void FTextureManager::ParseXTexture(FScanner &sc, int usetype) +{ + FTexture *tex = new FMultiPatchTexture(sc, usetype); + TexMan.AddTexture (tex); +} From 8ec95dc58eba6a0197b733ff2a6f7a3dc5b6b36b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 20 May 2014 10:14:44 +0200 Subject: [PATCH 221/311] - fixed a few places in the savegame code where map names were still truncated to 8 characters. --- src/g_level.cpp | 109 ++++++++++++++++++++++++++---------------------- src/version.h | 2 +- 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 8c97a399c..c4aafda4b 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1597,30 +1597,9 @@ void G_UnSnapshotLevel (bool hubLoad) // //========================================================================== -static void writeMapName (FArchive &arc, const char *name) -{ - BYTE size; - if (name[7] != 0) - { - size = 8; - } - else - { - size = (BYTE)strlen (name); - } - arc << size; - arc.Write (name, size); -} - -//========================================================================== -// -// -//========================================================================== - static void writeSnapShot (FArchive &arc, level_info_t *i) { - arc << i->snapshotVer; - writeMapName (arc, i->MapName); + arc << i->snapshotVer << i->MapName; i->snapshot->Serialize (arc); } @@ -1658,14 +1637,14 @@ void G_WriteSnapshots (FILE *file) { arc = new FPNGChunkArchive (file, VIST_ID); } - writeMapName (*arc, wadlevelinfos[i].MapName); + (*arc) << wadlevelinfos[i].MapName; } } if (arc != NULL) { - BYTE zero = 0; - *arc << zero; + FString empty = ""; + (*arc) << empty; delete arc; } @@ -1706,6 +1685,7 @@ void G_ReadSnapshots (PNGHandle *png) DWORD chunkLen; BYTE namelen; char mapname[256]; + FString MapName; level_info_t *i; G_ClearSnapshots (); @@ -1717,10 +1697,15 @@ void G_ReadSnapshots (PNGHandle *png) DWORD snapver; arc << snapver; - arc << namelen; - arc.Read (mapname, namelen); - mapname[namelen] = 0; - i = FindLevelInfo (mapname); + if (SaveVersion < 4508) + { + arc << namelen; + arc.Read(mapname, namelen); + mapname[namelen] = 0; + MapName = mapname; + } + else arc << MapName; + i = FindLevelInfo (MapName); i->snapshotVer = snapver; i->snapshot = new FCompressedMemFile; i->snapshot->Serialize (arc); @@ -1746,14 +1731,25 @@ void G_ReadSnapshots (PNGHandle *png) { FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen); - arc << namelen; - while (namelen != 0) + if (SaveVersion < 4508) { - arc.Read (mapname, namelen); - mapname[namelen] = 0; - i = FindLevelInfo (mapname); - i->flags |= LEVEL_VISITED; arc << namelen; + while (namelen != 0) + { + arc.Read(mapname, namelen); + mapname[namelen] = 0; + i = FindLevelInfo(mapname); + i->flags |= LEVEL_VISITED; + arc << namelen; + } + } + else + { + while (arc << MapName, MapName.Len() > 0) + { + i = FindLevelInfo(MapName); + i->flags |= LEVEL_VISITED; + } } } @@ -1809,8 +1805,7 @@ CCMD(listsnapshots) static void writeDefereds (FArchive &arc, level_info_t *i) { - writeMapName (arc, i->MapName); - arc << i->defered; + arc << i->MapName << i->defered; } //========================================================================== @@ -1837,8 +1832,8 @@ void P_WriteACSDefereds (FILE *file) if (arc != NULL) { // Signal end of defereds - BYTE zero = 0; - *arc << zero; + FString empty = ""; + (*arc) << empty; delete arc; } } @@ -1852,6 +1847,7 @@ void P_ReadACSDefereds (PNGHandle *png) { BYTE namelen; char mapname[256]; + FString MapName; size_t chunklen; P_RemoveDefereds (); @@ -1860,18 +1856,33 @@ void P_ReadACSDefereds (PNGHandle *png) { FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); - arc << namelen; - while (namelen) + if (SaveVersion < 4508) { - arc.Read (mapname, namelen); - mapname[namelen] = 0; - level_info_t *i = FindLevelInfo (mapname); - if (i == NULL) - { - I_Error ("Unknown map '%s' in savegame", mapname); - } - arc << i->defered; arc << namelen; + while (namelen != 0) + { + arc.Read(mapname, namelen); + mapname[namelen] = 0; + level_info_t *i = FindLevelInfo(mapname); + if (i == NULL) + { + I_Error("Unknown map '%s' in savegame", mapname); + } + arc << i->defered; + arc << namelen; + } + } + else + { + while (arc << MapName, MapName.Len() > 0) + { + level_info_t *i = FindLevelInfo(MapName); + if (i == NULL) + { + I_Error("Unknown map '%s' in savegame", MapName.GetChars()); + } + arc << i->defered; + } } } png->File->ResetFilePtr(); diff --git a/src/version.h b/src/version.h index 8e853057a..6c94bf3e6 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4507 +#define SAVEVER 4508 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 261bc778467ac07657b35ca92e0d0f69a092a32e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 20 May 2014 10:29:27 +0200 Subject: [PATCH 222/311] - fixed: when bringing up a new weapon the current flash state needs to be removed. Especially when dropping the current weapon it can still be active, this is most easily observed with Strife's crossbow which loops the flash state, but it also can happen with other weapons, right after shooting. --- src/p_pspr.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 85830ac55..49f8bcb84 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -208,6 +208,9 @@ void P_BringUpWeapon (player_t *player) player->psprites[ps_weapon].sy = player->cheats & CF_INSTANTWEAPSWITCH ? WEAPONTOP : WEAPONBOTTOM; P_SetPsprite (player, ps_weapon, newstate); + // make sure that the previous weapon's flash state is terminated. + // When coming here from a weapon drop it may still be active. + P_SetPsprite(player, ps_flash, NULL); } From 9d846395bc0e78a3881ea8530502125191a5a4c9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 24 May 2014 21:05:00 +0200 Subject: [PATCH 223/311] - replaced console buffer with a significantly more efficient new version that also can hold a lot more data. --- src/CMakeLists.txt | 1 + src/c_console.cpp | 402 +++++----------------------------------- src/c_console.h | 3 + src/c_consolebuffer.cpp | 317 +++++++++++++++++++++++++++++++ src/c_consolebuffer.h | 85 +++++++++ src/nodebuild.cpp | 6 - src/v_text.cpp | 4 +- src/v_text.h | 6 +- 8 files changed, 458 insertions(+), 366 deletions(-) create mode 100644 src/c_consolebuffer.cpp create mode 100644 src/c_consolebuffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5203b294c..517b6bdbe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -789,6 +789,7 @@ add_executable( zdoom WIN32 c_bind.cpp c_cmds.cpp c_console.cpp + c_consolebuffer.cpp c_cvars.cpp c_dispatch.cpp c_expr.cpp diff --git a/src/c_console.cpp b/src/c_console.cpp index 396b2dfce..4dabdb9e1 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -65,22 +65,29 @@ #include "g_level.h" #include "d_event.h" #include "d_player.h" +#include "c_consolebuffer.h" #include "gi.h" -#define CONSOLESIZE 16384 // Number of characters to store in console -#define CONSOLELINES 256 // Max number of lines of console text -#define LINEMASK (CONSOLELINES-1) - #define LEFTMARGIN 8 #define RIGHTMARGIN 8 #define BOTTOMARGIN 12 + +CUSTOM_CVAR(Int, con_buffersize, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + // ensure a minimum size + if (self >= 0 && self < 128) self = 128; +} + +FConsoleBuffer *conbuffer; + static void C_TabComplete (bool goForward); static bool C_TabCompleteList (); static bool TabbedLast; // True if last key pressed was tab static bool TabbedList; // True if tab list was shown -CVAR (Bool, con_notablist, false, CVAR_ARCHIVE) +CVAR(Bool, con_notablist, false, CVAR_ARCHIVE) + static FTextureID conback; static DWORD conshade; @@ -94,18 +101,15 @@ extern FBaseCVar *CVars; extern FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; int ConCols, PhysRows; +int ConWidth; bool vidactive = false; bool cursoron = false; int ConBottom, ConScroll, RowAdjust; int CursorTicker; constate_e ConsoleState = c_up; -static char ConsoleBuffer[CONSOLESIZE]; -static char *Lines[CONSOLELINES]; -static bool LineJoins[CONSOLELINES]; static int TopLine, InsertLine; -static char *BufferRover = ConsoleBuffer; static void ClearConsole (); static void C_PasteText(FString clip, BYTE *buffer, int len); @@ -182,7 +186,6 @@ static struct NotifyText static int NotifyTop, NotifyTopGoal; -#define PRINTLEVELS 5 int PrintColors[PRINTLEVELS+2] = { CR_RED, CR_GOLD, CR_GRAY, CR_GREEN, CR_GREEN, CR_GOLD }; static void setmsgcolor (int index, int color); @@ -328,78 +331,11 @@ void C_InitConsole (int width, int height, bool ingame) { cwidth = cheight = 8; } - ConCols = (width - LEFTMARGIN - RIGHTMARGIN) / cwidth; + ConWidth = (width - LEFTMARGIN - RIGHTMARGIN); + ConCols = ConWidth / cwidth; PhysRows = height / cheight; - // If there is some text in the console buffer, reformat it - // for the new resolution. - if (TopLine != InsertLine) - { - // Note: Don't use new here, because we attach a handler to new in - // i_main.cpp that calls I_FatalError if the allocation fails, - // but we can gracefully handle such a condition here by just - // clearing the console buffer. (OTOH, what are the chances that - // any other memory allocations would succeed if we can't get - // these mallocs here?) - - char *fmtBuff = (char *)malloc (CONSOLESIZE); - char **fmtLines = (char **)malloc (CONSOLELINES*sizeof(char*)*4); - int out = 0; - - if (fmtBuff && fmtLines) - { - int in; - char *fmtpos; - bool newline = true; - - fmtpos = fmtBuff; - memset (fmtBuff, 0, CONSOLESIZE); - - for (in = TopLine; in != InsertLine; in = (in + 1) & LINEMASK) - { - size_t len = strlen (Lines[in]); - - if (fmtpos + len + 2 - fmtBuff > CONSOLESIZE) - { - break; - } - if (newline) - { - newline = false; - fmtLines[out++] = fmtpos; - } - strcpy (fmtpos, Lines[in]); - fmtpos += len; - if (!LineJoins[in]) - { - *fmtpos++ = '\n'; - fmtpos++; - if (out == CONSOLELINES*4) - { - break; - } - newline = true; - } - } - } - - ClearConsole (); - - if (fmtBuff && fmtLines) - { - int i; - - for (i = 0; i < out; i++) - { - AddToConsole (-1, fmtLines[i]); - } - } - - if (fmtBuff) - free (fmtBuff); - if (fmtLines) - free (fmtLines); - } + if (conbuffer == NULL) conbuffer = new FConsoleBuffer; } //========================================================================== @@ -507,16 +443,21 @@ void C_DeinitConsole () work = NULL; worklen = 0; } + + if (conbuffer != NULL) + { + delete conbuffer; + conbuffer = NULL; + } } static void ClearConsole () { - RowAdjust = 0; + if (conbuffer != NULL) + { + conbuffer->Clear(); + } TopLine = InsertLine = 0; - BufferRover = ConsoleBuffer; - memset (ConsoleBuffer, 0, CONSOLESIZE); - memset (Lines, 0, sizeof(Lines)); - memset (LineJoins, 0, sizeof(LineJoins)); } static void setmsgcolor (int index, int color) @@ -596,223 +537,9 @@ void C_AddNotifyString (int printlevel, const char *source) NotifyTopGoal = 0; } -static int FlushLines (const char *start, const char *stop) -{ - int i; - - for (i = TopLine; i != InsertLine; i = (i + 1) & LINEMASK) - { - if (Lines[i] < stop && Lines[i] + strlen (Lines[i]) > start) - { - Lines[i] = NULL; - } - else - { - break; - } - } - return i; -} - -static void AddLine (const char *text, bool more, size_t len) -{ - if (BufferRover + len + 1 - ConsoleBuffer > CONSOLESIZE) - { - TopLine = FlushLines (BufferRover, ConsoleBuffer + CONSOLESIZE); - BufferRover = ConsoleBuffer; - } - if (len >= CONSOLESIZE - 1) - { - text = text + len - CONSOLESIZE + 1; - len = CONSOLESIZE - 1; - } - TopLine = FlushLines (BufferRover, BufferRover + len + 1); - memcpy (BufferRover, text, len); - BufferRover[len] = 0; - Lines[InsertLine] = BufferRover; - BufferRover += len + 1; - LineJoins[InsertLine] = more; - InsertLine = (InsertLine + 1) & LINEMASK; - if (InsertLine == TopLine) - { - TopLine = (TopLine + 1) & LINEMASK; - } -} - void AddToConsole (int printlevel, const char *text) { - static enum - { - NEWLINE, - APPENDLINE, - REPLACELINE - } addtype = NEWLINE; - - char *work_p; - char *linestart; - FString cc('A' + char(CR_TAN)); - int size, len; - int x; - int maxwidth; - - if (ConsoleDrawing) - { - EnqueueConsoleText (false, printlevel, text); - return; - } - - len = (int)strlen (text); - size = len + 20; - - if (addtype != NEWLINE) - { - InsertLine = (InsertLine - 1) & LINEMASK; - if (Lines[InsertLine] == NULL) - { - InsertLine = (InsertLine + 1) & LINEMASK; - addtype = NEWLINE; - } - else - { - BufferRover = Lines[InsertLine]; - } - } - if (addtype == APPENDLINE) - { - size += (int)strlen (Lines[InsertLine]); - } - if (size > worklen) - { - work = (char *)M_Realloc (work, size); - worklen = size; - } - if (work == NULL) - { - static char oom[] = TEXTCOLOR_RED "*** OUT OF MEMORY ***"; - work = oom; - worklen = 0; - } - else - { - if (addtype == APPENDLINE) - { - strcpy (work, Lines[InsertLine]); - strcat (work, text); - } - else if (printlevel >= 0) - { - work[0] = TEXTCOLOR_ESCAPE; - work[1] = 'A' + (printlevel == PRINT_HIGH ? CR_TAN : - printlevel == 200 ? CR_GREEN : - printlevel < PRINTLEVELS ? PrintColors[printlevel] : - CR_TAN); - cc = work[1]; - strcpy (work + 2, text); - } - else - { - strcpy (work, text); - } - } - - work_p = linestart = work; - - if (ConFont != NULL && screen != NULL) - { - x = 0; - maxwidth = screen->GetWidth() - LEFTMARGIN - RIGHTMARGIN; - - while (*work_p) - { - if (*work_p == TEXTCOLOR_ESCAPE) - { - work_p++; - if (*work_p == '[') - { - char *start = work_p; - while (*work_p != ']' && *work_p != '\0') - { - work_p++; - } - if (*work_p != '\0') - { - work_p++; - } - cc = FString(start, work_p - start); - } - else if (*work_p != '\0') - { - cc = *work_p++; - } - continue; - } - int w = ConFont->GetCharWidth (*work_p); - if (*work_p == '\n' || x + w > maxwidth) - { - AddLine (linestart, *work_p != '\n', work_p - linestart); - if (*work_p == '\n') - { - x = 0; - work_p++; - } - else - { - x = w; - } - if (*work_p) - { - linestart = work_p - 1 - cc.Len(); - if (linestart < work) - { - // The line start is outside the buffer. - // Make space for the newly inserted stuff. - size_t movesize = work-linestart; - memmove(work + movesize, work, strlen(work)+1); - work_p += movesize; - linestart = work; - } - linestart[0] = TEXTCOLOR_ESCAPE; - strncpy (linestart + 1, cc, cc.Len()); - } - else - { - linestart = work_p; - } - } - else - { - x += w; - work_p++; - } - } - - if (*linestart) - { - AddLine (linestart, true, work_p - linestart); - } - } - else - { - while (*work_p) - { - if (*work_p++ == '\n') - { - AddLine (linestart, false, work_p - linestart - 1); - linestart = work_p; - } - } - if (*linestart) - { - AddLine (linestart, true, work_p - linestart); - } - } - - switch (text[len-1]) - { - case '\r': addtype = REPLACELINE; break; - case '\n': addtype = NEWLINE; break; - default: addtype = APPENDLINE; break; - } + conbuffer->AddText(printlevel, text, Logfile); } /* Adds a string to the console and also to the notify buffer */ @@ -823,34 +550,6 @@ int PrintString (int printlevel, const char *outline) return 0; } - if (Logfile) - { - // Strip out any color escape sequences before writing to the log file - char * copy = new char[strlen(outline)+1]; - const char * srcp = outline; - char * dstp = copy; - - while (*srcp != 0) - { - if (*srcp!=0x1c) - { - *dstp++=*srcp++; - } - else - { - if (srcp[1]!=0) srcp+=2; - else break; - } - } - *dstp=0; - - fputs (copy, Logfile); - delete [] copy; -//#ifdef _DEBUG - fflush (Logfile); -//#endif - } - if (printlevel != PRINT_LOG) { I_PrintStr (outline); @@ -949,6 +648,11 @@ void C_Ticker () if (lasttic == 0) lasttic = gametic - 1; + if (con_buffersize > 0) + { + conbuffer->ResizeBuffer(con_buffersize); + } + if (ConsoleState != c_up) { if (ConsoleState == c_falling) @@ -1236,38 +940,22 @@ void C_DrawConsole (bool hw2d) if (lines > 0) { + // No more enqueuing because adding new text to the console won't touch the actual print data. + conbuffer->FormatText(ConFont, ConWidth); + unsigned int consolelines = conbuffer->GetFormattedLineCount(); + FBrokenLines **blines = conbuffer->GetLines(); + FBrokenLines **printline = blines + consolelines - 1 - RowAdjust; + int bottomline = ConBottom - ConFont->GetHeight()*2 - 4; - int pos = (InsertLine - 1) & LINEMASK; - int i; ConsoleDrawing = true; - for (i = RowAdjust; i; i--) + for(FBrokenLines **p = printline; p >= blines && lines > 0; p--, lines--) { - if (pos == TopLine) - { - RowAdjust = RowAdjust - i; - break; - } - else - { - pos = (pos - 1) & LINEMASK; - } + screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text, TAG_DONE); } - pos++; - do - { - pos = (pos - 1) & LINEMASK; - if (Lines[pos] != NULL) - { - screen->DrawText (ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), - Lines[pos], TAG_DONE); - } - lines--; - } while (pos != TopLine && lines > 0); ConsoleDrawing = false; - DequeueConsoleText (); if (ConBottom >= 20) { @@ -1293,7 +981,7 @@ void C_DrawConsole (bool hw2d) { // Indicate that the view has been scrolled up (10) // and if we can scroll no further (12) - screen->DrawChar (ConFont, CR_GREEN, 0, bottomline, pos == TopLine ? 12 : 10, TAG_DONE); + screen->DrawChar (ConFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE); } } } @@ -1445,7 +1133,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) RowAdjust += (SCREENHEIGHT-4) / ((gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) ? ConFont->GetHeight() : ConFont->GetHeight()*2) - 3; } - else if (RowAdjust < CONSOLELINES) + else if (RowAdjust < conbuffer->GetFormattedLineCount()) { // Scroll console buffer up if (ev->subtype == EV_GUI_WheelUp) { @@ -1455,6 +1143,10 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) { RowAdjust++; } + if (RowAdjust > conbuffer->GetFormattedLineCount()) + { + RowAdjust = conbuffer->GetFormattedLineCount(); + } } break; @@ -1488,7 +1180,7 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) case GK_HOME: if (ev->data3 & GKM_CTRL) { // Move to top of console buffer - RowAdjust = CONSOLELINES; + RowAdjust = conbuffer->GetFormattedLineCount(); } else { // Move cursor to start of line diff --git a/src/c_console.h b/src/c_console.h index 8560d6779..2c2e553f9 100644 --- a/src/c_console.h +++ b/src/c_console.h @@ -47,6 +47,9 @@ typedef enum cstate_t } constate_e; +#define PRINTLEVELS 5 +extern int PrintColors[PRINTLEVELS + 2]; + extern constate_e ConsoleState; extern int ConBottom; diff --git a/src/c_consolebuffer.cpp b/src/c_consolebuffer.cpp new file mode 100644 index 000000000..3f64f34e4 --- /dev/null +++ b/src/c_consolebuffer.cpp @@ -0,0 +1,317 @@ +/* +** consolebuffer.cpp +** +** manages the text for the console +** +**--------------------------------------------------------------------------- +** Copyright 2014 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "c_console.h" +#include "c_consolebuffer.h" + + +//========================================================================== +// +// +// +//========================================================================== + +FConsoleBuffer::FConsoleBuffer() +{ + mLogFile = NULL; + mAddType = NEWLINE; + mLastFont = NULL; + mLastDisplayWidth = -1; + mLastLineNeedsUpdate = false; + mTextLines = 0; + mBufferWasCleared = true; + mBrokenStart.Push(0); +} + +//========================================================================== +// +// +// +//========================================================================== + +FConsoleBuffer::~FConsoleBuffer() +{ + FreeBrokenText(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FConsoleBuffer::FreeBrokenText(unsigned start, unsigned end) +{ + if (end > mBrokenConsoleText.Size()) end = mBrokenConsoleText.Size(); + for (unsigned i = start; i < end; i++) + { + if (mBrokenConsoleText[i] != NULL) V_FreeBrokenLines(mBrokenConsoleText[i]); + mBrokenConsoleText[i] = NULL; + } +} + +//========================================================================== +// +// Adds a new line of text to the console +// This is kept as simple as possible. This function does not: +// - remove old text if the buffer gets larger than the specified size +// - format the text for the current screen layout +// +// These tasks will only be be performed once per frame because they are +// relatively expensive. The old console did them each time text was added +// resulting in extremely bad performance with a high output rate. +// +//========================================================================== + +void FConsoleBuffer::AddText(int printlevel, const char *text, FILE *logfile) +{ + FString build = TEXTCOLOR_TAN; + + if (mAddType == REPLACELINE) + { + // Just wondering: Do we actually need this case? If so, it may need some work. + mConsoleText.Pop(); // remove the line to be replaced + mLastLineNeedsUpdate = true; + } + else if (mAddType == APPENDLINE) + { + mConsoleText.Pop(build); + printlevel = -1; + mLastLineNeedsUpdate = true; + } + + if (printlevel >= 0 && printlevel != PRINT_HIGH) + { + if (printlevel == 200) build = TEXTCOLOR_GREEN; + else if (printlevel < PRINTLEVELS) build.Format("%c%c", TEXTCOLOR_ESCAPE, PrintColors[printlevel]); + } + + size_t textsize = strlen(text); + + if (text[textsize-1] == '\r') + { + textsize--; + mAddType = REPLACELINE; + } + else if (text[textsize-1] == '\n') + { + textsize--; + mAddType = NEWLINE; + } + else + { + mAddType = APPENDLINE; + } + + // don't bother about linefeeds etc. inside the text, we'll let the formatter sort this out later. + build.AppendCStrPart(text, textsize); + mConsoleText.Push(build); + if (logfile != NULL) WriteLineToLog(logfile, text); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FConsoleBuffer::WriteLineToLog(FILE *LogFile, const char *outline) +{ + // Strip out any color escape sequences before writing to the log file + char * copy = new char[strlen(outline)+1]; + const char * srcp = outline; + char * dstp = copy; + + while (*srcp != 0) + { + + if (*srcp != TEXTCOLOR_ESCAPE) + { + switch (*srcp) + { + case '\35': + *dstp++ = '<'; + break; + + case '\36': + *dstp++ = '-'; + break; + + case '\37': + *dstp++ = '>'; + break; + + default: + *dstp++=*srcp; + break; + } + srcp++; + } + else if (srcp[1] == '[') + { + srcp+=2; + while (*srcp != ']' && *srcp != 0) srcp++; + if (*srcp == ']') srcp++; + } + else + { + if (srcp[1]!=0) srcp+=2; + else break; + } + } + *dstp=0; + + fputs (copy, LogFile); + delete [] copy; + fflush (LogFile); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FConsoleBuffer::WriteContentToLog(FILE *LogFile) +{ + if (LogFile != NULL) + { + for (unsigned i = 0; i < mConsoleText.Size(); i++) + { + WriteLineToLog(LogFile, mConsoleText[i]); + } + } +} + +//========================================================================== +// +// ensures that the following text is not appended to the current line. +// +//========================================================================== + +void FConsoleBuffer::Linefeed(FILE *Logfile) +{ + if (mAddType != NEWLINE && Logfile != NULL) fputc('\n', Logfile); + mAddType = NEWLINE; +} + +//========================================================================== +// +// +// +//========================================================================== + +static const char bar1[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" + "\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_TAN "\n"; +static const char bar2[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" + "\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_GREEN "\n"; +static const char bar3[] = TEXTCOLOR_RED "\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" + "\36\36\36\36\36\36\36\36\36\36\36\36\37" TEXTCOLOR_NORMAL "\n"; +static const char logbar[] = "\n<------------------------------->\n"; + +void FConsoleBuffer::AddMidText(const char *string, bool bold, FILE *Logfile) +{ + Linefeed(Logfile); + AddText (-1, bold? bar2 : bar1, Logfile); + AddText (-1, string, Logfile); + Linefeed(Logfile); + AddText(-1, bar3, Logfile); +} + +//========================================================================== +// +// Format the text for output +// +//========================================================================== + +void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth) +{ + if (formatfont != mLastFont || displaywidth != mLastDisplayWidth || mBufferWasCleared) + { + FreeBrokenText(); + mBrokenConsoleText.Clear(); + mBrokenStart.Clear(); + mBrokenStart.Push(0); + mBrokenLines.Clear(); + mLastFont = formatfont; + mLastDisplayWidth = displaywidth; + mBufferWasCleared = false; + } + unsigned brokensize = mBrokenConsoleText.Size(); + if (brokensize == mConsoleText.Size()) + { + // The last line got text appended. We have to wait until here to format it because + // it is possible that during display new text will be added from the NetUpdate calls in the software version of DrawTextureV. + if (mLastLineNeedsUpdate) + { + brokensize--; + V_FreeBrokenLines(mBrokenConsoleText[brokensize]); + mBrokenConsoleText.Resize(brokensize); + } + } + mBrokenLines.Resize(mBrokenStart[brokensize]); + mBrokenStart.Resize(brokensize); + for (unsigned i = brokensize; i < mConsoleText.Size(); i++) + { + FBrokenLines *bl = V_BreakLines(formatfont, displaywidth, mConsoleText[i], true); + mBrokenConsoleText.Push(bl); + mBrokenStart.Push(mBrokenLines.Size()); + while (bl->Width != -1) + { + mBrokenLines.Push(bl); + bl++; + } + } + mTextLines = mBrokenLines.Size(); + mBrokenStart.Push(mTextLines); + mLastLineNeedsUpdate = false; +} + +//========================================================================== +// +// Delete old content if number of lines gets too large +// +//========================================================================== + +void FConsoleBuffer::ResizeBuffer(unsigned newsize) +{ + if (mConsoleText.Size() > newsize) + { + unsigned todelete = mConsoleText.Size() - newsize; + mConsoleText.Delete(0, todelete); + mBufferWasCleared = true; + } +} + diff --git a/src/c_consolebuffer.h b/src/c_consolebuffer.h new file mode 100644 index 000000000..710423012 --- /dev/null +++ b/src/c_consolebuffer.h @@ -0,0 +1,85 @@ +/* +** consolebuffer.h +** +** manages the text for the console +** +**--------------------------------------------------------------------------- +** Copyright 2014 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include "zstring.h" +#include "tarray.h" +#include "v_text.h" + +enum EAddType +{ + NEWLINE, + APPENDLINE, + REPLACELINE +}; + +class FConsoleBuffer +{ + TArray mConsoleText; + TArray mBrokenConsoleText; // This holds the structures returned by V_BreakLines and is used for memory management. + TArray mBrokenStart; + TArray mBrokenLines; // This holds the single lines, indexed by mBrokenStart and is used for printing. + FILE * mLogFile; + EAddType mAddType; + int mTextLines; + bool mBufferWasCleared; + + FFont *mLastFont; + int mLastDisplayWidth; + bool mLastLineNeedsUpdate; + + void WriteLineToLog(FILE *LogFile, const char *outline); + void FreeBrokenText(unsigned int start = 0, unsigned int end = INT_MAX); + + void Linefeed(FILE *Logfile); + +public: + FConsoleBuffer(); + ~FConsoleBuffer(); + void AddText(int printlevel, const char *string, FILE *logfile = NULL); + void AddMidText(const char *string, bool bold, FILE *logfile); + void FormatText(FFont *formatfont, int displaywidth); + void ResizeBuffer(unsigned newsize); + void WriteContentToLog(FILE *logfile); + void Clear() + { + mBufferWasCleared = true; + mConsoleText.Clear(); + } + int GetFormattedLineCount() { return mTextLines; } + FBrokenLines **GetLines() { return &mBrokenLines[0]; } +}; + diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index f3ceec17d..210f0f3de 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -125,12 +125,10 @@ void FNodeBuilder::BuildTree () { fixed_t bbox[4]; - C_InitTicker ("Building BSP", FRACUNIT); HackSeg = DWORD_MAX; HackMate = DWORD_MAX; CreateNode (0, Segs.Size(), bbox); CreateSubsectorsForReal (); - C_InitTicker (NULL, 0); } int FNodeBuilder::CreateNode (DWORD set, unsigned int count, fixed_t bbox[4]) @@ -199,10 +197,6 @@ int FNodeBuilder::CreateSubsector (DWORD set, fixed_t bbox[4]) } SegsStuffed += count; - if ((SegsStuffed & ~127) != ((SegsStuffed - count) & ~127)) - { - C_SetTicker (MulScale16 (SegsStuffed, (SDWORD)Segs.Size())); - } D(Printf (PRINT_LOG, "bbox (%d,%d)-(%d,%d)\n", bbox[BOXLEFT]>>16, bbox[BOXBOTTOM]>>16, bbox[BOXRIGHT]>>16, bbox[BOXTOP]>>16)); diff --git a/src/v_text.cpp b/src/v_text.cpp index c5208be36..64b95c041 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -336,7 +336,7 @@ static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const B line->Width = font->StringWidth (line->Text); } -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) +FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor) { FBrokenLines lines[128]; // Support up to 128 lines (should be plenty) @@ -397,7 +397,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) space = string - 1; breakit (&lines[i], font, start, space, linecolor); - if (c == '\n') + if (c == '\n' && !preservecolor) { lastcolor = ""; // Why, oh why, did I do it like this? } diff --git a/src/v_text.h b/src/v_text.h index 29dfa627b..f1426b30a 100644 --- a/src/v_text.h +++ b/src/v_text.h @@ -75,9 +75,9 @@ struct FBrokenLines #define TEXTCOLOR_CHAT "\034*" #define TEXTCOLOR_TEAMCHAT "\034!" -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str); +FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false); void V_FreeBrokenLines (FBrokenLines *lines); -inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str) - { return V_BreakLines (font, maxwidth, (const BYTE *)str); } +inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false) + { return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor); } #endif //__V_TEXT_H__ From b285cbebe4fb7f3a84240eabeb4276761565567b Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sun, 25 May 2014 01:12:16 +0200 Subject: [PATCH 224/311] - Fixed compiler errors in latest TEXTURES code. --- src/r_data/sprites.cpp | 4 ++-- src/r_utility.cpp | 2 +- src/textures/animations.cpp | 4 ++-- src/textures/jpegtexture.cpp | 4 ++-- src/textures/multipatchtexture.cpp | 14 +++++++------- src/textures/texturemanager.cpp | 2 +- src/w_wad.h | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 604619403..c1e59c415 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -63,7 +63,7 @@ static bool R_InstallSpriteLump (FTextureID lump, unsigned frame, char rot, bool if (frame >= MAX_SPRITE_FRAMES || rotation > 16) { - Printf (TEXTCOLOR_RED"R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan[lump]->Name); + Printf (TEXTCOLOR_RED"R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan[lump]->Name.GetChars()); return false; } @@ -998,4 +998,4 @@ void R_DeinitSpriteData() delete[] skins; skins = NULL; } -} \ No newline at end of file +} diff --git a/src/r_utility.cpp b/src/r_utility.cpp index e11631700..5bf38ad26 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -972,7 +972,7 @@ void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, int fov) texture = static_cast(TexMan[picnum]); if (!texture->bHasCanvas) { - Printf ("%s is not a valid target for a camera\n", texture->Name); + Printf ("%s is not a valid target for a camera\n", texture->Name.GetChars()); return; } diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 3601646a0..58ef7a5ca 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -231,8 +231,8 @@ void FTextureManager::InitAnimated (void) if (debuganimated) { Printf("Defining animation '%s' (texture %d, lump %d, file %d) to '%s' (texture %d, lump %d, file %d)\n", - tex1->Name, pic1.GetIndex(), tex1->GetSourceLump(), Wads.GetLumpFile(tex1->GetSourceLump()), - tex2->Name, pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump())); + tex1->Name.GetChars(), pic1.GetIndex(), tex1->GetSourceLump(), Wads.GetLumpFile(tex1->GetSourceLump()), + tex2->Name.GetChars(), pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump())); } if (pic1 == pic2) diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index 3a87f70af..849cec645 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -448,7 +448,7 @@ void FJPEGTexture::MakeTexture () } catch (int) { - Printf (TEXTCOLOR_ORANGE " in texture %s\n", Name); + Printf (TEXTCOLOR_ORANGE " in texture %s\n", Name.GetChars()); jpeg_destroy_decompress(&cinfo); } if (buff != NULL) @@ -532,7 +532,7 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC } catch(int) { - Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name); + Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name.GetChars()); } jpeg_destroy_decompress(&cinfo); if (buff != NULL) delete [] buff; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 84e7385db..348ad3a98 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -268,14 +268,14 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) { I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", - maxpatchnum, Name, LittleShort(mpatch.d->patch)+1); + maxpatchnum, Name.GetChars(), LittleShort(mpatch.d->patch)+1); } Parts[i].OriginX = LittleShort(mpatch.d->originx); Parts[i].OriginY = LittleShort(mpatch.d->originy); Parts[i].Texture = patchlookup[LittleShort(mpatch.d->patch)].Texture; if (Parts[i].Texture == NULL) { - Printf(TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name, Name); + Printf(TEXTCOLOR_RED "Unknown patch %s in texture %s\n", patchlookup[LittleShort(mpatch.d->patch)].Name.GetChars(), Name.GetChars()); NumParts--; i--; } @@ -290,7 +290,7 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl } if (NumParts == 0) { - Printf ("Texture %s is left without any patches\n", Name); + Printf ("Texture %s is left without any patches\n", Name.GetChars()); } CheckForHacks (); @@ -1023,7 +1023,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, i } if (part.Texture == NULL) { - if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name); + if (!silent) Printf(TEXTCOLOR_RED "Unknown patch '%s' in texture '%s'\n", sc.String, Name.GetChars()); } sc.MustGetStringName(","); sc.MustGetNumber(); @@ -1244,13 +1244,13 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) { sc.MustGetFloat(); xScale = FLOAT2FIXED(sc.Float); - if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); + if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name.GetChars()); } else if (sc.Compare("YScale")) { sc.MustGetFloat(); yScale = FLOAT2FIXED(sc.Float); - if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); + if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name.GetChars()); } else if (sc.Compare("WorldPanning")) { @@ -1318,7 +1318,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) if (Width <= 0 || Height <= 0) { UseType = FTexture::TEX_Null; - Printf("Texture %s has invalid dimensions (%d, %d)\n", Name, Width, Height); + Printf("Texture %s has invalid dimensions (%d, %d)\n", Name.GetChars(), Width, Height); Width = Height = 1; } CalcBitSize (); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 2a10ce0df..a79769c3d 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -949,7 +949,7 @@ void FTextureManager::SortTexturesByType(int start, int end) { if (newtextures[j] != NULL) { - Printf("Texture %s has unknown type!\n", newtextures[j]->Name); + Printf("Texture %s has unknown type!\n", newtextures[j]->Name.GetChars()); AddTexture(newtextures[j]); } } diff --git a/src/w_wad.h b/src/w_wad.h index 0a95699f6..4dfe3434d 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -196,8 +196,8 @@ public: int GetLumpOffset (int lump); // [RH] Returns offset of lump in the wadfile int GetLumpFlags (int lump); // Return the flags for this lump void GetLumpName (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy - void FWadCollection::GetLumpName(FString &to, int lump) const; - const char *GetLumpFullName(int lump) const; // [RH] Returns the lump's full name + void GetLumpName (FString &to, int lump) const; + const char *GetLumpFullName (int lump) const; // [RH] Returns the lump's full name FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to From 72bbb19cc7b313c03a77c5edb3a1c689469f5d5c Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sun, 25 May 2014 10:11:09 +0200 Subject: [PATCH 225/311] - Shut up GCC aggressive optimizer warnings. From what I can see, GCC would miscompile the involved loops, because the index variable is 'signed int' and the multiplication with an unsigned would cause signed overflow (undefined behavior). Change the index variable type to 'unsigned int' to expect unsigned overflow (conformant to standard). --- src/g_heretic/a_hereticmisc.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 2 +- src/g_heretic/a_ironlich.cpp | 2 +- src/g_hexen/a_iceguy.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index 83200068b..279635482 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) { - int i; + unsigned int i; AActor *tiny; angle_t angle; diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 23ecf1ae5..17c9621d5 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -797,7 +797,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1) DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers) { - int i; + unsigned int i; angle_t angle; AActor *ripper; diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 5801e6cac..d8c1fd285 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -171,7 +171,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek) DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact) { - int i; + unsigned int i; angle_t angle; AActor *shard; diff --git a/src/g_hexen/a_iceguy.cpp b/src/g_hexen/a_iceguy.cpp index 2d908f974..9d8360d4d 100644 --- a/src/g_hexen/a_iceguy.cpp +++ b/src/g_hexen/a_iceguy.cpp @@ -125,7 +125,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie) DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode) { AActor *mo; - int i; + unsigned int i; for (i = 0; i < 8; i++) { From 75cde0b2219fdd798eaa30e1d41ce33dd696b9f6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 29 May 2014 17:30:01 +0200 Subject: [PATCH 226/311] - allow locks to check for a key's species so that newly defined keys can open previously defined locks without the need to redefine them. --- src/g_shared/a_keys.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/g_shared/a_keys.cpp b/src/g_shared/a_keys.cpp index e7f1b286b..67d0ffb10 100644 --- a/src/g_shared/a_keys.cpp +++ b/src/g_shared/a_keys.cpp @@ -19,12 +19,29 @@ struct OneKey bool check(AActor * owner) { - // P_GetMapColorForKey() checks the key directly - if (owner->IsKindOf (RUNTIME_CLASS(AKey))) + if (owner->IsKindOf(RUNTIME_CLASS(AKey))) + { + // P_GetMapColorForKey() checks the key directly return owner->IsA(key); - // Other calls check an actor that may have a key in its inventory. - else - return !!owner->FindInventory(key); + } + else + { + // Other calls check an actor that may have a key in its inventory. + AInventory *item; + + for (item = owner->Inventory; item != NULL; item = item->Inventory) + { + if (item->IsA(key)) + { + return true; + } + else if (item->GetSpecies() == key->TypeName) + { + return true; + } + } + return false; + } } }; From 8f5683e23d61825e77b2c7b68312a01cf4354d61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 29 May 2014 17:50:14 +0200 Subject: [PATCH 227/311] - moved secret found message to string table and removed the CVAR crutch that dates from a time when modifying string table content wasn't as easy as it is now. - added 'showsecretsector' CVAR to show the sector number with the secret found message. --- src/g_shared/a_pickups.cpp | 2 +- src/g_shared/a_secrettrigger.cpp | 4 +--- src/p_spec.cpp | 21 +++++++++++++++------ src/p_spec.h | 2 +- wadsrc/static/language.enu | 2 ++ 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index cc559ea94..f14e7f4c7 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1018,7 +1018,7 @@ void AInventory::Touch (AActor *toucher) if (flags5 & MF5_COUNTSECRET) { - P_GiveSecret(toucher, true, true); + P_GiveSecret(toucher, true, true, -1); } //Added by MC: Check if item taken was the roam destination of any bot diff --git a/src/g_shared/a_secrettrigger.cpp b/src/g_shared/a_secrettrigger.cpp index 4484340db..24c6f0db4 100644 --- a/src/g_shared/a_secrettrigger.cpp +++ b/src/g_shared/a_secrettrigger.cpp @@ -42,8 +42,6 @@ #include "v_font.h" #include "p_spec.h" -EXTERN_CVAR(String, secretmessage) - class ASecretTrigger : public AActor { DECLARE_CLASS (ASecretTrigger, AActor) @@ -62,7 +60,7 @@ void ASecretTrigger::PostBeginPlay () void ASecretTrigger::Activate (AActor *activator) { - P_GiveSecret(activator, args[0] <= 1, (args[0] == 0 || args[0] == 2)); + P_GiveSecret(activator, args[0] <= 1, (args[0] == 0 || args[0] == 2), -1); Destroy (); } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 63f7c1c89..e66dc2ab4 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -61,6 +61,7 @@ #include "a_sharedglobal.h" #include "farchive.h" #include "a_keys.h" +#include "c_dispatch.h" // State. #include "r_state.h" @@ -73,9 +74,6 @@ static FRandom pr_playerinspecialsector ("PlayerInSpecialSector"); void P_SetupPortals(); -// [GrafZahl] Make this message changable by the user! ;) -CVAR(String, secretmessage, "A Secret is revealed!", CVAR_ARCHIVE) - IMPLEMENT_POINTY_CLASS (DScroller) DECLARE_POINTER (m_Interpolations[0]) DECLARE_POINTER (m_Interpolations[1]) @@ -581,7 +579,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) if (sector->special & SECRET_MASK) { sector->special &= ~SECRET_MASK; - P_GiveSecret(player->mo, true, true); + P_GiveSecret(player->mo, true, true, int(sector - sectors)); } } @@ -672,7 +670,9 @@ void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, // //============================================================================ -void P_GiveSecret(AActor *actor, bool printmessage, bool playsound) +CVAR(Bool, showsecretsector, false, 0) + +void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum) { if (actor != NULL) { @@ -682,7 +682,16 @@ void P_GiveSecret(AActor *actor, bool printmessage, bool playsound) } if (actor->CheckLocalView (consoleplayer)) { - if (printmessage) C_MidPrint (SmallFont, secretmessage); + if (printmessage) + { + if (!showsecretsector || sectornum < 0) C_MidPrint(SmallFont, GStrings["SECRETMESSAGE"]); + else + { + FString s = GStrings["SECRETMESSAGE"]; + s.AppendFormat(" (Sector %d)", sectornum); + C_MidPrint(SmallFont, s); + } + } if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM); } } diff --git a/src/p_spec.h b/src/p_spec.h index f8dad701b..245c699d7 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -172,7 +172,7 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags); void P_SetSectorFriction (int tag, int amount, bool alterFlag); -void P_GiveSecret(AActor *actor, bool printmessage, bool playsound); +void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); // // getSide() diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 5695ad502..76ba7c0d7 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2,6 +2,8 @@ [enu default] +SECRETMESSAGE = "A secret is revealed!"; + D_DEVSTR = "Useless mode ON.\n"; D_CDROM = "CD-ROM Version: zdoom.ini from c:\\zdoomdat\n"; PRESSKEY = "press a key."; From 98c25deec19039f61d3ea11e510e4628334c7da5 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 31 May 2014 16:29:28 +0300 Subject: [PATCH 228/311] Fix LZMA compilation on GCC with position-independent code (PIC) generation enabled EBX register is used Global Offset Table in PIC http://www.greyhat.ch/lab/downloads/pic.html --- lzma/C/CpuArch.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c index 4b319fa88..925edbeb8 100644 --- a/lzma/C/CpuArch.c +++ b/lzma/C/CpuArch.c @@ -74,8 +74,24 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) *c = c2; *d = d2; + #elif __PIC__ + + /* GCC or Clang WITH position-independent code generation */ + + __asm__ __volatile__ ( + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + : "=a" (*a) , + "=r" (*b) , + "=c" (*c) , + "=d" (*d) + : "0" (function)) ; + #else + /* GCC or Clang WITHOUT position-independent code generation */ + __asm__ __volatile__ ( "cpuid" : "=a" (*a) , From e8513a64edf92bb767560b2239c8f91a80ba802e Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 1 Jun 2014 15:29:22 +1200 Subject: [PATCH 229/311] Rebuild nodes for hellfact map04 --- wadsrc/static/compatibility.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index e2516a30d..1c2307ec0 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -332,7 +332,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 setactivation 455 16 // SPAC_Push } - +8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad { rebuildnodes From 3817bed0b3dcbc1dd85f6c1c745e5de9ba0b0759 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 1 Jun 2014 18:11:50 +1200 Subject: [PATCH 230/311] Weap scroll could sometimes miss sameslot weapons In rear cases, when using next/prevweap, defined weapons in the same slot couldn't cycle when looping to another when you only had weapons in 1 slot. --- src/g_shared/a_weapons.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 6caf42b7d..fae232557 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -1143,7 +1143,7 @@ AWeapon *FWeaponSlots::PickNextWeapon(player_t *player) return weap; } } - while ((slot != startslot || index != startindex) && slotschecked < NUM_WEAPON_SLOTS); + while ((slot != startslot || index != startindex) && slotschecked <= NUM_WEAPON_SLOTS); } return player->ReadyWeapon; } @@ -1198,7 +1198,7 @@ AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player) return weap; } } - while ((slot != startslot || index != startindex) && slotschecked < NUM_WEAPON_SLOTS); + while ((slot != startslot || index != startindex) && slotschecked <= NUM_WEAPON_SLOTS); } return player->ReadyWeapon; } From 96e4cb90b7e48d40ae07353a34db60318b87b19c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 1 Jun 2014 15:12:41 +0300 Subject: [PATCH 231/311] Fix crash on attempt to save cached OpenGL nodes on OS X Root permissions are required to be able to create directories inside /Library/Application Support So user's ~/Library/Application Support is used to store cached nodes --- src/m_specialpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index b4fcba3c3..e6f74eda6 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -335,7 +335,7 @@ FString M_GetCachePath(bool create) char pathstr[PATH_MAX]; FSRef folder; - if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) && + if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) && noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX)) { path = pathstr; From 9cd074ddf3cf65fd2192320d34b8e5a05357deb6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Jun 2014 10:51:17 +0200 Subject: [PATCH 232/311] - fixed: plane equation vectors must be normalized when being loaded from UDMF. --- src/p_udmf.cpp | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 19dfdf08c..7588199b4 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1246,6 +1246,7 @@ public: int fadecolor = -1; int desaturation = -1; int fplaneflags = 0, cplaneflags = 0; + double fp[4] = { 0 }, cp[4] = { 0 }; memset(sec, 0, sizeof(*sec)); sec->lightlevel = 160; @@ -1449,44 +1450,42 @@ public: case NAME_floorplane_a: fplaneflags |= 1; - sec->floorplane.a = CheckFixed(key); + fp[0] = CheckFloat(key); break; case NAME_floorplane_b: fplaneflags |= 2; - sec->floorplane.b = CheckFixed(key); + fp[1] = CheckFloat(key); break; case NAME_floorplane_c: fplaneflags |= 4; - sec->floorplane.c = CheckFixed(key); - sec->floorplane.ic = FixedDiv(FRACUNIT, sec->floorplane.c); + fp[2] = CheckFloat(key); break; case NAME_floorplane_d: fplaneflags |= 8; - sec->floorplane.d = CheckFixed(key); + fp[3] = CheckFloat(key); break; case NAME_ceilingplane_a: cplaneflags |= 1; - sec->ceilingplane.a = CheckFixed(key); + cp[0] = CheckFloat(key); break; case NAME_ceilingplane_b: cplaneflags |= 2; - sec->ceilingplane.b = CheckFixed(key); + cp[1] = CheckFloat(key); break; case NAME_ceilingplane_c: cplaneflags |= 4; - sec->ceilingplane.c = CheckFixed(key); - sec->ceilingplane.ic = FixedDiv(FRACUNIT, sec->ceilingplane.c); + cp[2] = CheckFloat(key); break; case NAME_ceilingplane_d: cplaneflags |= 8; - sec->ceilingplane.d = CheckFixed(key); + cp[3] = CheckFloat(key); break; default: @@ -1509,6 +1508,17 @@ public: sec->floorplane.c = FRACUNIT; sec->floorplane.ic = FRACUNIT; } + else + { + double ulen = TVector3(fp[0], fp[1], fp[2]).Length(); + + // normalize the vector, it must have a length of 1 + sec->floorplane.a = FLOAT2FIXED(fp[0] / ulen); + sec->floorplane.b = FLOAT2FIXED(fp[1] / ulen); + sec->floorplane.c = FLOAT2FIXED(fp[2] / ulen); + sec->floorplane.d = FLOAT2FIXED(fp[3] / ulen); + sec->floorplane.ic = FLOAT2FIXED(ulen / fp[2]); + } if (cplaneflags != 15) { sec->ceilingplane.a = sec->ceilingplane.b = 0; @@ -1516,6 +1526,17 @@ public: sec->ceilingplane.c = -FRACUNIT; sec->ceilingplane.ic = -FRACUNIT; } + else + { + double ulen = TVector3(cp[0], cp[1], cp[2]).Length(); + + // normalize the vector, it must have a length of 1 + sec->floorplane.a = FLOAT2FIXED(cp[0] / ulen); + sec->floorplane.b = FLOAT2FIXED(cp[1] / ulen); + sec->floorplane.c = FLOAT2FIXED(cp[2] / ulen); + sec->floorplane.d = FLOAT2FIXED(cp[3] / ulen); + sec->floorplane.ic = FLOAT2FIXED(ulen / cp[2]); + } if (lightcolor == -1 && fadecolor == -1 && desaturation == -1) { From 3e7b0c29165114d543669bb00793920412f37c08 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 2 Jun 2014 10:44:29 +0300 Subject: [PATCH 233/311] Fix crash when GL nodes file cannot be opened for writing Report errors to console if nodes file cannot be opened or written --- src/p_glnodes.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index a8fa04c34..e59f3859a 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1168,8 +1168,21 @@ static void CreateCachedNodes(MapData *map) FString path = CreateCacheName(map, true); FILE *f = fopen(path, "wb"); - fwrite(compressed, 1, outlen+offset, f); - fclose(f); + + if (f != NULL) + { + if (fwrite(compressed, outlen+offset, 1, f) != 1) + { + Printf("Error saving nodes to file %s\n", path.GetChars()); + } + + fclose(f); + } + else + { + Printf("Cannot open nodes file %s for writing\n", path.GetChars()); + } + delete [] compressed; } From 20adcecb1d480724ebccc9448d2bef562c3ba59f Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 2 Jun 2014 11:37:40 +0300 Subject: [PATCH 234/311] Remove redundant saving of GL nodes if they were loaded from cache --- src/p_glnodes.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index e59f3859a..899005ffa 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -959,6 +959,7 @@ bool P_LoadGLNodes(MapData * map) bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) { bool ret = false; + bool loaded = false; // If the map loading code has performed a node rebuild we don't need to check for it again. if (!rebuilt && !P_CheckForGLNodes()) @@ -978,7 +979,8 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) numsegs = 0; // Try to load GL nodes (cached or GWA) - if (!P_LoadGLNodes(map)) + loaded = P_LoadGLNodes(map); + if (!loaded) { // none found - we have to build new ones! unsigned int startTime, endTime; @@ -1006,20 +1008,22 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) } } + if (!loaded) + { #ifdef DEBUG - // Building nodes in debug is much slower so let's cache them only if cachetime is 0 - buildtime = 0; + // Building nodes in debug is much slower so let's cache them only if cachetime is 0 + buildtime = 0; #endif - if (gl_cachenodes && buildtime/1000.f >= gl_cachetime) - { - DPrintf("Caching nodes\n"); - CreateCachedNodes(map); + if (gl_cachenodes && buildtime/1000.f >= gl_cachetime) + { + DPrintf("Caching nodes\n"); + CreateCachedNodes(map); + } + else + { + DPrintf("Not caching nodes (time = %f)\n", buildtime/1000.f); + } } - else - { - DPrintf("Not caching nodes (time = %f)\n", buildtime/1000.f); - } - if (!gamenodes) { From 842ef86e73efc3819b61289db0cba5e6c66ff364 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 9 Jun 2014 19:51:32 +1200 Subject: [PATCH 235/311] Don't reset the inventory of dead players --- src/g_game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 65fa5733d..b84ac890d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1307,7 +1307,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags) } // Clears the entire inventory and gives back the defaults for starting a game - if (flags & CHANGELEVEL_RESETINVENTORY) + if ((flags & CHANGELEVEL_RESETINVENTORY) && p->playerstate != PST_DEAD) { p->mo->ClearInventory(); p->mo->GiveDefaultInventory(); From 67c6690689b98b36bffecf557dffe9dca875a810 Mon Sep 17 00:00:00 2001 From: WChrisK Date: Wed, 11 Jun 2014 23:30:25 -0400 Subject: [PATCH 236/311] Added a check that doesn't print empty obituary strings, as wad's that hide obituary strings in multiplayer games end up spamming a lot of empty lines. --- src/p_interaction.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 4be8ed627..0eae78632 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -320,6 +320,10 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf message = GStrings("OB_DEFAULT"); } + // [CK] Don't display empty strings + if (message == NULL || strlen(message) <= 0) + return; + SexMessage (message, gendermessage, gender, self->player->userinfo.GetName(), attacker->player->userinfo.GetName()); Printf (PRINT_MEDIUM, "%s\n", gendermessage); From 2838c4b25bab4ee375e282e0f7e6aa137f1008bd Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 16 Jun 2014 03:19:05 +1200 Subject: [PATCH 237/311] Prediction was rebuilding too much thinglist data - Stopped player prediction from rebuilding more sector list data then the player originally had. --- src/p_local.h | 1 + src/p_user.cpp | 57 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index e7fb2cb7d..58d9d02e5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -500,6 +500,7 @@ void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, void P_DelSector_List(); void P_DelSeclist(msecnode_t *); // phares 3/16/98 +msecnode_t* P_DelSecnode(msecnode_t *); void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 int P_GetFriction(const AActor *mo, int *frictionfactor); diff --git a/src/p_user.cpp b/src/p_user.cpp index ea7b315d8..cd111838d 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2742,25 +2742,11 @@ void P_UnPredictPlayer () act->UnlinkFromWorld(); memcpy(&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x - (BYTE *)act)); - // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist(sector_list); - sector_list = NULL; - for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) - { - sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); - } - - // The blockmap ordering needs to remain unchanged, too. Right now, act has the right - // pointers, so temporarily set its MF_NOBLOCKMAP flag so that LinkToWorld() does not - // mess with them. - { - DWORD keepflags = act->flags; - act->flags |= MF_NOBLOCKMAP; - act->LinkToWorld(); - act->flags = keepflags; - } - - // Restore sector links. + // The blockmap ordering needs to remain unchanged, too. + // Restore sector links and refrences. + // [ED850] This is somewhat of a duplicate of LinkToWorld(), but we need to keep every thing the same, + // otherwise we end up fixing bugs in blockmap logic (i.e undefined behaviour with polyobject collisions), + // which we really don't want to do here. if (!(act->flags & MF_NOSECTOR)) { sector_t *sec = act->Sector; @@ -2781,6 +2767,39 @@ void P_UnPredictPlayer () *link = me; } + // Destroy old refrences + msecnode_t *node = sector_list; + while (node) + { + node->m_thing = NULL; + node = node->m_tnext; + } + + // Make the sector_list match the player's touching_sectorlist before it got predicted. + P_DelSeclist(sector_list); + sector_list = NULL; + for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) + { + sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); + } + act->touching_sectorlist = sector_list; // Attach to thing + sector_list = NULL; // clear for next time + + node = sector_list; + while (node) + { + if (node->m_thing == NULL) + { + if (node == sector_list) + sector_list = node->m_tnext; + node = P_DelSecnode(node); + } + else + { + node = node->m_tnext; + } + } + msecnode_t *snode; // Restore sector thinglist order From a3a7ee569f97499df524ba17ad33552daf4cb432 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 17 Jun 2014 19:23:34 +1200 Subject: [PATCH 238/311] Multi-intermission waits for all players + changes - Added a segment of code that now makes the intermission wait for all players before advancing, instead of continuing on any player. A "ready icon" shows to reflect this. - The Deathmatch intermisson couldn't show the ready icon (because it just used the ingame scoreboard), so a proper intermission was added, which reflects the same design as the coop scoreboard. - The colour column wasted more space then it should have needed, so it was replaced with player colour backgrounds. - Slight y offset adjustments to make everything fit in 320x200 properly. --- src/hu_scores.cpp | 14 +- src/hu_stuff.h | 5 + src/wi_stuff.cpp | 375 ++++++++++++++++------------ wadsrc/static/graphics/readyico.png | Bin 0 -> 259 bytes wadsrc/static/language.enu | 2 + 5 files changed, 234 insertions(+), 162 deletions(-) create mode 100644 wadsrc/static/graphics/readyico.png diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index afbb7a35d..af5d1bbaa 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -82,9 +82,7 @@ CVAR (Int, sb_deathmatch_otherplayercolor, CR_GREY, CVAR_ARCHIVE) CVAR (Bool, sb_teamdeathmatch_enable, true, CVAR_ARCHIVE) CVAR (Int, sb_teamdeathmatch_headingcolor, CR_RED, CVAR_ARCHIVE) -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static int STACK_ARGS comparepoints (const void *arg1, const void *arg2) +int STACK_ARGS comparepoints (const void *arg1, const void *arg2) { // Compare first be frags/kills, then by name. player_t *p1 = *(player_t **)arg1; @@ -99,7 +97,7 @@ static int STACK_ARGS comparepoints (const void *arg1, const void *arg2) return diff; } -static int STACK_ARGS compareteams (const void *arg1, const void *arg2) +int STACK_ARGS compareteams (const void *arg1, const void *arg2) { // Compare first by teams, then by frags, then by name. player_t *p1 = *(player_t **)arg1; @@ -118,6 +116,8 @@ static int STACK_ARGS compareteams (const void *arg1, const void *arg2) return diff; } +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + // CODE -------------------------------------------------------------------- //========================================================================== @@ -247,7 +247,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER lineheight = MAX(height, maxiconheight * CleanYfac); ypadding = (lineheight - height + 1) / 2; - bottom = gamestate != GS_INTERMISSION ? ST_Y : SCREENHEIGHT; + bottom = ST_Y; y = MAX(48*CleanYfac, (bottom - MAXPLAYERS * (height + CleanYfac + 1)) / 2); HU_DrawTimeRemaining (bottom - height); @@ -255,10 +255,6 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER if (teamplay && deathmatch) { y -= (BigFont->GetHeight() + 8) * CleanYfac; - if (gamestate == GS_INTERMISSION) - { - y = MAX(BigFont->GetHeight() * 4, y); - } for (i = 0; i < Teams.Size (); i++) { diff --git a/src/hu_stuff.h b/src/hu_stuff.h index c8e76fee0..e2cc75918 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -50,4 +50,9 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh void HU_DrawColorBar(int x, int y, int height, int playernum); int HU_GetRowColor(player_t *player, bool hightlight); +// Sorting routines + +int comparepoints(const void *arg1, const void *arg2); +int compareteams(const void *arg1, const void *arg2); + #endif diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 982668566..477de8f3e 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -45,6 +45,7 @@ #include "v_text.h" #include "gi.h" #include "d_player.h" +#include "d_netinf.h" #include "b_bot.h" #include "textures/textures.h" #include "r_data/r_translate.h" @@ -190,6 +191,7 @@ static TArray anims; #define SHOWNEXTLOCDELAY 4 // in seconds static int acceleratestage; // used to accelerate or skip a stage +static bool playerready[MAXPLAYERS]; static int me; // wbs->pnum static stateenum_t state; // specifies current state static wbstartstruct_t *wbs; // contains information passed into intermission @@ -199,11 +201,17 @@ static int bcnt; // used for timing of background animation static int cnt_kills[MAXPLAYERS]; static int cnt_items[MAXPLAYERS]; static int cnt_secret[MAXPLAYERS]; +static int cnt_frags[MAXPLAYERS]; +static int cnt_deaths[MAXPLAYERS]; static int cnt_time; static int cnt_total_time; static int cnt_par; static int cnt_pause; +static int total_frags; +static int total_deaths; static bool noautostartmap; +static int dofrags; +static int ng_state; // // GRAPHICS @@ -1208,128 +1216,133 @@ int WI_fragSum (int playernum) return frags; } -static int dm_state; -static int dm_frags[MAXPLAYERS][MAXPLAYERS]; -static int dm_totals[MAXPLAYERS]; +static int player_deaths[MAXPLAYERS]; void WI_initDeathmatchStats (void) { - int i, j; state = StatCount; acceleratestage = 0; - dm_state = 1; + memset(playerready, 0, sizeof(playerready)); + memset(cnt_frags, 0, sizeof(cnt_frags)); + memset(cnt_deaths, 0, sizeof(cnt_frags)); + memset(player_deaths, 0, sizeof(player_deaths)); + total_frags = 0; + total_deaths = 0; + ng_state = 1; cnt_pause = TICRATE; for (i=0 ; i 99) - dm_frags[i][j] = 99; + cnt_frags[i] += 2; - if (dm_frags[i][j] < -99) - dm_frags[i][j] = -99; - - stillticking = true; - } - } - dm_totals[i] = WI_fragSum(i); + if (cnt_frags[i] > plrs[i].fragcount) + cnt_frags[i] = plrs[i].fragcount; + else + stillticking = true; + } - if (dm_totals[i] > 99) - dm_totals[i] = 99; - - if (dm_totals[i] < -99) - dm_totals[i] = -99; - } - + if (!stillticking) + { + S_Sound(CHAN_VOICE | CHAN_UI, "intermission/nextstage", 1, ATTN_NONE); + ng_state++; + } + } + else if (ng_state == 4) + { + if (!(bcnt & 3)) + S_Sound(CHAN_VOICE | CHAN_UI, "intermission/tick", 1, ATTN_NONE); + + stillticking = false; + + for (i = 0; i player_deaths[i]) + cnt_deaths[i] = player_deaths[i]; + else + stillticking = true; } if (!stillticking) { - S_Sound (CHAN_VOICE | CHAN_UI, "intermission/nextstage", 1, ATTN_NONE); - dm_state++; + S_Sound(CHAN_VOICE | CHAN_UI, "intermission/nextstage", 1, ATTN_NONE); + ng_state++; } - */ - dm_state = 3; } - else if (dm_state == 4) + else if (ng_state == 6) { - if (acceleratestage) + int i; + for (i = 0; i < MAXPLAYERS; i++) { - S_Sound (CHAN_VOICE | CHAN_UI, "intermission/pastdmstats", 1, ATTN_NONE); + // If the player is in the game and not ready, stop checking + if (playeringame[i] && !players[i].isbot && !playerready[i]) + break; + } + + // All players are ready; proceed. + if (i == MAXPLAYERS && acceleratestage) + { + S_Sound(CHAN_VOICE | CHAN_UI, "intermission/pastdmstats", 1, ATTN_NONE); WI_initShowNextLoc(); } } - else if (dm_state & 1) + else if (ng_state & 1) { if (!--cnt_pause) { - dm_state++; + ng_state++; cnt_pause = TICRATE; } } @@ -1339,97 +1352,126 @@ void WI_updateDeathmatchStats () void WI_drawDeathmatchStats () { + int i, pnum, x, y, ypadding, height, lineheight; + int maxnamewidth, maxscorewidth, maxiconheight; + int pwidth = IntermissionFont->GetCharWidth('%'); + int icon_x, name_x, frags_x, deaths_x; + int deaths_len; + float h, s, v, r, g, b; + EColorRange color; + const char *text_deaths, *text_frags; + FTexture *readyico = TexMan.FindTexture("READYICO"); + player_t *sortedplayers[MAXPLAYERS]; // draw animated background - WI_drawBackground(); - WI_drawLF(); + WI_drawBackground(); - // [RH] Draw heads-up scores display - HU_DrawScores (&players[me]); + y = WI_drawLF(); -/* - int i; - int j; - int x; - int y; - int w; - - int lh; // line height + HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight); + // Use the readyico height if it's bigger. + height = readyico->GetScaledHeight() - readyico->GetScaledTopOffset(); + maxiconheight = MAX(height, maxiconheight); + height = SmallFont->GetHeight() * CleanYfac; + lineheight = MAX(height, maxiconheight * CleanYfac); + ypadding = (lineheight - height + 1) / 2; + y += CleanYfac; - lh = WI_SPACINGY; + text_deaths = GStrings("SCORE_DEATHS"); + //text_color = GStrings("SCORE_COLOR"); + text_frags = GStrings("SCORE_FRAGS"); - // draw stat titles (top line) - V_DrawPatchClean(DM_TOTALSX-LittleShort(total->width)/2, - DM_MATRIXY-WI_SPACINGY+10, - &FB, - total); - - V_DrawPatchClean(DM_KILLERSX, DM_KILLERSY, &FB, killers); - V_DrawPatchClean(DM_VICTIMSX, DM_VICTIMSY, &FB, victims); + icon_x = 8 * CleanXfac; + name_x = icon_x + maxscorewidth * CleanXfac; + frags_x = name_x + (maxnamewidth + MAX(SmallFont->StringWidth("XXXXX"), SmallFont->StringWidth(text_frags)) + 8) * CleanXfac; + deaths_x = frags_x + ((deaths_len = SmallFont->StringWidth(text_deaths)) + 8) * CleanXfac; - // draw P? - x = DM_MATRIXX + DM_SPACINGX; - y = DM_MATRIXY; + x = (SCREENWIDTH - deaths_x) >> 1; + icon_x += x; + name_x += x; + frags_x += x; + deaths_x += x; - for (i=0 ; iDrawText(SmallFont, color, name_x, y, GStrings("SCORE_NAME"), DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, frags_x - SmallFont->StringWidth(text_frags)*CleanXfac, y, text_frags, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, deaths_x - deaths_len*CleanXfac, y, text_deaths, DTA_CleanNoMove, true, TAG_DONE); + y += height + 6 * CleanYfac; + + // Sort all players + for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) - { - V_DrawPatchClean(x-LittleShort(p[i]->width)/2, - DM_MATRIXY - WI_SPACINGY, - &FB, - p[i]); - - V_DrawPatchClean(DM_MATRIXX-LittleShort(p[i]->width)/2, - y, - &FB, - p[i]); - - if (i == me) - { - V_DrawPatchClean(x-LittleShort(p[i]->width)/2, - DM_MATRIXY - WI_SPACINGY, - &FB, - bstar); - - V_DrawPatchClean(DM_MATRIXX-LittleShort(p[i]->width)/2, - y, - &FB, - star); - } - } - x += DM_SPACINGX; - y += WI_SPACINGY; + sortedplayers[i] = &players[i]; } - // draw stats - y = DM_MATRIXY+10; - w = LittleShort(num[0]->width); + if (teamplay) + qsort(sortedplayers, MAXPLAYERS, sizeof(player_t *), compareteams); + else + qsort(sortedplayers, MAXPLAYERS, sizeof(player_t *), comparepoints); - for (i=0 ; iDim(MAKERGB(clamp(int(r*255.f), 0, 255), + clamp(int(g*255.f), 0, 255), + clamp(int(b*255.f), 0, 255)), 0.8f, x, y - ypadding, (deaths_x - x) + (8 * CleanXfac), lineheight); + + if (playerready[pnum] || player->isbot) // Bots are automatically assumed ready, to prevent confusion + screen->DrawTexture(readyico, x - (readyico->GetWidth() * CleanXfac), y, DTA_CleanNoMove, true, TAG_DONE); + + color = (EColorRange)HU_GetRowColor(player, pnum == consoleplayer); + if (player->mo->ScoreIcon.isValid()) { - for (j=0 ; jmo->ScoreIcon]; + screen->DrawTexture(pic, icon_x, y, DTA_CleanNoMove, true, TAG_DONE); } - y += WI_SPACINGY; + screen->DrawText(SmallFont, color, name_x, y + ypadding, player->userinfo.GetName(), DTA_CleanNoMove, true, TAG_DONE); + WI_drawNum(SmallFont, frags_x, y + ypadding, cnt_frags[pnum], 0, false, color); + if (ng_state >= 2) + { + WI_drawNum(SmallFont, deaths_x, y + ypadding, cnt_deaths[pnum], 0, false, color); + } + y += lineheight + CleanYfac; } -*/ + + // Draw "TOTAL" line + y += height + 3 * CleanYfac; + color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED; + screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_TOTAL"), DTA_CleanNoMove, true, TAG_DONE); + WI_drawNum(SmallFont, frags_x, y, total_frags, 0, false, color); + if (ng_state >= 4) + { + WI_drawNum(SmallFont, deaths_x, y, total_deaths, 0, false, color); + } + + // Draw game time + y += height + CleanYfac; + + int seconds = plrs[me].stime / TICRATE; + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + FString leveltime = GStrings("SCORE_LVLTIME"); + leveltime += ": "; + + char timer[sizeof "HH:MM:SS"]; + mysnprintf(timer, sizeof(timer), "%02i:%02i:%02i", hours, minutes, seconds); + leveltime += timer; + + screen->DrawText(SmallFont, color, x, y, leveltime, DTA_CleanNoMove, true, TAG_DONE); } -static int cnt_frags[MAXPLAYERS]; -static int dofrags; -static int ng_state; - void WI_initNetgameStats () { @@ -1437,6 +1479,7 @@ void WI_initNetgameStats () state = StatCount; acceleratestage = 0; + memset(playerready, 0, sizeof(playerready)); ng_state = 1; cnt_pause = TICRATE; @@ -1587,7 +1630,16 @@ void WI_updateNetgameStats () } else if (ng_state == 10) { - if (acceleratestage) + int i; + for (i = 0; i < MAXPLAYERS; i++) + { + // If the player is in the game and not ready, stop checking + if (playeringame[i] && !players[i].isbot && !playerready[i]) + break; + } + + // All players are ready; proceed. + if (i == MAXPLAYERS && acceleratestage) { S_Sound (CHAN_VOICE | CHAN_UI, "intermission/pastcoopstats", 1, ATTN_NONE); WI_initShowNextLoc(); @@ -1611,8 +1663,10 @@ void WI_drawNetgameStats () int icon_x, name_x, kills_x, bonus_x, secret_x; int bonus_len, secret_len; int missed_kills, missed_items, missed_secrets; + float h, s, v, r, g, b; EColorRange color; - const char *text_bonus, *text_color, *text_secret, *text_kills; + const char *text_bonus, *text_secret, *text_kills; + FTexture *readyico = TexMan.FindTexture("READYICO"); // draw animated background WI_drawBackground(); @@ -1620,17 +1674,22 @@ void WI_drawNetgameStats () y = WI_drawLF(); HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight); + // Use the readyico height if it's bigger. + height = readyico->GetScaledHeight() - readyico->GetScaledTopOffset(); + if (height > maxiconheight) + { + maxiconheight = height; + } height = SmallFont->GetHeight() * CleanYfac; lineheight = MAX(height, maxiconheight * CleanYfac); ypadding = (lineheight - height + 1) / 2; - y += 16*CleanYfac; + y += CleanYfac; text_bonus = GStrings((gameinfo.gametype & GAME_Raven) ? "SCORE_BONUS" : "SCORE_ITEMS"); - text_color = GStrings("SCORE_COLOR"); text_secret = GStrings("SCORE_SECRET"); text_kills = GStrings("SCORE_KILLS"); - icon_x = (SmallFont->StringWidth(text_color) + 8) * CleanXfac; + icon_x = 8 * CleanXfac; name_x = icon_x + maxscorewidth * CleanXfac; kills_x = name_x + (maxnamewidth + MAX(SmallFont->StringWidth("XXXXX"), SmallFont->StringWidth(text_kills)) + 8) * CleanXfac; bonus_x = kills_x + ((bonus_len = SmallFont->StringWidth(text_bonus)) + 8) * CleanXfac; @@ -1645,7 +1704,6 @@ void WI_drawNetgameStats () color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED; - screen->DrawText(SmallFont, color, x, y, text_color, DTA_CleanNoMove, true, TAG_DONE); screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_NAME"), DTA_CleanNoMove, true, TAG_DONE); screen->DrawText(SmallFont, color, kills_x - SmallFont->StringWidth(text_kills)*CleanXfac, y, text_kills, DTA_CleanNoMove, true, TAG_DONE); screen->DrawText(SmallFont, color, bonus_x - bonus_len*CleanXfac, y, text_bonus, DTA_CleanNoMove, true, TAG_DONE); @@ -1665,7 +1723,17 @@ void WI_drawNetgameStats () continue; player = &players[i]; - HU_DrawColorBar(x, y, lineheight, i); + + D_GetPlayerColor(i, &h, &s, &v, NULL); + HSVtoRGB(&r, &g, &b, h, s, v); + + screen->Dim(MAKERGB(clamp(int(r*255.f), 0, 255), + clamp(int(g*255.f), 0, 255), + clamp(int(b*255.f), 0, 255)), 0.8f, x, y - ypadding, (secret_x - x) + (8 * CleanXfac), lineheight); + + if (playerready[i] || player->isbot) // Bots are automatically assumed ready, to prevent confusion + screen->DrawTexture(readyico, x - (readyico->GetWidth() * CleanXfac), y, DTA_CleanNoMove, true, TAG_DONE); + color = (EColorRange)HU_GetRowColor(player, i == consoleplayer); if (player->mo->ScoreIcon.isValid()) { @@ -1689,7 +1757,7 @@ void WI_drawNetgameStats () } // Draw "MISSED" line - y += 5 * CleanYfac; + y += 3 * CleanYfac; screen->DrawText(SmallFont, CR_DARKGRAY, name_x, y, GStrings("SCORE_MISSED"), DTA_CleanNoMove, true, TAG_DONE); WI_drawPercent(SmallFont, kills_x, y, missed_kills, wbs->maxkills, false, CR_DARKGRAY); if (ng_state >= 4) @@ -1702,7 +1770,7 @@ void WI_drawNetgameStats () } // Draw "TOTAL" line - y += height + 5 * CleanYfac; + y += height + 3 * CleanYfac; color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED; screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_TOTAL"), DTA_CleanNoMove, true, TAG_DONE); WI_drawNum(SmallFont, kills_x, y, wbs->maxkills, 0, false, color); @@ -1939,6 +2007,7 @@ void WI_checkForAccelerate(void) == players[i].oldbuttons) && !player->isbot) { acceleratestage = 1; + playerready[i] = true; } player->oldbuttons = player->cmd.ucmd.buttons; } diff --git a/wadsrc/static/graphics/readyico.png b/wadsrc/static/graphics/readyico.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9b20804bdec28c4ba6ad078b556e53c5e3d543 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDVB6cUq=Rpjs4tz5?O(K&H|6f zVg?4jLm Date: Tue, 17 Jun 2014 20:25:53 +1200 Subject: [PATCH 239/311] Added wi_autoadvance - Prevents an absent player from stopping the intermission --- src/wi_stuff.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 477de8f3e..e60fee303 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -64,6 +64,7 @@ typedef enum CVAR (Bool, wi_percents, true, CVAR_ARCHIVE) CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE) CVAR (Bool, wi_noautostartmap, false, CVAR_USERINFO|CVAR_ARCHIVE) +CVAR (Int, wi_autoadvance, 0, CVAR_SERVERINFO) void WI_loadData (); @@ -1113,6 +1114,7 @@ void WI_updateNoState () else { bool noauto = noautostartmap; + bool autoskip = (wi_autoadvance > 0 && bcnt > (wi_autoadvance * TICRATE)); for (int i = 0; !noauto && i < MAXPLAYERS; ++i) { @@ -1121,7 +1123,7 @@ void WI_updateNoState () noauto |= players[i].userinfo.GetNoAutostartMap(); } } - if (!noauto) + if (!noauto || autoskip) { cnt--; } @@ -1252,10 +1254,11 @@ void WI_updateDeathmatchStats () int i; bool stillticking; + bool autoskip = (wi_autoadvance > 0 && bcnt > (wi_autoadvance * TICRATE)); WI_updateAnimatedBack(); - if (acceleratestage && ng_state != 6) + if ((acceleratestage || autoskip) && ng_state != 6) { acceleratestage = 0; @@ -1332,7 +1335,7 @@ void WI_updateDeathmatchStats () } // All players are ready; proceed. - if (i == MAXPLAYERS && acceleratestage) + if ((i == MAXPLAYERS && acceleratestage) || autoskip) { S_Sound(CHAN_VOICE | CHAN_UI, "intermission/pastdmstats", 1, ATTN_NONE); WI_initShowNextLoc(); @@ -1503,10 +1506,11 @@ void WI_updateNetgameStats () int i; int fsum; bool stillticking; + bool autoskip = (wi_autoadvance > 0 && bcnt > (wi_autoadvance * TICRATE)); WI_updateAnimatedBack (); - if (acceleratestage && ng_state != 10) + if ((acceleratestage || autoskip) && ng_state != 10) { acceleratestage = 0; @@ -1639,7 +1643,7 @@ void WI_updateNetgameStats () } // All players are ready; proceed. - if (i == MAXPLAYERS && acceleratestage) + if ((i == MAXPLAYERS && acceleratestage) || autoskip) { S_Sound (CHAN_VOICE | CHAN_UI, "intermission/pastcoopstats", 1, ATTN_NONE); WI_initShowNextLoc(); From 6164807e97764047ef39699a7602ee9860d4d5c7 Mon Sep 17 00:00:00 2001 From: Shawn Walker Date: Sat, 21 Jun 2014 22:49:42 -0700 Subject: [PATCH 240/311] - fix x64 visual studio linking for common controls --- src/win32/zdoom.exe.manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/zdoom.exe.manifest b/src/win32/zdoom.exe.manifest index e8fb80f97..4aee7a96c 100644 --- a/src/win32/zdoom.exe.manifest +++ b/src/win32/zdoom.exe.manifest @@ -2,7 +2,7 @@ - + \ No newline at end of file From e56e525d0ff9b946031058278013bda688bb60d4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 22 Jun 2014 08:55:21 +0200 Subject: [PATCH 241/311] - A_FireCustomMissile transfer tranlsation flag, code submission by jpalomo --- src/thingdef/thingdef_codeptr.cpp | 17 ++++++++++++++--- wadsrc/static/actors/constants.txt | 4 ++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 43cb34c8d..9055f7b91 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1297,6 +1297,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) // A_FireProjectile // //========================================================================== +enum FP_Flags +{ + FPF_AIMATANGLE = 1, + FPF_TRANSFERTRANSLATION = 2, +}; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { ACTION_PARAM_START(7); @@ -1305,11 +1310,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) ACTION_PARAM_BOOL(UseAmmo, 2); ACTION_PARAM_INT(SpawnOfs_XY, 3); ACTION_PARAM_FIXED(SpawnHeight, 4); - ACTION_PARAM_BOOL(AimAtAngle, 5); + ACTION_PARAM_INT(Flags, 5); ACTION_PARAM_ANGLE(pitch, 6); if (!self->player) return; + player_t *player=self->player; AWeapon * weapon=player->ReadyWeapon; AActor *linetarget; @@ -1327,18 +1333,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) fixed_t z = SpawnHeight; fixed_t shootangle = self->angle; - if (AimAtAngle) shootangle+=Angle; + if (Flags & FPF_AIMATANGLE) shootangle += Angle; // Temporarily adjusts the pitch fixed_t SavedPlayerPitch = self->pitch; self->pitch -= pitch; AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget); self->pitch = SavedPlayerPitch; + if (Flags & FPF_TRANSFERTRANSLATION) + { + misl->Translation = self->Translation; + } + // automatic handling of seeker missiles if (misl) { if (linetarget && misl->flags2&MF2_SEEKERMISSILE) misl->tracer=linetarget; - if (!AimAtAngle) + if (!(Flags & FPF_AIMATANGLE)) { // This original implementation is to aim straight ahead and then offset // the angle from the resulting direction. diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 0ea5060e2..0332d09a3 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -164,6 +164,10 @@ const int CPF_DAGGER = 2; const int CPF_PULLIN = 4; const int CPF_NORANDOMPUFFZ = 8; +// Flags for A_CustomMissile +const int FPF_AIMATANGLE = 1; +const int FPF_TRANSFERTRANSLATION = 2; + // Flags for A_Teleport const int TF_TELEFRAG = 1;const int TF_RANDOMDECIDE = 2; From 0e3bee6f300b9e441161a3f642354750ff603f0c Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Mon, 23 Jun 2014 19:52:32 +0200 Subject: [PATCH 242/311] - Enable 'language' feature on unix targets. The sdl version of the function 'SetLanguageIDs' is very limited, comparing to the win32 counterpart, as it will try to accept only the language codes (ie 'enu', 'fr', 'ptb', etc). If a different string is provided, zdoom will default its language to English. --- src/sdl/i_system.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index e46b8e59d..f7137d103 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -97,13 +97,7 @@ SDL_Cursor *X11Cursor; SDL_Cursor *FirstCursor; #endif -DWORD LanguageIDs[4] = -{ - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0) -}; +DWORD LanguageIDs[4]; int (*I_GetTime) (bool saveMS); int (*I_WaitForTic) (int); @@ -326,6 +320,13 @@ void I_WaitVBL (int count) // void SetLanguageIDs () { + size_t langlen = strlen(language); + + DWORD lang = (langlen < 2 || langlen > 3) ? + MAKE_ID('e','n','u','0') : + MAKE_ID(language[0],language[1],language[2],'0'); + + LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang; } // From bdddea541f4513999e4a77ec5a2ac4c280b7e68b Mon Sep 17 00:00:00 2001 From: djcj Date: Tue, 24 Jun 2014 11:22:55 +0200 Subject: [PATCH 243/311] update lzma to v9.22 beta --- lzma/C/7zCrc.c | 65 ++++++++++++++++++++++++++------------------- lzma/C/7zCrcOpt.c | 38 +++++++++++++++++++++++--- lzma/C/7zVersion.h | 9 ++++--- lzma/C/CpuArch.c | 20 -------------- lzma/C/CpuArch.h | 4 +-- lzma/C/Lzma2Dec.c | 26 +++++++----------- lzma/C/LzmaDec.c | 22 ++++++--------- lzma/C/LzmaEnc.c | 14 +++++++--- lzma/C/LzmaEnc.h | 12 ++++----- lzma/C/Threads.h | 7 ----- lzma/C/Types.h | 14 +++++++--- lzma/history.txt | 8 ++++++ lzma/lzma.txt | 8 +++++- lzma/lzmalib.vcproj | 3 ++- 14 files changed, 139 insertions(+), 111 deletions(-) mode change 100755 => 100644 lzma/history.txt mode change 100755 => 100644 lzma/lzma.txt diff --git a/lzma/C/7zCrc.c b/lzma/C/7zCrc.c index 5801dabfc..6993a6988 100644 --- a/lzma/C/7zCrc.c +++ b/lzma/C/7zCrc.c @@ -1,15 +1,24 @@ -/* 7zCrc.c -- CRC32 calculation -2009-11-23 : Igor Pavlov : Public domain */ +/* 7zCrc.c -- CRC32 init +2010-12-01 : Igor Pavlov : Public domain */ #include "7zCrc.h" #include "CpuArch.h" #define kCrcPoly 0xEDB88320 -#ifdef MY_CPU_LE -#define CRC_NUM_TABLES 8 +#ifdef MY_CPU_X86_OR_AMD64 + #define CRC_NUM_TABLES 8 + UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +#elif defined(MY_CPU_LE) + #define CRC_NUM_TABLES 4 #else -#define CRC_NUM_TABLES 1 + #define CRC_NUM_TABLES 5 + #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif + +#ifndef MY_CPU_BE + UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); #endif typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); @@ -17,25 +26,6 @@ typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, static CRC_FUNC g_CrcUpdate; UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; -#if CRC_NUM_TABLES == 1 - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#else - -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); - -#endif - UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) { return g_CrcUpdate(v, data, size, g_CrcTable); @@ -57,18 +47,37 @@ void MY_FAST_CALL CrcGenerateTable() r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); g_CrcTable[i] = r; } - #if CRC_NUM_TABLES == 1 - g_CrcUpdate = CrcUpdateT1; - #else for (; i < 256 * CRC_NUM_TABLES; i++) { UInt32 r = g_CrcTable[i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); } + + #ifdef MY_CPU_LE + g_CrcUpdate = CrcUpdateT4; - #ifdef MY_CPU_X86_OR_AMD64 + + #if CRC_NUM_TABLES == 8 if (!CPU_Is_InOrder()) g_CrcUpdate = CrcUpdateT8; #endif + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + g_CrcUpdate = CrcUpdateT4; + else + #endif + { + for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) + { + UInt32 x = g_CrcTable[i - 256]; + g_CrcTable[i] = CRC_UINT32_SWAP(x); + } + g_CrcUpdate = CrcUpdateT1_BeT4; + } + } #endif } diff --git a/lzma/C/7zCrcOpt.c b/lzma/C/7zCrcOpt.c index 6205d7161..85405ccfc 100644 --- a/lzma/C/7zCrcOpt.c +++ b/lzma/C/7zCrcOpt.c @@ -1,12 +1,12 @@ -/* 7zCrcOpt.c -- CRC32 calculation : optimized version -2009-11-23 : Igor Pavlov : Public domain */ +/* 7zCrcOpt.c -- CRC32 calculation +2010-12-01 : Igor Pavlov : Public domain */ #include "CpuArch.h" -#ifdef MY_CPU_LE - #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#ifndef MY_CPU_BE + UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; @@ -32,3 +32,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U } #endif + + +#ifndef MY_CPU_LE + +#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) + +UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + v = CRC_UINT32_SWAP(v); + table += 0x100; + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const UInt32 *)p; + v = + table[0x000 + (v & 0xFF)] ^ + table[0x100 + ((v >> 8) & 0xFF)] ^ + table[0x200 + ((v >> 16) & 0xFF)] ^ + table[0x300 + ((v >> 24))]; + } + table -= 0x100; + v = CRC_UINT32_SWAP(v); + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif diff --git a/lzma/C/7zVersion.h b/lzma/C/7zVersion.h index d4ac470e2..43f0fef6f 100644 --- a/lzma/C/7zVersion.h +++ b/lzma/C/7zVersion.h @@ -1,7 +1,8 @@ #define MY_VER_MAJOR 9 -#define MY_VER_MINOR 20 -#define MY_VER_BUILD 0 -#define MY_VERSION "9.20" -#define MY_DATE "2010-11-18" +#define MY_VER_MINOR 22 +#define MY_VER_BUILD 00 +#define MY_VERSION "9.22 beta" +#define MY_7ZIP_VERSION "9.22 beta" +#define MY_DATE "2011-04-18" #define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c index 925edbeb8..36e7680d9 100644 --- a/lzma/C/CpuArch.c +++ b/lzma/C/CpuArch.c @@ -3,10 +3,6 @@ #include "CpuArch.h" -#ifdef _WIN32 -#include -#endif - #ifdef MY_CPU_X86_OR_AMD64 #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) @@ -74,24 +70,8 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) *c = c2; *d = d2; - #elif __PIC__ - - /* GCC or Clang WITH position-independent code generation */ - - __asm__ __volatile__ ( - "xchgl %%ebx, %1\n" - "cpuid\n" - "xchgl %%ebx, %1\n" - : "=a" (*a) , - "=r" (*b) , - "=c" (*c) , - "=d" (*d) - : "0" (function)) ; - #else - /* GCC or Clang WITHOUT position-independent code generation */ - __asm__ __volatile__ ( "cpuid" : "=a" (*a) , diff --git a/lzma/C/CpuArch.h b/lzma/C/CpuArch.h index 0a709bb26..1cd7c29c5 100644 --- a/lzma/C/CpuArch.h +++ b/lzma/C/CpuArch.h @@ -1,5 +1,5 @@ /* CpuArch.h -- CPU specific code -2010-10-26: Igor Pavlov : Public domain */ +2010-12-01: Igor Pavlov : Public domain */ #ifndef __CPU_ARCH_H #define __CPU_ARCH_H @@ -52,7 +52,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla #define MY_CPU_LE #endif -#if defined(__BIG_ENDIAN__) +#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) #define MY_CPU_BE #endif diff --git a/lzma/C/Lzma2Dec.c b/lzma/C/Lzma2Dec.c index 8f2406755..7c4eb4449 100644 --- a/lzma/C/Lzma2Dec.c +++ b/lzma/C/Lzma2Dec.c @@ -1,5 +1,5 @@ /* Lzma2Dec.c -- LZMA2 Decoder -2009-05-03 : Igor Pavlov : Public domain */ +2010-12-15 : Igor Pavlov : Public domain */ /* #define SHOW_DEBUG_INFO */ @@ -330,27 +330,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte * SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) { - CLzma2Dec decoder; + CLzma2Dec p; SRes res; SizeT outSize = *destLen, inSize = *srcLen; - Byte props[LZMA_PROPS_SIZE]; - - Lzma2Dec_Construct(&decoder); - *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; - decoder.decoder.dic = dest; - decoder.decoder.dicBufSize = outSize; - - RINOK(Lzma2Dec_GetOldProps(prop, props)); - RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); - + Lzma2Dec_Construct(&p); + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); + p.decoder.dic = dest; + p.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&p); *srcLen = inSize; - res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); - *destLen = decoder.decoder.dicPos; + res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.decoder.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; - - LzmaDec_FreeProbs(&decoder.decoder, alloc); + Lzma2Dec_FreeProbs(&p, alloc); return res; } diff --git a/lzma/C/LzmaDec.c b/lzma/C/LzmaDec.c index 4fdc11d4b..72451d1ff 100644 --- a/lzma/C/LzmaDec.c +++ b/lzma/C/LzmaDec.c @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2009-09-20 : Igor Pavlov : Public domain */ +2010-12-15 : Igor Pavlov : Public domain */ #include "LzmaDec.h" @@ -442,8 +442,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) p->processedPos += len; p->remainLen -= len; - while (len-- != 0) + while (len != 0) { + len--; dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; dicPos++; } @@ -972,28 +973,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, { CLzmaDec p; SRes res; - SizeT inSize = *srcLen; - SizeT outSize = *destLen; - *srcLen = *destLen = 0; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; if (inSize < RC_INIT_SIZE) return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); - if (res != 0) - return res; + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); p.dic = dest; p.dicBufSize = outSize; - LzmaDec_Init(&p); - *srcLen = inSize; res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - + *destLen = p.dicPos; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) res = SZ_ERROR_INPUT_EOF; - - (*destLen) = p.dicPos; LzmaDec_FreeProbs(&p, alloc); return res; } diff --git a/lzma/C/LzmaEnc.c b/lzma/C/LzmaEnc.c index 9e6dbdbe2..da39520c6 100644 --- a/lzma/C/LzmaEnc.c +++ b/lzma/C/LzmaEnc.c @@ -1,5 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2010-04-16 : Igor Pavlov : Public domain */ +2011-01-27 : Igor Pavlov : Public domain */ #include @@ -46,6 +46,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) { p->level = 5; p->dictSize = p->mc = 0; + p->reduceSize = (UInt32)(Int32)-1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; p->writeEndMark = 0; } @@ -56,6 +57,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (level < 0) level = 5; p->level = level; if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->dictSize > p->reduceSize) + { + unsigned i; + for (i = 15; i <= 30; i++) + { + if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } + if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } + } + } if (p->lc < 0) p->lc = 3; if (p->lp < 0) p->lp = 0; if (p->pb < 0) p->pb = 2; @@ -329,7 +339,6 @@ typedef struct SRes result; UInt32 dictSize; - UInt32 matchFinderCycles; int needInit; @@ -398,7 +407,6 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) return SZ_ERROR_PARAM; p->dictSize = props.dictSize; - p->matchFinderCycles = props.mc; { unsigned fb = props.fb; if (fb < 5) diff --git a/lzma/C/LzmaEnc.h b/lzma/C/LzmaEnc.h index 999f5afff..7573ba01b 100644 --- a/lzma/C/LzmaEnc.h +++ b/lzma/C/LzmaEnc.h @@ -1,14 +1,12 @@ /* LzmaEnc.h -- LZMA Encoder -2009-02-07 : Igor Pavlov : Public domain */ +2011-01-27 : Igor Pavlov : Public domain */ #ifndef __LZMA_ENC_H #define __LZMA_ENC_H #include "Types.h" -#ifdef __cplusplus -extern "C" { -#endif +EXTERN_C_BEGIN #define LZMA_PROPS_SIZE 5 @@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version (1 << 12) <= dictSize <= (1 << 30) for 64-bit version default = (1 << 24) */ + UInt32 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. + Encoder uses this value to reduce dictionary size */ int lc; /* 0 <= lc <= 8, default = 3 */ int lp; /* 0 <= lp <= 4, default = 0 */ int pb; /* 0 <= pb <= 4, default = 2 */ @@ -73,8 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -#ifdef __cplusplus -} -#endif +EXTERN_C_END #endif diff --git a/lzma/C/Threads.h b/lzma/C/Threads.h index b82214355..6a7afa829 100644 --- a/lzma/C/Threads.h +++ b/lzma/C/Threads.h @@ -6,13 +6,6 @@ #include "Types.h" -#ifdef _WIN32 -#include -typedef DWORD WRes; -#else -typedef int WRes; -#endif - #ifdef __cplusplus extern "C" { #endif diff --git a/lzma/C/Types.h b/lzma/C/Types.h index 284991104..f193ce2f5 100644 --- a/lzma/C/Types.h +++ b/lzma/C/Types.h @@ -6,6 +6,10 @@ #include +#ifdef _WIN32 +#include +#endif + #ifndef EXTERN_C_BEGIN #ifdef __cplusplus #define EXTERN_C_BEGIN extern "C" { @@ -38,12 +42,14 @@ EXTERN_C_BEGIN typedef int SRes; -#ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#ifdef _WIN32 +typedef DWORD WRes; +#else +typedef int WRes; #endif -#if defined(__APPLE__) && !__LP64__ -#define _LZMA_UINT32_IS_ULONG +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #endif typedef unsigned char Byte; diff --git a/lzma/history.txt b/lzma/history.txt old mode 100755 new mode 100644 index 50ff40f02..36d01d7d9 --- a/lzma/history.txt +++ b/lzma/history.txt @@ -1,6 +1,14 @@ HISTORY of the LZMA SDK ----------------------- +9.21 beta 2011-04-11 +------------------------- +- New class FString for file names at file systems. +- Speed optimization in CRC code for big-endian CPUs. +- The BUG in Lzma2Dec.c was fixed: + Lzma2Decode function didn't work. + + 9.18 beta 2010-11-02 ------------------------- - New small SFX module for installers (SfxSetup). diff --git a/lzma/lzma.txt b/lzma/lzma.txt old mode 100755 new mode 100644 index 579f2ccd8..9d3cef003 --- a/lzma/lzma.txt +++ b/lzma/lzma.txt @@ -1,4 +1,4 @@ -LZMA SDK 9.20 +LZMA SDK 9.22 ------------- LZMA SDK provides the documentation, samples, header files, libraries, @@ -24,6 +24,12 @@ Some code in LZMA SDK is based on public domain code from another developers: 1) PPMd var.H (2001): Dmitry Shkarin 2) SHA-256: Wei Dai (Crypto++ library) +You can copy, modify, distribute and perform LZMA SDK code, even for commercial purposes, +all without asking permission. + +LZMA SDK code is compatible with open source licenses, for example, you can +include it to GNU GPL or GNU LGPL code. + LZMA SDK Contents ----------------- diff --git a/lzma/lzmalib.vcproj b/lzma/lzmalib.vcproj index b37a52970..e5033511b 100644 --- a/lzma/lzmalib.vcproj +++ b/lzma/lzmalib.vcproj @@ -1,11 +1,12 @@ Date: Wed, 25 Jun 2014 20:11:05 +0300 Subject: [PATCH 244/311] Fix LZMA compilation on GCC with position-independent code (PIC) generation enabled EBX register is used Global Offset Table in PIC http://www.greyhat.ch/lab/downloads/pic.html --- lzma/C/CpuArch.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c index 36e7680d9..425d18923 100644 --- a/lzma/C/CpuArch.c +++ b/lzma/C/CpuArch.c @@ -70,8 +70,24 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) *c = c2; *d = d2; + #elif __PIC__ + + /* GCC or Clang WITH position-independent code generation */ + + __asm__ __volatile__ ( + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + : "=a" (*a) , + "=r" (*b) , + "=c" (*c) , + "=d" (*d) + : "0" (function)) ; + #else + /* GCC or Clang WITHOUT position-independent code generation */ + __asm__ __volatile__ ( "cpuid" : "=a" (*a) , From 1a3ac9d0b36fa7dbaefdf2df1246cb8b246026cc Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Thu, 26 Jun 2014 01:23:41 +0200 Subject: [PATCH 245/311] - Simplify CMake GCC and Clang checking. Introduce the variable 'ZD_CMAKE_COMPILER_IS_GNUC(XX)_COMPATIBLE' and replace any occurrence of '"${CMAKE_C(XX)_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C(XX)_COMPILER_ID}" STREQUAL "Clang"' with it. This makes it possible to add more GCC compatible compilers in just one place. --- CMakeLists.txt | 15 ++++++++++++++- bzip2/CMakeLists.txt | 4 ++-- dumb/CMakeLists.txt | 8 ++++---- game-music-emu/CMakeLists.txt | 4 ++-- gdtoa/CMakeLists.txt | 4 ++-- jpeg-6b/CMakeLists.txt | 4 ++-- lzma/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 22 +++++++++++----------- tools/updaterevision/CMakeLists.txt | 6 +++--- 9 files changed, 42 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dccc6e792..d548d26a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,10 +78,23 @@ else( MSVC ) set( ZDOOM_OUTPUT_OLDSTYLE OFF ) endif( MSVC ) +# Replacement variables for a possible long list of C/C++ compilers compatible with GCC +if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) + set( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE TRUE ) +else( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) + set( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE FALSE ) +endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) + if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) - set( PROFILE 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." ) + set( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE TRUE ) +else( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + set( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE FALSE ) endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) + set( PROFILE 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) + set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") find_package( BZip2 ) diff --git a/bzip2/CMakeLists.txt b/bzip2/CMakeLists.txt index 5f35eb346..05dab7ec2 100644 --- a/bzip2/CMakeLists.txt +++ b/bzip2/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required( VERSION 2.4 ) make_release_only() -if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) -endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) add_definitions( -DBZ_NO_STDIO ) add_library( bz2 diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt index 178de53a9..2b70ee412 100644 --- a/dumb/CMakeLists.txt +++ b/dumb/CMakeLists.txt @@ -13,9 +13,9 @@ endif( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DDEBUGMODE=1" ) -if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-pointer-sign -Wno-uninitialized" ) -endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) CHECK_FUNCTION_EXISTS( itoa ITOA_EXISTS ) if( NOT ITOA_EXISTS ) @@ -103,6 +103,6 @@ add_library( dumb src/it/xmeffect.c ) target_link_libraries( dumb ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set_source_files_properties( src/it/filter.cpp PROPERTIES COMPILE_FLAGS -msse ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) diff --git a/game-music-emu/CMakeLists.txt b/game-music-emu/CMakeLists.txt index d0cc7af5f..79c528fa3 100644 --- a/game-music-emu/CMakeLists.txt +++ b/game-music-emu/CMakeLists.txt @@ -18,7 +18,7 @@ if( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) endif( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) if( NOT PROFILE ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer" ) @@ -27,7 +27,7 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE if( HAVE_NO_ARRAY_BOUNDS ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-array-bounds" ) endif( HAVE_NO_ARRAY_BOUNDS ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 72a365bbf..7f394e140 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -8,9 +8,9 @@ if( MSVC ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4554 /wd4102" ) endif( MSVC ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) add_definitions( -DINFNAN_CHECK -DMULTIPLE_THREADS ) diff --git a/jpeg-6b/CMakeLists.txt b/jpeg-6b/CMakeLists.txt index dd5055f9b..c70892770 100644 --- a/jpeg-6b/CMakeLists.txt +++ b/jpeg-6b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required( VERSION 2.4 ) make_release_only() -if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" ) -endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) add_library( jpeg jcomapi.c diff --git a/lzma/CMakeLists.txt b/lzma/CMakeLists.txt index beebb0fde..7cd330cc8 100644 --- a/lzma/CMakeLists.txt +++ b/lzma/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required( VERSION 2.4 ) make_release_only() -if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) -endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) set( LZMA_FILES C/7zBuf.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 517b6bdbe..9c53446c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,14 +15,14 @@ else( NOT APPLE ) # At the moment asm code doesn't work with OS X, so disable by default option( NO_ASM "Disable assembly code" ON ) endif( NOT APPLE ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) option( NO_STRIP "Do not strip Release or MinSizeRel builds" ) # At least some versions of Xcode fail if you strip with the linker # instead of the separate strip utility. if( APPLE ) set( NO_STRIP ON ) endif( APPLE ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON ) @@ -418,7 +418,7 @@ endif( SSE_MATTERS ) # Set up flags for GCC -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) if( PROFILE ) set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg" ) @@ -447,7 +447,7 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s" ) set (CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} -s" ) endif( NOT NO_STRIP ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # Check for functions that may or may not exist. @@ -575,15 +575,15 @@ if( WIN32 ) set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ) - if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # CMake is not set up to compile and link rc files with GCC. :( add_custom_command( OUTPUT zdoom-rc.o COMMAND windres -o zdoom-rc.o -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zdoom.rc DEPENDS win32/zdoom.rc ) set( SYSTEM_SOURCES ${SYSTEM_SOURCES} zdoom-rc.o ) - else( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + else( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( SYSTEM_SOURCES ${SYSTEM_SOURCES} win32/zdoom.rc ) - endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) else( WIN32 ) set( SYSTEM_SOURCES_DIR sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) @@ -1152,16 +1152,16 @@ if( NOT WIN32 ) COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/link-make COMMAND /bin/sh -c ${CMAKE_CURRENT_BINARY_DIR}/link-make ) endif( NOT WIN32 ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) +if( CMAKE_COMPILER_IS_GNUCXX ) # GCC misoptimizes this file set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( CMAKE_COMPILER_IS_GNUCXX ) +if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # Need to enable intrinsics for this file. if( SSE_MATTERS ) set_source_files_properties( x86.cpp PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" ) endif( SSE_MATTERS ) -endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+") source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+") diff --git a/tools/updaterevision/CMakeLists.txt b/tools/updaterevision/CMakeLists.txt index 2500f64fb..9e814a7d7 100644 --- a/tools/updaterevision/CMakeLists.txt +++ b/tools/updaterevision/CMakeLists.txt @@ -1,12 +1,12 @@ cmake_minimum_required( VERSION 2.4 ) if( WIN32 ) - if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE OR ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/trustinfo.o COMMAND windres -o ${CMAKE_CURRENT_BINARY_DIR}/trustinfo.o -i ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.rc DEPENDS trustinfo.rc ) set( TRUSTINFO trustinfo.o ) - else( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + else( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE OR ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) if( MSVC_VERSION GREATER 1399 ) # VC 8+ adds a manifest automatically to the executable. We need to # merge ours with it. @@ -14,7 +14,7 @@ if( WIN32 ) else( MSVC_VERSION GREATER 1399 ) set( TRUSTINFO trustinfo.rc ) endif( MSVC_VERSION GREATER 1399 ) - endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + endif( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE OR ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) else( WIN32 ) set( TRUSTINFO "" ) endif( WIN32 ) From 270541f9422038c829f673de30a0b4e4562d05f5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 26 Jun 2014 09:43:51 +0200 Subject: [PATCH 246/311] fixed compilation with latest LZMA SDK on Windows. LZMA SDK recently added an #include to its headers, meaning it's no longer safe to include its headers globally in platform independent files. The following changes were necessary: - rename DWORD type in zipdir.c - add USE_WINDOWS_DWORD and reorder includes in file_7z.cpp - wrap LZMA decoder stream into a local struct that's declared anonymously in files.h and adjust files.cpp for this change. --- src/files.cpp | 25 +++++++++++++++++----- src/files.h | 5 +++-- src/resourcefiles/file_7z.cpp | 6 ++++-- tools/zipdir/zipdir.c | 40 +++++++++++++++++------------------ 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/files.cpp b/src/files.cpp index d7dfc2cbe..981b351a9 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -33,11 +33,15 @@ ** */ +#define USE_WINDOWS_DWORD +#include "LzmaDec.h" + #include "files.h" #include "i_system.h" #include "templates.h" #include "m_misc.h" + //========================================================================== // // FileReader @@ -370,6 +374,15 @@ extern "C" void bz_internal_error (int errcode) // //========================================================================== +// This is retarded but necessary to work around the inclusion of windows.h in recent +// LZMA versions, meaning it's no longer possible to include the LZMA headers in files.h. +// As a result we cannot declare the CLzmaDec member in the header so we work around +// it my wrapping it into another struct that can be declared anonymously in the header. +struct FileReaderLZMA::StreamPointer +{ + CLzmaDec Stream; +}; + static void *SzAlloc(void *, size_t size) { return malloc(size); } static void SzFree(void *, void *address) { free(address); } ISzAlloc g_Alloc = { SzAlloc, SzFree }; @@ -398,20 +411,22 @@ FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool FillBuffer(); - LzmaDec_Construct(&Stream); - err = LzmaDec_Allocate(&Stream, header + 4, LZMA_PROPS_SIZE, &g_Alloc); + Streamp = new StreamPointer; + LzmaDec_Construct(&Streamp->Stream); + err = LzmaDec_Allocate(&Streamp->Stream, header + 4, LZMA_PROPS_SIZE, &g_Alloc); if (err != SZ_OK) { I_Error("FileReaderLZMA: LzmaDec_Allocate failed: %d\n", err); } - LzmaDec_Init(&Stream); + LzmaDec_Init(&Streamp->Stream); } FileReaderLZMA::~FileReaderLZMA () { - LzmaDec_Free(&Stream, &g_Alloc); + LzmaDec_Free(&Streamp->Stream, &g_Alloc); + delete Streamp; } long FileReaderLZMA::Read (void *buffer, long len) @@ -426,7 +441,7 @@ long FileReaderLZMA::Read (void *buffer, long len) size_t out_processed = len; size_t in_processed = InSize; - err = LzmaDec_DecodeToBuf(&Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status); + err = LzmaDec_DecodeToBuf(&Streamp->Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status); InPos += in_processed; InSize -= in_processed; next_out += out_processed; diff --git a/src/files.h b/src/files.h index ebe9665a4..f7d061c8e 100644 --- a/src/files.h +++ b/src/files.h @@ -4,7 +4,6 @@ #include #include #include "bzlib.h" -#include "LzmaDec.h" #include "doomtype.h" #include "m_swap.h" @@ -257,6 +256,8 @@ private: // Wraps around a FileReader to decompress a lzma stream class FileReaderLZMA : public FileReaderBase { + struct StreamPointer; + public: FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip); ~FileReaderLZMA (); @@ -308,7 +309,7 @@ private: FileReader &File; bool SawEOF; - CLzmaDec Stream; + StreamPointer *Streamp; // anonymous pointer to LKZA decoder struct - to avoid including the LZMA headers globally size_t Size; size_t InPos, InSize; size_t OutProcessed; diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 53653bb59..c3845d8cc 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -32,6 +32,10 @@ ** ** */ +#define USE_WINDOWS_DWORD + +#include "7z.h" +#include "7zCrc.h" #include "resourcefile.h" #include "cmdlib.h" @@ -41,8 +45,6 @@ #include "i_system.h" #include "w_wad.h" -#include "7z.h" -#include "7zCrc.h" //----------------------------------------------------------------------- diff --git a/tools/zipdir/zipdir.c b/tools/zipdir/zipdir.c index 9b521bedf..1479952e0 100644 --- a/tools/zipdir/zipdir.c +++ b/tools/zipdir/zipdir.c @@ -129,7 +129,7 @@ typedef struct compressor_s int method; } compressor_t; -typedef unsigned int DWORD; +typedef unsigned int UINT32; typedef unsigned short WORD; typedef unsigned char BYTE; @@ -139,49 +139,49 @@ typedef unsigned char BYTE; //#pragma pack(push,1) typedef struct { - DWORD Magic; // 0 + UINT32 Magic; // 0 BYTE VersionToExtract[2]; // 4 WORD Flags; // 6 WORD Method; // 8 WORD ModTime; // 10 WORD ModDate; // 12 - DWORD CRC32; // 14 - DWORD CompressedSize; // 18 - DWORD UncompressedSize; // 22 + UINT32 CRC32; // 14 + UINT32 CompressedSize; // 18 + UINT32 UncompressedSize; // 22 WORD NameLength; // 26 WORD ExtraLength; // 28 } LocalFileHeader; typedef struct { - DWORD Magic; + UINT32 Magic; BYTE VersionMadeBy[2]; BYTE VersionToExtract[2]; WORD Flags; WORD Method; WORD ModTime; WORD ModDate; - DWORD CRC32; - DWORD CompressedSize; - DWORD UncompressedSize; + UINT32 CRC32; + UINT32 CompressedSize; + UINT32 UncompressedSize; WORD NameLength; WORD ExtraLength; WORD CommentLength; WORD StartingDiskNumber; WORD InternalAttributes; - DWORD ExternalAttributes; - DWORD LocalHeaderOffset; + UINT32 ExternalAttributes; + UINT32 LocalHeaderOffset; } CentralDirectoryEntry; typedef struct { - DWORD Magic; + UINT32 Magic; WORD DiskNumber; WORD FirstDisk; WORD NumEntries; WORD NumEntriesOnAllDisks; - DWORD DirectorySize; - DWORD DirectoryOffset; + UINT32 DirectorySize; + UINT32 DirectoryOffset; WORD ZipCommentLength; } EndOfCentralDirectory; //#pragma pack(pop) @@ -1373,7 +1373,7 @@ BYTE *find_central_dir(FILE *fin) back_read = 4; while (back_read < max_back) { - DWORD read_size, read_pos; + UINT32 read_size, read_pos; int i; if (back_read + BUFREADCOMMENT > max_back) back_read = max_back; @@ -1420,12 +1420,12 @@ BYTE *find_central_dir(FILE *fin) free(dir); return NULL; } - if (*(DWORD *)dir != ZIP_CENTRALFILE) + if (*(UINT32 *)dir != ZIP_CENTRALFILE) { free(dir); return NULL; } - *(DWORD *)(dir + LittleLong(eod.DirectorySize)) = ZIP_ENDOFDIR; + *(UINT32 *)(dir + LittleLong(eod.DirectorySize)) = ZIP_ENDOFDIR; return dir; } @@ -1444,7 +1444,7 @@ CentralDirectoryEntry *find_file_in_zip(BYTE *dir, const char *path, unsigned in CentralDirectoryEntry *ent; int flags; - while (*(DWORD *)dir == ZIP_CENTRALFILE) + while (*(UINT32 *)dir == ZIP_CENTRALFILE) { ent = (CentralDirectoryEntry *)dir; if (pathlen == LittleShort(ent->NameLength) && @@ -1455,7 +1455,7 @@ CentralDirectoryEntry *find_file_in_zip(BYTE *dir, const char *path, unsigned in } dir += sizeof(*ent) + LittleShort(ent->NameLength) + LittleShort(ent->ExtraLength) + LittleShort(ent->CommentLength); } - if (*(DWORD *)dir != ZIP_CENTRALFILE) + if (*(UINT32 *)dir != ZIP_CENTRALFILE) { return NULL; } @@ -1495,7 +1495,7 @@ int copy_zip_file(FILE *zip, file_entry_t *file, FILE *ozip, CentralDirectoryEnt { LocalFileHeader lfh; BYTE *buf; - DWORD buf_size; + UINT32 buf_size; if (fseek(ozip, LittleLong(ent->LocalHeaderOffset), SEEK_SET) != 0) { From cb9877e7ffa2f48876a4c076398bec2851d92de1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 26 Jun 2014 17:52:26 -0400 Subject: [PATCH 247/311] - Using USE_WINDOWS_DWORD on other platforms can cause problems. --- src/files.cpp | 2 ++ src/resourcefiles/file_7z.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/files.cpp b/src/files.cpp index 981b351a9..d7dad642e 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -33,7 +33,9 @@ ** */ +#ifdef _WIN32 #define USE_WINDOWS_DWORD +#endif #include "LzmaDec.h" #include "files.h" diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index c3845d8cc..72e8d5f0e 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -32,7 +32,9 @@ ** ** */ +#ifdef _WIN32 #define USE_WINDOWS_DWORD +#endif #include "7z.h" #include "7zCrc.h" From d941203ab0d3c583700b8a91c2686ff89916a9e2 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 26 Jun 2014 20:37:11 -0400 Subject: [PATCH 248/311] - Fixed edward-san's typo. - Cleared a warning. --- src/sdl/i_system.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index f7137d103..88850d9fe 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -103,10 +103,8 @@ int (*I_GetTime) (bool saveMS); int (*I_WaitForTic) (int); void (*I_FreezeTime) (bool frozen); -void I_Tactile (int on, int off, int total) +void I_Tactile (int /*on*/, int /*off*/, int /*total*/) { - // UNUSED. - on = off = total = 0; } ticcmd_t emptycmd; @@ -323,8 +321,8 @@ void SetLanguageIDs () size_t langlen = strlen(language); DWORD lang = (langlen < 2 || langlen > 3) ? - MAKE_ID('e','n','u','0') : - MAKE_ID(language[0],language[1],language[2],'0'); + MAKE_ID('e','n','u','\0') : + MAKE_ID(language[0],language[1],language[2],'\0'); LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang; } From e6d468eb3824266f2a068394a8edde2911c20584 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 28 Jun 2014 10:49:59 +0300 Subject: [PATCH 249/311] Use byte swapping functions from on OS X Remove inclusion of Core Foundation headers to avoid type conflicts with LZMA SDK. --- src/m_swap.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/m_swap.h b/src/m_swap.h index 6e0bc88cc..82751fd47 100644 --- a/src/m_swap.h +++ b/src/m_swap.h @@ -29,51 +29,51 @@ // WAD files are stored little endian. #ifdef __APPLE__ -#include +#include inline short LittleShort(short x) { - return (short)CFSwapInt16LittleToHost((uint16_t)x); + return (short)OSSwapLittleToHostInt16((uint16_t)x); } inline unsigned short LittleShort(unsigned short x) { - return CFSwapInt16LittleToHost(x); + return OSSwapLittleToHostInt16(x); } inline short LittleShort(int x) { - return CFSwapInt16LittleToHost((uint16_t)x); + return OSSwapLittleToHostInt16((uint16_t)x); } inline int LittleLong(int x) { - return CFSwapInt32LittleToHost((uint32_t)x); + return OSSwapLittleToHostInt32((uint32_t)x); } inline unsigned int LittleLong(unsigned int x) { - return CFSwapInt32LittleToHost(x); + return OSSwapLittleToHostInt32(x); } inline short BigShort(short x) { - return (short)CFSwapInt16BigToHost((uint16_t)x); + return (short)OSSwapBigToHostInt16((uint16_t)x); } inline unsigned short BigShort(unsigned short x) { - return CFSwapInt16BigToHost(x); + return OSSwapBigToHostInt16(x); } inline int BigLong(int x) { - return CFSwapInt32BigToHost((uint32_t)x); + return OSSwapBigToHostInt32((uint32_t)x); } inline unsigned int BigLong(unsigned int x) { - return CFSwapInt32BigToHost(x); + return OSSwapBigToHostInt32(x); } #else From 7b69c60af13235f8210644a6173bc3b9d038913d Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 28 Jun 2014 10:50:37 +0300 Subject: [PATCH 250/311] Use correct 'true' keyword --- src/sdl/i_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 3c721ae51..27324edf6 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -303,8 +303,8 @@ int main (int argc, char **argv) vid_defwidth = videoInfo->current_w; vid_defheight = videoInfo->current_h; vid_defbits = videoInfo->vfmt->BitsPerPixel; - vid_vsync = True; - fullscreen = True; + vid_vsync = true; + fullscreen = true; } #endif // __APPLE__ From 65203760a841629f642c91d92103adbb554837bd Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 28 Jun 2014 10:52:26 +0300 Subject: [PATCH 251/311] Fix incorrect actor flag handling on big endian platforms --- src/thingdef/thingdef_properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 3b61bedca..81452c7b0 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -167,7 +167,7 @@ INTBOOL CheckActorFlag(const AActor *owner, FFlagDef *fd) { return fd->flagbit & *(DWORD *)(((char*)owner) + fd->structoffset); } -#ifdef __BID_ENDIAN__ +#ifdef __BIG_ENDIAN__ else if (fd->fieldsize == 2) { return fd->flagbit & *(WORD *)(((char*)owner) + fd->structoffset); From 7d7f146ce1ed2edda1ef9f0a345ac6d5456ebdaf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 28 Jun 2014 15:21:19 +0200 Subject: [PATCH 252/311] - fixed: transferring a translation to a missile needs to check if the missile was spawned successfully. --- src/thingdef/thingdef_codeptr.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9055f7b91..048d4d47f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1340,14 +1340,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) self->pitch -= pitch; AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget); self->pitch = SavedPlayerPitch; - if (Flags & FPF_TRANSFERTRANSLATION) - { - misl->Translation = self->Translation; - } // automatic handling of seeker missiles if (misl) { + if (Flags & FPF_TRANSFERTRANSLATION) misl->Translation = self->Translation; if (linetarget && misl->flags2&MF2_SEEKERMISSILE) misl->tracer=linetarget; if (!(Flags & FPF_AIMATANGLE)) { From d0e551060dd0f5a78dcce5a013dc29110874047b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Jun 2014 12:50:42 +0200 Subject: [PATCH 253/311] - fixed: When the 3D floor init code was updated 5 years ago for Vavoom's latest changes to its 3D-floor implementation it accidentally set the 3D-floor's alpha as its desaturation. --- src/p_3dfloors.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 95ced549a..91153715a 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -253,10 +253,11 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) l->frontsector->ColorMap = GetSpecialLights (l->frontsector->ColorMap->Color, (unsigned int)(vavoomcolors[l->args[0]]&VC_COLORMASK), - (unsigned int)(vavoomcolors[l->args[0]]&VC_ALPHAMASK)>>24); - // l->frontsector->ColorMap->Desaturate); + l->frontsector->ColorMap->Desaturate); + + alpha = (int)((unsigned int)(vavoomcolors[l->args[0]]&VC_ALPHAMASK)>>24); } - alpha=(alpha*255)/100; + else alpha=(alpha*255)/100; break; } } From dd05e564cf1c0d1eb6b878c9690e4a3e2fa6cf1e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Jun 2014 14:32:50 +0200 Subject: [PATCH 254/311] - this needed more fixes... --- src/p_3dfloors.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 91153715a..bdeb45d78 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -226,11 +226,11 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) if (param==0) { flags=FF_EXISTS|FF_RENDERALL|FF_SOLID|FF_INVERTSECTOR; + alpha = 255; for (i=0;ilinecount;i++) { line_t * l=sec->lines[i]; - alpha=255; if (l->special==Sector_SetContents && l->frontsector==sec) { alpha=clamp(l->args[1], 0, 100); @@ -252,12 +252,10 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) l->frontsector->ColorMap = GetSpecialLights (l->frontsector->ColorMap->Color, - (unsigned int)(vavoomcolors[l->args[0]]&VC_COLORMASK), + vavoomcolors[l->args[0]], l->frontsector->ColorMap->Desaturate); - - alpha = (int)((unsigned int)(vavoomcolors[l->args[0]]&VC_ALPHAMASK)>>24); } - else alpha=(alpha*255)/100; + alpha=(alpha*255)/100; break; } } From d83f048858c6ca3be9442dce658a4dae542ebfad Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Tue, 1 Jul 2014 19:13:05 +0200 Subject: [PATCH 255/311] - Miscellaneous CMakeLists.txt fixes. - fixed a CMake warning about uninitialized use of the variable CROSS_EXPORTS in the tools subfolder when CMAKE_CROSSCOMPILING is off; - fixed a variable typo: CMAKE_CURRENTY_BINARY_DIR instead of CMAKE_CURRENT_BINARY_DIR; - in src/CMakeLists.txt, fixed a missing merge of a portion of code from maint branch to master. --- CMakeLists.txt | 6 ++++++ gdtoa/CMakeLists.txt | 2 +- src/CMakeLists.txt | 7 ++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d548d26a9..65e2d223f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,12 @@ endif( GME_FOUND AND NOT FORCE_INTERNAL_GME ) set( LZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lzma/C" ) +if( NOT CMAKE_CROSSCOMPILING ) + if( NOT CROSS_EXPORTS ) + set( CROSS_EXPORTS "" ) + endif( NOT CROSS_EXPORTS ) +endif( NOT CMAKE_CROSSCOMPILING ) + add_subdirectory( lzma ) add_subdirectory( tools ) add_subdirectory( dumb ) diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 7f394e140..9ec7c2f61 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -34,7 +34,7 @@ if( NOT MSVC AND NOT APPLE ) DEPENDS qnan ) set( GEN_FP_FILES arith.h gd_qnan.h ) - set( GEN_FP_DEPS ${CMAKE_CURRENT_BINARY_DIR}/arith.h ${CMAKE_CURRENTY_BINARY_DIR}/gd_qnan.h ) + set( GEN_FP_DEPS ${CMAKE_CURRENT_BINARY_DIR}/arith.h ${CMAKE_CURRENT_BINARY_DIR}/gd_qnan.h ) endif( NOT MSVC AND NOT APPLE ) add_library( gdtoa diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c53446c8..1564c9e60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -595,12 +595,13 @@ else( WIN32 ) endif( APPLE ) endif( WIN32 ) +if( NOT ASM_SOURCES ) + set( ASM_SOURCES "" ) +endif( NOT ASM_SOURCES ) + if( NO_ASM ) add_definitions( -DNOASM ) else( NO_ASM ) - if( NOT ASM_SOURCES ) - set( ASM_SOURCES "" ) - endif( NOT ASM_SOURCES ) if( X64 ) ADD_ASM_FILE( asm_x86_64 tmap3 ) else( X64 ) From e1729a9ec206b20a8ea0b9c2314d2652c697cd0f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 9 Jul 2014 09:15:51 +0200 Subject: [PATCH 256/311] - fixed compilation with VC++2005 solution. hu_stuff.h defined some callbacks for qsort without STACK_ARGS which causes problems with this solution's Release setting which uses __fastcall calling convention. --- src/hu_stuff.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index e2cc75918..dc22a2adc 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -21,6 +21,8 @@ #ifndef __HU_STUFF_H__ #define __HU_STUFF_H__ +#include "doomtype.h" + struct event_t; class player_t; @@ -52,7 +54,7 @@ int HU_GetRowColor(player_t *player, bool hightlight); // Sorting routines -int comparepoints(const void *arg1, const void *arg2); -int compareteams(const void *arg1, const void *arg2); +int STACK_ARGS comparepoints(const void *arg1, const void *arg2); +int STACK_ARGS compareteams(const void *arg1, const void *arg2); #endif From e1130b860ea5c56b0c0ba2218bf81851e9b5be4c Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 13 Jul 2014 14:32:43 +1200 Subject: [PATCH 257/311] Serialize FriendPlayer --- src/p_mobj.cpp | 4 ++++ src/version.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 72679ef71..076d106eb 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -314,6 +314,10 @@ void AActor::Serialize (FArchive &arc) arc << PoisonDamageType << PoisonDamageTypeReceived; } arc << ConversationRoot << Conversation; + if (SaveVersion >= 4509) + { + arc << FriendPlayer; + } { FString tagstr; diff --git a/src/version.h b/src/version.h index 6c94bf3e6..6b6361d26 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4508 +#define SAVEVER 4509 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 400a573e6505f4759d98774726a40ac701187d04 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 09:12:46 +0200 Subject: [PATCH 258/311] - fixed: ACS's LineAttack function with a valid tid still used the activator as the attack's source. --- src/p_acs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 981870a36..feecbb0aa 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5105,7 +5105,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const while ((source = it.Next()) != NULL) { - P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags); + P_LineAttack(source, angle, range, pitch, damage, damagetype, pufftype, fhflags); } } } From 004cf5748c6a425fea717635c7269608d52c3c61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 09:43:28 +0200 Subject: [PATCH 259/311] - fixed: FraggleScript's SpawnedThings array must always be checked for owned inventory items. The 'mapthingnumexist' function forgot to do that. --- src/fragglescript/t_func.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 2513a68a8..32d4909d4 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -3530,8 +3530,17 @@ void FParser::SF_MapThingNumExist() } else { + // Inventory items in the player's inventory have to be considered non-present. + if (SpawnedThings[intval]->IsKindOf(RUNTIME_CLASS(AInventory)) && + barrier_cast(SpawnedThings[intval])->Owner != NULL) + { + t_return.value.i = 0; + } + else + { + t_return.value.i = 1; + } t_return.type = svt_int; - t_return.value.i = 1; } } } @@ -3770,11 +3779,14 @@ void FParser::SF_ObjType() mo = Script->trigger; } - for(unsigned int i=0;iGetClass() == ActorTypes[i]) + if (mo != NULL) { - t_return.type = svt_int; - t_return.value.i = i; - return; + for (unsigned int i = 0; i < countof(ActorTypes); i++) if (mo->GetClass() == ActorTypes[i]) + { + t_return.type = svt_int; + t_return.value.i = i; + return; + } } t_return.type = svt_int; t_return.value.i = -1; From 20207699671531fd95cd7d01ff39dc7ce9ed522e Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 15 Jul 2014 20:16:28 -0400 Subject: [PATCH 260/311] - Fixed: Player turned into a zombie if exiting telefragged in buddha mode. - Fixed: Players could drop their inventory after dying. --- src/d_net.cpp | 3 ++- src/p_interaction.cpp | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 60a2b61c4..2cf13173f 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2163,7 +2163,8 @@ void Net_DoCommand (int type, BYTE **stream, int player) { DWORD which = ReadLong (stream); - if (gamestate == GS_LEVEL && !paused) + if (gamestate == GS_LEVEL && !paused + && players[player].playerstate != PST_DEAD) { AInventory *item = players[player].mo->Inventory; while (item != NULL && item->InventoryID != which) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 0eae78632..c3be908ea 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1255,7 +1255,9 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // This does not save the player if damage >= TELEFRAG_DAMAGE, still need to // telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor, // but telefragging should still do enough damage to kill the player) - if ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE) + if ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE + // Ignore players that are already dead. + && player->playerstate != PST_DEAD) { // If this is a voodoo doll we need to handle the real player as well. player->mo->health = target->health = player->health = 1; From fa5dfe79aec92b0876ad2c325b6d3c84839d1ea0 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 15 Jul 2014 21:07:07 -0400 Subject: [PATCH 261/311] - Disable cubic and spline resamplers on 64-bit with fmod 4.26 since they crash. --- src/sound/fmodsound.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 18f4cbb8f..648eb504e 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -212,8 +212,11 @@ static const FEnumList ResamplerNames[] = { "No Interpolation", FMOD_DSP_RESAMPLER_NOINTERP }, { "NoInterp", FMOD_DSP_RESAMPLER_NOINTERP }, { "Linear", FMOD_DSP_RESAMPLER_LINEAR }, + // [BL] 64-bit version of FMOD Ex 4.26 crashes with these resamplers. +#if !(defined(_M_X64) || defined(__amd64__)) || !(FMOD_VERSION >= 0x42600 && FMOD_VERSION <= 0x426FF) { "Cubic", FMOD_DSP_RESAMPLER_CUBIC }, { "Spline", FMOD_DSP_RESAMPLER_SPLINE }, +#endif { NULL, 0 } }; From bfbea404156633b8d9360995fb9250c5f78a0e1d Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 15 Jul 2014 21:20:05 -0400 Subject: [PATCH 262/311] - Fixed some typos with chex quest obituaries and French translation error. --- wadsrc/static/actors/chex/chexweapons.txt | 4 ++-- wadsrc/static/language.fr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/actors/chex/chexweapons.txt b/wadsrc/static/actors/chex/chexweapons.txt index 97043f2ca..96d8b4c4b 100644 --- a/wadsrc/static/actors/chex/chexweapons.txt +++ b/wadsrc/static/actors/chex/chexweapons.txt @@ -18,7 +18,7 @@ actor SuperBootspork : Chainsaw 2005 actor MiniZorcher : Pistol { game Chex - obituary "$OP_MPZORCH" + obituary "$OB_MPZORCH" inventory.pickupmessage "$GOTMINIZORCHER" Tag "$TAG_MINIZORCHER" states @@ -31,7 +31,7 @@ actor MiniZorcher : Pistol actor LargeZorcher : Shotgun 2001 { game Chex - obituary "$OP_MPZORCH" + obituary "$OB_MPZORCH" inventory.pickupmessage "$GOTLARGEZORCHER" Tag "$TAG_LARGEZORCHER" } diff --git a/wadsrc/static/language.fr b/wadsrc/static/language.fr index 1533a1506..10021fd82 100644 --- a/wadsrc/static/language.fr +++ b/wadsrc/static/language.fr @@ -993,7 +993,7 @@ HHUSTR_E5M9 = "L ECHEVAUX DE D'SPARIL"; TXT_GOTBLUEKEY = "CLE BLEUE"; TXT_GOTYELLOWKEY = "CLE JAUNE"; -TXT_GOTGREENKEY = "CLE ROUGE"; +TXT_GOTGREENKEY = "CLÉ VERTE"; // Artifacts From bd5bf2a40afd466245ded5630a66352ccbb524ce Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 15 Jul 2014 21:26:26 -0400 Subject: [PATCH 263/311] - Expand environment variables for autoload paths. - Forgot to save the French translation file for the last commit, so a few more corrections there. --- src/d_main.cpp | 2 +- wadsrc/static/language.fr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 93e6368c1..29a12c9c2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1598,7 +1598,7 @@ void D_AddConfigWads (TArray &wadfiles, const char *section) { // D_AddWildFile resets GameConfig's position, so remember it GameConfig->GetPosition (pos); - D_AddWildFile (wadfiles, value); + D_AddWildFile (wadfiles, ExpandEnvVars(value)); // Reset GameConfig's position to get next wad GameConfig->SetPosition (pos); } diff --git a/wadsrc/static/language.fr b/wadsrc/static/language.fr index 10021fd82..4e146955d 100644 --- a/wadsrc/static/language.fr +++ b/wadsrc/static/language.fr @@ -991,8 +991,8 @@ HHUSTR_E5M9 = "L ECHEVAUX DE D'SPARIL"; // Keys -TXT_GOTBLUEKEY = "CLE BLEUE"; -TXT_GOTYELLOWKEY = "CLE JAUNE"; +TXT_GOTBLUEKEY = "CLÉ BLEUE"; +TXT_GOTYELLOWKEY = "CLÉ JAUNE"; TXT_GOTGREENKEY = "CLÉ VERTE"; // Artifacts From b6bbdf619573fceebfb14a37d7ad0cc3177145d6 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 16 Jul 2014 18:59:49 -0400 Subject: [PATCH 264/311] - Call C_DeinitConsole in I_Quit so that we can be sure that Printf will work for as long as possible. Otherwise ZDoom will crash when ending a demo recording. --- src/d_main.cpp | 2 -- src/sdl/i_system.cpp | 2 ++ src/win32/i_system.cpp | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 29a12c9c2..2570e7a36 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1987,8 +1987,6 @@ static void D_DoomInit() Args->CollectFiles("-playdemo", ".lmp"); Args->CollectFiles("-file", NULL); // anything left goes after -file - atterm (C_DeinitConsole); - gamestate = GS_STARTUP; SetLanguageIDs (); diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 88850d9fe..9b3027a7d 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -353,6 +353,8 @@ void I_Quit (void) if (demorecording) G_CheckDemoStatus(); + + C_DeinitConsole(); } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 4690c253d..4248df274 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -781,6 +781,8 @@ void I_Quit() { G_CheckDemoStatus(); } + + C_DeinitConsole(); } From 84cb49b074962fd114c1dfd5268ece46ed5b0f4f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 16 Jul 2014 19:19:20 -0400 Subject: [PATCH 265/311] - Fixed: Legacy render style array was in the wrong order. --- src/p_acs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index feecbb0aa..87e65cac3 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3542,14 +3542,14 @@ static const int LegacyRenderStyleIndices[] = 3, // STYLE_SoulTrans, 4, // STYLE_OptFuzzy, 5, // STYLE_Stencil, - 6, // STYLE_AddStencil - 7, // STYLE_AddShaded 64, // STYLE_Translucent 65, // STYLE_Add, 66, // STYLE_Shaded, 67, // STYLE_TranslucentStencil, 68, // STYLE_Shadow, 69, // STYLE_Subtract, + 6, // STYLE_AddStencil + 7, // STYLE_AddShaded -1 }; From f99a84b498976c82e7410f94e9fbaced45cb6c31 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Mon, 14 Jul 2014 22:26:40 +1200 Subject: [PATCH 266/311] Changes to maketic/menu/console updates - Console and Menu will now update cleanly during stalls. - Moved net adaption so uncapped framerate will always use it. --- src/c_console.cpp | 10 +++-- src/d_net.cpp | 108 ++++++++++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 4dabdb9e1..e7c7dc30b 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -641,12 +641,14 @@ void C_NewModeAdjust () C_AdjustBottom (); } +int consoletic = 0; void C_Ticker () { static int lasttic = 0; + consoletic++; if (lasttic == 0) - lasttic = gametic - 1; + lasttic = consoletic - 1; if (con_buffersize > 0) { @@ -657,7 +659,7 @@ void C_Ticker () { if (ConsoleState == c_falling) { - ConBottom += (gametic - lasttic) * (SCREENHEIGHT*2/25); + ConBottom += (consoletic - lasttic) * (SCREENHEIGHT * 2 / 25); if (ConBottom >= SCREENHEIGHT / 2) { ConBottom = SCREENHEIGHT / 2; @@ -666,7 +668,7 @@ void C_Ticker () } else if (ConsoleState == c_rising) { - ConBottom -= (gametic - lasttic) * (SCREENHEIGHT*2/25); + ConBottom -= (consoletic - lasttic) * (SCREENHEIGHT * 2 / 25); if (ConBottom <= 0) { ConsoleState = c_up; @@ -681,7 +683,7 @@ void C_Ticker () CursorTicker = C_BLINKRATE; } - lasttic = gametic; + lasttic = consoletic; if (NotifyTopGoal > NotifyTop) { diff --git a/src/d_net.cpp b/src/d_net.cpp index 2cf13173f..0daf010c6 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1275,6 +1275,55 @@ void NetUpdate (void) // listen for other packets GetPackets (); + + if (!demoplayback) + { + // ideally nettics[0] should be 1 - 3 tics above lowtic + // if we are consistantly slower, speed up time + + // [RH] I had erroneously assumed frameskip[] had 4 entries + // because there were 4 players, but that's not the case at + // all. The game is comparing the lag behind the master for + // four runs of TryRunTics. If our tic count is ahead of the + // master all 4 times, the next run of NetUpdate will not + // process any new input. If we have less input than the + // master, the next run of NetUpdate will process extra tics + // (because gametime gets decremented here). + + // the key player does not adapt + if (consoleplayer != Net_Arbitrator) + { + // I'm not sure about this when using a packet server, because + // if left unmodified from the P2P version, it can make the game + // very jerky. The way I have it written right now basically means + // that it won't adapt. Fortunately, player prediction helps + // alleviate the lag somewhat. + + if (NetMode != NET_PacketServer) + { + mastertics = nettics[nodeforplayer[Net_Arbitrator]]; + } + if (nettics[0] <= mastertics) + { + gametime--; + if (debugfile) fprintf(debugfile, "-"); + } + if (NetMode != NET_PacketServer) + { + frameskip[(maketic / ticdup) & 3] = (oldnettics > mastertics); + } + else + { + frameskip[(maketic / ticdup) & 3] = (oldnettics - mastertics) > 3; + } + if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) + { + skiptics = 1; + if (debugfile) fprintf(debugfile, "+"); + } + oldnettics = nettics[0]; + } + }// !demoplayback } @@ -1751,72 +1800,27 @@ void TryRunTics (void) else counts = availabletics; + // Uncapped framerate needs seprate checks if (counts == 0 && !doWait) { // Check possible stall conditions Net_CheckLastRecieved(counts); + if (realtics >= 1) + { + C_Ticker(); + M_Ticker(); + } return; } if (counts < 1) counts = 1; - frameon++; - if (debugfile) fprintf (debugfile, "=======real: %i avail: %i game: %i\n", realtics, availabletics, counts); - if (!demoplayback) - { - // ideally nettics[0] should be 1 - 3 tics above lowtic - // if we are consistantly slower, speed up time - - // [RH] I had erroneously assumed frameskip[] had 4 entries - // because there were 4 players, but that's not the case at - // all. The game is comparing the lag behind the master for - // four runs of TryRunTics. If our tic count is ahead of the - // master all 4 times, the next run of NetUpdate will not - // process any new input. If we have less input than the - // master, the next run of NetUpdate will process extra tics - // (because gametime gets decremented here). - - // the key player does not adapt - if (consoleplayer != Net_Arbitrator) - { - // I'm not sure about this when using a packet server, because - // if left unmodified from the P2P version, it can make the game - // very jerky. The way I have it written right now basically means - // that it won't adapt. Fortunately, player prediction helps - // alleviate the lag somewhat. - - if (NetMode != NET_PacketServer) - { - mastertics = nettics[nodeforplayer[Net_Arbitrator]]; - } - if (nettics[0] <= mastertics) - { - gametime--; - if (debugfile) fprintf (debugfile, "-"); - } - if (NetMode != NET_PacketServer) - { - frameskip[frameon&3] = (oldnettics > mastertics); - } - else - { - frameskip[frameon&3] = (oldnettics - mastertics) > 3; - } - if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) - { - skiptics = 1; - if (debugfile) fprintf (debugfile, "+"); - } - oldnettics = nettics[0]; - } - }// !demoplayback - // wait for new tics if needed while (lowtic < gametic + counts) { @@ -1836,7 +1840,7 @@ void TryRunTics (void) Net_CheckLastRecieved (counts); // don't stay in here forever -- give the menu a chance to work - if (I_GetTime (false) - entertic >= TICRATE/3) + if (I_GetTime (false) - entertic >= 1) { C_Ticker (); M_Ticker (); From 484eb347ca9f2fc0d565f7f8f9bf27dc0d06aecc Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 18 Jul 2014 01:00:38 +0200 Subject: [PATCH 267/311] - Fixed: wrong FString empty string check. Even when '+logfile' argument was omitted, the console would print 'Could not start log', because 'logfile != NULL' was used as a check for the presence of '+logfile' argument, but the internal buffer of FString is never NULL, so the right check is 'logfile.isNotEmpty()'. While I'm at it, I fixed another bad check for 'pagename'. --- src/d_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 2570e7a36..628a885b2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1319,7 +1319,7 @@ void D_DoAdvanceDemo (void) break; } - if (pagename) + if (pagename.IsNotEmpty()) { if (Page != NULL) { @@ -2235,7 +2235,7 @@ void D_DoomMain (void) // +logfile gets checked too late to catch the full startup log in the logfile so do some extra check for it here. FString logfile = Args->TakeValue("+logfile"); - if (logfile != NULL) + if (logfile.IsNotEmpty()) { execLogfile(logfile); } @@ -2273,7 +2273,7 @@ void D_DoomMain (void) // The IWAD selection dialogue does not show in fullscreen so if the // restart is initiated without a defined IWAD assume for now that it's not going to change. - if (iwad.Len() == 0) iwad = lastIWAD; + if (iwad.IsEmpty()) iwad = lastIWAD; FIWadManager *iwad_man = new FIWadManager; const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); From ae2f7b87071d7dbcd2e0d274485411106a7a70b1 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 19 Jul 2014 00:53:18 +0200 Subject: [PATCH 268/311] - Remove a duplicate of a custom offsetof macro. It's already defined in cmdlib.h . --- src/p_terrain.cpp | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index fdd98c96a..a1a9ea25b 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -189,41 +189,38 @@ static const char *TerrainKeywords[] = NULL }; -// Alternate offsetof macro to shut GCC up -#define theoffsetof(type,field) ((size_t)&((type*)1)->field - 1) - static FGenericParse SplashParser[] = { { GEN_End, {0} }, - { GEN_Sound, {theoffsetof(FSplashDef, SmallSplashSound)} }, - { GEN_Fixed, {theoffsetof(FSplashDef, SmallSplashClip)} }, - { GEN_Sound, {theoffsetof(FSplashDef, NormalSplashSound)} }, - { GEN_Class, {theoffsetof(FSplashDef, SmallSplash)} }, - { GEN_Class, {theoffsetof(FSplashDef, SplashBase)} }, - { GEN_Class, {theoffsetof(FSplashDef, SplashChunk)} }, - { GEN_Byte, {theoffsetof(FSplashDef, ChunkXVelShift)} }, - { GEN_Byte, {theoffsetof(FSplashDef, ChunkYVelShift)} }, - { GEN_Byte, {theoffsetof(FSplashDef, ChunkZVelShift)} }, - { GEN_Fixed, {theoffsetof(FSplashDef, ChunkBaseZVel)} }, - { GEN_Bool, {theoffsetof(FSplashDef, NoAlert)} } + { GEN_Sound, {myoffsetof(FSplashDef, SmallSplashSound)} }, + { GEN_Fixed, {myoffsetof(FSplashDef, SmallSplashClip)} }, + { GEN_Sound, {myoffsetof(FSplashDef, NormalSplashSound)} }, + { GEN_Class, {myoffsetof(FSplashDef, SmallSplash)} }, + { GEN_Class, {myoffsetof(FSplashDef, SplashBase)} }, + { GEN_Class, {myoffsetof(FSplashDef, SplashChunk)} }, + { GEN_Byte, {myoffsetof(FSplashDef, ChunkXVelShift)} }, + { GEN_Byte, {myoffsetof(FSplashDef, ChunkYVelShift)} }, + { GEN_Byte, {myoffsetof(FSplashDef, ChunkZVelShift)} }, + { GEN_Fixed, {myoffsetof(FSplashDef, ChunkBaseZVel)} }, + { GEN_Bool, {myoffsetof(FSplashDef, NoAlert)} } }; static FGenericParse TerrainParser[] = { { GEN_End, {0} }, - { GEN_Splash, {theoffsetof(FTerrainDef, Splash)} }, - { GEN_Int, {theoffsetof(FTerrainDef, DamageAmount)} }, + { GEN_Splash, {myoffsetof(FTerrainDef, Splash)} }, + { GEN_Int, {myoffsetof(FTerrainDef, DamageAmount)} }, { GEN_Custom, {(size_t)ParseDamage} }, - { GEN_Int, {theoffsetof(FTerrainDef, DamageTimeMask)} }, - { GEN_Fixed, {theoffsetof(FTerrainDef, FootClip)} }, - { GEN_Float, {theoffsetof(FTerrainDef, StepVolume)} }, - { GEN_Time, {theoffsetof(FTerrainDef, WalkStepTics)} }, - { GEN_Time, {theoffsetof(FTerrainDef, RunStepTics)} }, - { GEN_Sound, {theoffsetof(FTerrainDef, LeftStepSound)} }, - { GEN_Sound, {theoffsetof(FTerrainDef, RightStepSound)} }, - { GEN_Bool, {theoffsetof(FTerrainDef, IsLiquid)} }, + { GEN_Int, {myoffsetof(FTerrainDef, DamageTimeMask)} }, + { GEN_Fixed, {myoffsetof(FTerrainDef, FootClip)} }, + { GEN_Float, {myoffsetof(FTerrainDef, StepVolume)} }, + { GEN_Time, {myoffsetof(FTerrainDef, WalkStepTics)} }, + { GEN_Time, {myoffsetof(FTerrainDef, RunStepTics)} }, + { GEN_Sound, {myoffsetof(FTerrainDef, LeftStepSound)} }, + { GEN_Sound, {myoffsetof(FTerrainDef, RightStepSound)} }, + { GEN_Bool, {myoffsetof(FTerrainDef, IsLiquid)} }, { GEN_Custom, {(size_t)ParseFriction} }, - { GEN_Bool, {theoffsetof(FTerrainDef, AllowProtection)} }, + { GEN_Bool, {myoffsetof(FTerrainDef, AllowProtection)} }, }; From 0276760a2d45dc5928e8de5cd51446af17b4dfda Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 19 Jul 2014 20:49:53 +1200 Subject: [PATCH 269/311] Animate switches when bumped --- src/p_spec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index e66dc2ab4..5068cd575 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -252,7 +252,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) if (buttonSuccess) { - if (activationType == SPAC_Use || activationType == SPAC_Impact) + if (activationType == SPAC_Use || activationType == SPAC_Impact || activationType == SPAC_Push) { P_ChangeSwitchTexture (line->sidedef[0], repeat, special); } From ff257a0300271da8c55a5d664ee482ffd71834fc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 21 Jul 2014 22:31:05 -0500 Subject: [PATCH 270/311] Fix compiling with provided VS 2005 projects --- game-music-emu/game-music-emu.vcproj | 1 + lzma/lzmalib.vcproj | 2 +- zdoom.vcproj | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/game-music-emu/game-music-emu.vcproj b/game-music-emu/game-music-emu.vcproj index 8ded6444a..45de9ebfb 100644 --- a/game-music-emu/game-music-emu.vcproj +++ b/game-music-emu/game-music-emu.vcproj @@ -180,6 +180,7 @@ WarningLevel="3" Detect64BitPortabilityProblems="true" DebugInformationFormat="3" + CallingConvention="1" /> + + From a21f01bc5f9b656f2a35376cf850808bac5ea792 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 Jul 2014 10:15:07 +0200 Subject: [PATCH 271/311] - added jpalomo's submission to make freelook a 3-state setting, like crouch and jump. This required moving around the flags a bit so demo compatibility had to be bumped. It may also require adjustment for launchers that can set the dmflags. --- src/d_main.cpp | 5 ++++- src/doomdef.h | 3 ++- src/g_game.cpp | 7 +++++++ src/g_level.cpp | 6 +++--- src/g_shared/a_pickups.cpp | 2 +- src/version.h | 8 ++++---- wadsrc/static/menudef.txt | 8 ++++---- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 628a885b2..90391433a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -422,7 +422,7 @@ CVAR (Flag, sv_fastmonsters, dmflags, DF_FAST_MONSTERS); CVAR (Flag, sv_nojump, dmflags, DF_NO_JUMP); CVAR (Flag, sv_allowjump, dmflags, DF_YES_JUMP); CVAR (Flag, sv_nofreelook, dmflags, DF_NO_FREELOOK); -CVAR (Flag, sv_respawnsuper, dmflags, DF_RESPAWN_SUPER); +CVAR (Flag, sv_allowfreelook, dmflags, DF_YES_FREELOOK); CVAR (Flag, sv_nofov, dmflags, DF_NO_FOV); CVAR (Flag, sv_noweaponspawn, dmflags, DF_NO_COOP_WEAPON_SPAWN); CVAR (Flag, sv_nocrouch, dmflags, DF_NO_CROUCH); @@ -439,6 +439,7 @@ CVAR (Flag, sv_coophalveammo, dmflags, DF_COOP_HALVE_AMMO); CVAR (Mask, sv_crouch, dmflags, DF_NO_CROUCH|DF_YES_CROUCH); CVAR (Mask, sv_jump, dmflags, DF_NO_JUMP|DF_YES_JUMP); CVAR (Mask, sv_fallingdamage, dmflags, DF_FORCE_FALLINGHX|DF_FORCE_FALLINGZD); +CVAR (Mask, sv_freelook, dmflags, DF_NO_FREELOOK|DF_YES_FREELOOK); //========================================================================== // @@ -510,6 +511,8 @@ CVAR (Flag, sv_noautoaim, dmflags2, DF2_NOAUTOAIM); CVAR (Flag, sv_dontcheckammo, dmflags2, DF2_DONTCHECKAMMO); CVAR (Flag, sv_killbossmonst, dmflags2, DF2_KILLBOSSMONST); CVAR (Flag, sv_nocountendmonst, dmflags2, DF2_NOCOUNTENDMONST); +CVAR (Flag, sv_respawnsuper, dmflags2, DF2_RESPAWN_SUPER); + //========================================================================== // // CVAR compatflags diff --git a/src/doomdef.h b/src/doomdef.h index 6ef9fcd04..3e00975cf 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -254,7 +254,7 @@ enum DF_NO_JUMP = 1 << 16, // Don't allow jumping DF_YES_JUMP = 2 << 16, DF_NO_FREELOOK = 1 << 18, // Don't allow freelook - DF_RESPAWN_SUPER = 1 << 19, // Respawn invulnerability and invisibility + DF_YES_FREELOOK = 2 << 18, DF_NO_FOV = 1 << 20, // Only let the arbitrator set FOV (for all players) DF_NO_COOP_WEAPON_SPAWN = 1 << 21, // Don't spawn multiplayer weapons in coop games DF_NO_CROUCH = 1 << 22, // Don't allow crouching @@ -298,6 +298,7 @@ enum DF2_DONTCHECKAMMO = 1 << 24, // Don't Check ammo when switching weapons. DF2_KILLBOSSMONST = 1 << 25, // Kills all monsters spawned by a boss cube when the boss dies DF2_NOCOUNTENDMONST = 1 << 26, // Do not count monsters in 'end level when dying' sectors towards kill count + DF2_RESPAWN_SUPER = 1 << 27, // Respawn invulnerability and invisibility }; // [RH] Compatibility flags. diff --git a/src/g_game.cpp b/src/g_game.cpp index b84ac890d..2058c2df0 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1835,6 +1835,13 @@ void G_DoLoadGame () BYTE *vars_p = (BYTE *)text; C_ReadCVars (&vars_p); delete[] text; + if (SaveVersion <= 4509) + { + // account for the flag shuffling for making freelook a 3-state option + INTBOOL flag = dmflags & DF_YES_FREELOOK; + dmflags = dmflags & ~DF_YES_FREELOOK; + if (flag) dmflags2 = dmflags2 | DF2_RESPAWN_SUPER; + } } // dearchive all the modifications diff --git a/src/g_level.cpp b/src/g_level.cpp index c4aafda4b..69bee5de1 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1320,11 +1320,11 @@ bool FLevelLocals::IsCrouchingAllowed() const bool FLevelLocals::IsFreelookAllowed() const { - if (level.flags & LEVEL_FREELOOK_NO) + if (dmflags & DF_NO_FREELOOK) return false; - if (level.flags & LEVEL_FREELOOK_YES) + if (dmflags & DF_YES_FREELOOK) return true; - return !(dmflags & DF_NO_FREELOOK); + return !(level.flags & LEVEL_FREELOOK_NO); } //========================================================================== diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index f14e7f4c7..acb6224a3 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -497,7 +497,7 @@ bool AInventory::SpecialDropAction (AActor *dropper) bool AInventory::ShouldRespawn () { - if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags & DF_RESPAWN_SUPER)) return false; + if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags2 & DF2_RESPAWN_SUPER)) return false; if (ItemFlags & IF_NEVERRESPAWN) return false; return !!(dmflags & DF_ITEMS_RESPAWN); } diff --git a/src/version.h b/src/version.h index 6b6361d26..6d24c3fe8 100644 --- a/src/version.h +++ b/src/version.h @@ -51,7 +51,7 @@ const char *GetVersionString(); // Version identifier for network games. // Bump it every time you do a release unless you're certain you // didn't change anything that will affect sync. -#define NETGAMEVERSION 229 +#define NETGAMEVERSION 230 // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to @@ -61,11 +61,11 @@ const char *GetVersionString(); // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x21A +#define DEMOGAMEVERSION 0x21B // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. -#define MINDEMOVERSION 0x215 +#define MINDEMOVERSION 0x21B // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION. @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4509 +#define SAVEVER 4510 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 71aeb9ae5..7099e6cc7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1157,7 +1157,7 @@ OptionValue FallingDM 3, "Strife" } -OptionValue JumpCrouch +OptionValue JumpCrouchFreeLook { 0, "Default" 1, "Off" @@ -1189,9 +1189,9 @@ OptionMenu GameplayOptions Option "Degeneration", "sv_degeneration", "YesNo" Option "Allow Autoaim", "sv_noautoaim", "NoYes" Option "Allow Suicide", "sv_disallowsuicide", "NoYes" - Option "Allow jump", "sv_jump", "JumpCrouch" - Option "Allow crouch", "sv_crouch", "JumpCrouch" - Option "Allow freelook", "sv_nofreelook", "NoYes" + Option "Allow jump", "sv_jump", "JumpCrouchFreeLook" + Option "Allow crouch", "sv_crouch", "JumpCrouchFreeLook" + Option "Allow freelook", "sv_freelook", "JumpCrouchFreeLook" Option "Allow FOV", "sv_nofov", "NoYes" Option "Allow BFG aiming", "sv_nobfgaim", "NoYes" Option "Allow automap", "sv_noautomap", "NoYes" From 6d4eb7f62d73cd9ea7ea7630b5af3d588a45b5d6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 10:07:37 +0200 Subject: [PATCH 272/311] - changed handling of DF_NO_COOP_WEAPON_SPAWN dmflag so that weapons are not determined by class type but by a newly added flag WEAPONSPAWN, to allow CustomInventory replacements to act like weapons when being spawned. --- src/actor.h | 1 + src/p_mobj.cpp | 2 +- src/thingdef/thingdef_data.cpp | 1 + wadsrc/static/actors/shared/inventory.txt | 6 +++++- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/actor.h b/src/actor.h index 0dd20c14f..4c2952639 100644 --- a/src/actor.h +++ b/src/actor.h @@ -340,6 +340,7 @@ enum MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO) MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings. MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag + MF7_WEAPONSPAWN = 0x00000010, // subject to DF_NO_COOP_WEAPON_SPAWN dmflag // --- mobj.renderflags --- diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 076d106eb..cdc511d11 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4724,7 +4724,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // [RH] don't spawn extra weapons in coop if so desired if (multiplayer && !deathmatch && (dmflags & DF_NO_COOP_WEAPON_SPAWN)) { - if (i->IsDescendantOf (RUNTIME_CLASS(AWeapon))) + if (GetDefaultByType(i)->flags7 & MF7_WEAPONSPAWN) { if ((mthing->flags & (MTF_DEATHMATCH|MTF_SINGLE)) == MTF_DEATHMATCH) return NULL; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index bf0bf2e13..013415cc7 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -240,6 +240,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF7, NEVERTARGET, AActor, flags7), DEFINE_FLAG(MF7, NOTELESTOMP, AActor, flags7), DEFINE_FLAG(MF7, ALWAYSTELEFRAG, AActor, flags7), + DEFINE_FLAG(MF7, WEAPONSPAWN, AActor, flags7), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index ed113c4df..e293282b8 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -335,6 +335,7 @@ Actor Weapon : Inventory native Weapon.BobSpeed 1.0 Weapon.BobRangeX 1.0 Weapon.BobRangeY 1.0 + +WEAPONSPAWN States { LightDone: @@ -362,4 +363,7 @@ Actor WeaponHolder : Inventory native +INVENTORY.UNDROPPABLE } -Actor WeaponPiece : Inventory native {} +Actor WeaponPiece : Inventory native +{ + +WEAPONSPAWN +} From 993b6c30665f6ef11d5808dd574a824c07b58a63 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 28 Jul 2014 17:13:42 +0200 Subject: [PATCH 273/311] - fixed typo in FraggleScript item class list --- src/fragglescript/t_func.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 32d4909d4..4825fe06b 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -154,7 +154,7 @@ static const char * const ActorNames_init[]= "RocketAmmo", "RocketBox", "Cell", - "CellBox", + "CellPack", "Shell", "ShellBox", "Backpack", From 6af441c4d7509b1e194fbca053338940ed0c2db5 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 29 Jul 2014 11:06:02 +1200 Subject: [PATCH 274/311] Dup frames shouldn't adapt. Adapting during a dup frame caused jittery network performance (especially when using high dup values). The demoplayback check also didn't need to be there anyway. --- src/d_net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 0daf010c6..9ba6eefa0 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1276,7 +1276,7 @@ void NetUpdate (void) // listen for other packets GetPackets (); - if (!demoplayback) + if (!resendOnly) { // ideally nettics[0] should be 1 - 3 tics above lowtic // if we are consistantly slower, speed up time @@ -1323,7 +1323,7 @@ void NetUpdate (void) } oldnettics = nettics[0]; } - }// !demoplayback + } } From 4c6edd5e58e5b61b601d39a4aec271e1ec2d4747 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 26 Jul 2014 22:58:47 -0500 Subject: [PATCH 275/311] Add script array support to ZDoom --- src/p_acs.cpp | 421 +++++++++++++++++++++++++++++++++++++------------- src/p_acs.h | 79 +++++++++- 2 files changed, 389 insertions(+), 111 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 87e65cac3..baf573b99 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -122,10 +122,11 @@ FRandom pr_acs ("ACS"); struct CallReturn { - CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, unsigned int runaway) + CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway) : ReturnFunction(func), ReturnModule(module), ReturnLocals(locals), + ReturnArrays(arrays), ReturnAddress(pc), bDiscardResult(discard), EntryInstrCount(runaway) @@ -134,6 +135,7 @@ struct CallReturn ScriptFunction *ReturnFunction; FBehavior *ReturnModule; SDWORD *ReturnLocals; + ACSLocalArrays *ReturnArrays; int ReturnAddress; int bDiscardResult; unsigned int EntryInstrCount; @@ -1673,6 +1675,26 @@ void FBehavior::SerializeVarSet (FArchive &arc, SDWORD *vars, int max) } } +static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset) +{ + unsigned count = (LittleShort(((unsigned *)chunk)[1]) - 2) / 4; + int *sizes = (int *)((BYTE *)chunk + 10); + arrays->Count = count; + if (count > 0) + { + ACSLocalArrayInfo *info = new ACSLocalArrayInfo[count]; + arrays->Info = info; + for (unsigned i = 0; i < count; ++i) + { + info[i].Size = LittleLong(sizes[i]); + info[i].Offset = offset; + offset += info[i].Size; + } + } + // Return the new local variable size, with space for the arrays + return offset; +} + FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) { BYTE *object; @@ -1822,12 +1844,45 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) { DWORD *chunk; - Functions = FindChunk (MAKE_ID('F','U','N','C')); - if (Functions != NULL) + // Load functions + BYTE *funcs; + Functions = NULL; + funcs = FindChunk (MAKE_ID('F','U','N','C')); + if (funcs != NULL) { - NumFunctions = LittleLong(((DWORD *)Functions)[1]) / 8; - Functions += 8; + NumFunctions = LittleLong(((DWORD *)funcs)[1]) / 8; + funcs += 8; FunctionProfileData = new ACSProfileInfo[NumFunctions]; + Functions = new ScriptFunction[NumFunctions]; + for (i = 0; i < NumFunctions; ++i) + { + ScriptFunctionInFile *funcf = &((ScriptFunctionInFile *)funcs)[i]; + ScriptFunction *funcm = &Functions[i]; + funcm->ArgCount = funcf->ArgCount; + funcm->HasReturnValue = funcf->HasReturnValue; + funcm->ImportNum = funcf->ImportNum; + funcm->LocalCount = funcf->LocalCount; + funcm->Address = funcf->Address; + } + } + + // Load local arrays for functions + if (NumFunctions > 0) + { + for (chunk = (DWORD *)FindChunk(MAKE_ID('F','A','R','Y')); chunk != NULL; chunk = (DWORD *)NextChunk((BYTE *)chunk)) + { + int size = LittleLong(chunk[1]); + if (size >= 6) + { + unsigned int func_num = LittleShort(((WORD *)chunk)[4]); + if (func_num < (unsigned int)NumFunctions) + { + ScriptFunction *func = &Functions[func_num]; + // Unlike scripts, functions do not include their arg count in their local count. + func->LocalCount = ParseLocalArrayChunk(chunk, &func->LocalArrays, func->LocalCount + func->ArgCount) - func->ArgCount; + } + } + } } // Load JUMP points @@ -2135,6 +2190,11 @@ FBehavior::~FBehavior () delete[] ArrayStore; ArrayStore = NULL; } + if (Functions != NULL) + { + delete[] Functions; + Functions = NULL; + } if (FunctionProfileData != NULL) { delete[] FunctionProfileData; @@ -2302,6 +2362,21 @@ void FBehavior::LoadScriptsDirectory () } } + // Load script array sizes. (One chunk per script that uses arrays.) + for (scripts.b = FindChunk(MAKE_ID('S','A','R','Y')); scripts.dw != NULL; scripts.b = NextChunk(scripts.b)) + { + int size = LittleLong(scripts.dw[1]); + if (size >= 6) + { + int script_num = LittleShort(scripts.w[4]); + ScriptPtr *ptr = const_cast(FindScript(script_num)); + if (ptr != NULL) + { + ptr->VarCount = ParseLocalArrayChunk(scripts.b, &ptr->LocalArrays, ptr->VarCount); + } + } + } + // Load script names (if any) scripts.b = FindChunk(MAKE_ID('S','N','A','M')); if (scripts.dw != NULL) @@ -5460,14 +5535,50 @@ inline int getshort (int *&pc) return res; } +static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged) +{ + if (ranged) + { + capacity = STACK(1); + offset = STACK(2); + if (capacity < 1 || offset < 0) + { + sp -= 4; + return false; + } + sp -= 2; + } + else + { + capacity = INT_MAX; + offset = 0; + } + a = STACK(1); + offset += STACK(2); + sp -= 2; + return true; +} + int DLevelScript::RunScript () { DACSThinker *controller = DACSThinker::ActiveThinker; SDWORD *locals = localvars; + ACSLocalArrays noarrays; + ACSLocalArrays *localarrays = &noarrays; ScriptFunction *activeFunction = NULL; FRemapTable *translation = 0; int resultValue = 1; + if (InModuleScriptNumber >= 0) + { + ScriptPtr *ptr = activeBehavior->GetScriptPtr(InModuleScriptNumber); + assert(ptr != NULL); + if (ptr != NULL) + { + localarrays = &ptr->LocalArrays; + } + } + // Hexen truncates all special arguments to bytes (only when using an old MAPINFO and old ACS format const int specialargmask = ((level.flags2 & LEVEL2_HEXENHACK) && activeBehavior->GetFormat() == ACS_Old) ? 255 : ~0; @@ -5832,9 +5943,10 @@ int DLevelScript::RunScript () } sp += i; ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction, - activeBehavior, mylocals, pcd == PCD_CALLDISCARD, runaway); + activeBehavior, mylocals, localarrays, pcd == PCD_CALLDISCARD, runaway); sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int); pc = module->Ofs2PC (func->Address); + localarrays = &func->LocalArrays; activeFunction = func; activeBehavior = module; fmt = module->GetFormat(); @@ -5868,6 +5980,7 @@ int DLevelScript::RunScript () activeBehavior = ret->ReturnModule; fmt = activeBehavior->GetFormat(); locals = ret->ReturnLocals; + localarrays = ret->ReturnArrays; if (!ret->bDiscardResult) { Stack[sp++] = value; @@ -5966,6 +6079,11 @@ int DLevelScript::RunScript () sp--; break; + case PCD_ASSIGNSCRIPTARRAY: + localarrays->Set(locals, NEXTBYTE, STACK(2), STACK(1)); + sp -= 2; + break; + case PCD_ASSIGNMAPARRAY: activeBehavior->SetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(2), STACK(1)); sp -= 2; @@ -5997,6 +6115,10 @@ int DLevelScript::RunScript () PushToStack (ACS_GlobalVars[NEXTBYTE]); break; + case PCD_PUSHSCRIPTARRAY: + STACK(1) = localarrays->Get(locals, NEXTBYTE, STACK(1)); + break; + case PCD_PUSHMAPARRAY: STACK(1) = activeBehavior->GetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(1)); break; @@ -6029,6 +6151,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_ADDSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + STACK(1)); + sp -= 2; + } + break; + case PCD_ADDMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6074,6 +6204,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_SUBSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - STACK(1)); + sp -= 2; + } + break; + case PCD_SUBMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6119,6 +6257,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_MULSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) * STACK(1)); + sp -= 2; + } + break; + case PCD_MULMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6192,6 +6338,19 @@ int DLevelScript::RunScript () } break; + case PCD_DIVSCRIPTARRAY: + if (STACK(1) == 0) + { + state = SCRIPT_DivideBy0; + } + else + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) / STACK(1)); + sp -= 2; + } + break; + case PCD_DIVMAPARRAY: if (STACK(1) == 0) { @@ -6280,6 +6439,19 @@ int DLevelScript::RunScript () } break; + case PCD_MODSCRIPTARRAY: + if (STACK(1) == 0) + { + state = SCRIPT_ModulusBy0; + } + else + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) % STACK(1)); + sp -= 2; + } + break; + case PCD_MODMAPARRAY: if (STACK(1) == 0) { @@ -6341,6 +6513,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_ANDSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) & STACK(1)); + sp -= 2; + } + break; + case PCD_ANDMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6386,6 +6566,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_EORSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) ^ STACK(1)); + sp -= 2; + } + break; + case PCD_EORMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6431,6 +6619,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_ORSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) | STACK(1)); + sp -= 2; + } + break; + case PCD_ORMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6477,6 +6673,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_LSSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) << STACK(1)); + sp -= 2; + } + break; + case PCD_LSMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6522,6 +6726,14 @@ int DLevelScript::RunScript () sp--; break; + case PCD_RSSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(2); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) >> STACK(1)); + sp -= 2; + } + break; + case PCD_RSMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6564,6 +6776,14 @@ int DLevelScript::RunScript () ++ACS_GlobalVars[NEXTBYTE]; break; + case PCD_INCSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(1); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + 1); + sp--; + } + break; + case PCD_INCMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -6605,6 +6825,14 @@ int DLevelScript::RunScript () --ACS_GlobalVars[NEXTBYTE]; break; + case PCD_DECSCRIPTARRAY: + { + int a = NEXTBYTE, i = STACK(1); + localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - 1); + sp--; + } + break; + case PCD_DECMAPARRAY: { int a = *(activeBehavior->MapVars[NEXTBYTE]); @@ -7031,37 +7259,35 @@ scriptwait: } break; + // Print script character array + case PCD_PRINTSCRIPTCHARARRAY: + case PCD_PRINTSCRIPTCHRANGE: + { + int capacity, offset, a, c; + if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTSCRIPTCHRANGE)) + { + while (capacity-- && (c = localarrays->Get(locals, a, offset)) != '\0') + { + work += (char)c; + offset++; + } + } + } + break; + // [JB] Print map character array case PCD_PRINTMAPCHARARRAY: case PCD_PRINTMAPCHRANGE: { - int capacity, offset; - - if (pcd == PCD_PRINTMAPCHRANGE) + int capacity, offset, a, c; + if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTMAPCHRANGE)) { - capacity = STACK(1); - offset = STACK(2); - if (capacity < 1 || offset < 0) + while (capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0') { - sp -= 4; - break; + work += (char)c; + offset++; } - sp -= 2; } - else - { - capacity = 0x7FFFFFFF; - offset = 0; - } - - int a = *(activeBehavior->MapVars[STACK(1)]); - offset += STACK(2); - int c; - while(capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0') { - work += (char)c; - offset++; - } - sp-= 2; } break; @@ -7069,32 +7295,15 @@ scriptwait: case PCD_PRINTWORLDCHARARRAY: case PCD_PRINTWORLDCHRANGE: { - int capacity, offset; - if (pcd == PCD_PRINTWORLDCHRANGE) + int capacity, offset, a, c; + if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTWORLDCHRANGE)) { - capacity = STACK(1); - offset = STACK(2); - if (capacity < 1 || offset < 0) + while (capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0') { - sp -= 4; - break; + work += (char)c; + offset++; } - sp -= 2; } - else - { - capacity = 0x7FFFFFFF; - offset = 0; - } - - int a = STACK(1); - offset += STACK(2); - int c; - while(capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0') { - work += (char)c; - offset++; - } - sp-= 2; } break; @@ -7102,32 +7311,15 @@ scriptwait: case PCD_PRINTGLOBALCHARARRAY: case PCD_PRINTGLOBALCHRANGE: { - int capacity, offset; - if (pcd == PCD_PRINTGLOBALCHRANGE) + int capacity, offset, a, c; + if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTGLOBALCHRANGE)) { - capacity = STACK(1); - offset = STACK(2); - if (capacity < 1 || offset < 0) + while (capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0') { - sp -= 4; - break; + work += (char)c; + offset++; } - sp -= 2; } - else - { - capacity = 0x7FFFFFFF; - offset = 0; - } - - int a = STACK(1); - offset += STACK(2); - int c; - while(capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0') { - work += (char)c; - offset++; - } - sp-= 2; } break; @@ -8674,6 +8866,7 @@ scriptwait: } break; + case PCD_STRCPYTOSCRIPTCHRANGE: case PCD_STRCPYTOMAPCHRANGE: case PCD_STRCPYTOWORLDCHRANGE: case PCD_STRCPYTOGLOBALCHRANGE: @@ -8704,7 +8897,7 @@ scriptwait: break; } - for (int i = 0;i < STACK(1); i++) + for (int i = 0; i < STACK(1); i++) { if (! (*(lookup++))) { @@ -8715,43 +8908,55 @@ scriptwait: switch (pcd) { - case PCD_STRCPYTOMAPCHRANGE: - { - int a = STACK(5); - if (a < NUM_MAPVARS && a > 0 && - activeBehavior->MapVars[a]) - { - Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup); - } - } - break; - case PCD_STRCPYTOWORLDCHRANGE: - { - int a = STACK(5); + case PCD_STRCPYTOSCRIPTCHRANGE: + { + int a = STACK(5); - while (capacity-- > 0) - { - ACS_WorldArrays[a][index++] = *lookup; - if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0 - } - - Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied - } - break; - case PCD_STRCPYTOGLOBALCHRANGE: + while (capacity-- > 0) { - int a = STACK(5); - - while (capacity-- > 0) - { - ACS_GlobalArrays[a][index++] = *lookup; - if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0 - } - - Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied + localarrays->Set(locals, a, index++, *lookup); + if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0 } - break; - + + Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied + } + break; + case PCD_STRCPYTOMAPCHRANGE: + { + int a = STACK(5); + if (a < NUM_MAPVARS && a > 0 && + activeBehavior->MapVars[a]) + { + Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup); + } + } + break; + case PCD_STRCPYTOWORLDCHRANGE: + { + int a = STACK(5); + + while (capacity-- > 0) + { + ACS_WorldArrays[a][index++] = *lookup; + if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0 + } + + Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied + } + break; + case PCD_STRCPYTOGLOBALCHRANGE: + { + int a = STACK(5); + + while (capacity-- > 0) + { + ACS_GlobalArrays[a][index++] = *lookup; + if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0 + } + + Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied + } + break; } sp -= 5; } diff --git a/src/p_acs.h b/src/p_acs.h index ec41ab886..02544e367 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -144,6 +144,51 @@ struct ProfileCollector int Index; }; +struct ACSLocalArrayInfo +{ + unsigned int Size; + int Offset; +}; + +struct ACSLocalArrays +{ + unsigned int Count; + ACSLocalArrayInfo *Info; + + ACSLocalArrays() + { + Count = 0; + Info = NULL; + } + ~ACSLocalArrays() + { + if (Info != NULL) + { + delete[] Info; + Info = NULL; + } + } + + // Bounds-checking Set and Get for local arrays + void Set(int *locals, int arraynum, int arrayentry, int value) + { + if ((unsigned int)arraynum < Count && + (unsigned int)arrayentry < Info[arraynum].Size) + { + locals[Info[arraynum].Offset + arrayentry] = value; + } + } + int Get(int *locals, int arraynum, int arrayentry) + { + if ((unsigned int)arraynum < Count && + (unsigned int)arrayentry < Info[arraynum].Size) + { + return locals[Info[arraynum].Offset + arrayentry]; + } + return 0; + } +}; + // The in-memory version struct ScriptPtr { @@ -153,6 +198,7 @@ struct ScriptPtr BYTE ArgCount; WORD VarCount; WORD Flags; + ACSLocalArrays LocalArrays; ACSProfileInfo ProfileData; }; @@ -189,7 +235,7 @@ struct ScriptFlagsPtr WORD Flags; }; -struct ScriptFunction +struct ScriptFunctionInFile { BYTE ArgCount; BYTE LocalCount; @@ -198,6 +244,16 @@ struct ScriptFunction DWORD Address; }; +struct ScriptFunction +{ + BYTE ArgCount; + BYTE HasReturnValue; + BYTE ImportNum; + int LocalCount; + DWORD Address; + ACSLocalArrays LocalArrays; +}; + // Script types enum { @@ -285,7 +341,7 @@ private: BYTE *Chunks; ScriptPtr *Scripts; int NumScripts; - BYTE *Functions; + ScriptFunction *Functions; ACSProfileInfo *FunctionProfileData; int NumFunctions; ArrayInfo *ArrayStore; @@ -694,8 +750,25 @@ public: PCD_SCRIPTWAITNAMED, PCD_TRANSLATIONRANGE3, PCD_GOTOSTACK, + PCD_ASSIGNSCRIPTARRAY, + PCD_PUSHSCRIPTARRAY, + PCD_ADDSCRIPTARRAY, + PCD_SUBSCRIPTARRAY, + PCD_MULSCRIPTARRAY, + PCD_DIVSCRIPTARRAY, +/*370*/ PCD_MODSCRIPTARRAY, + PCD_INCSCRIPTARRAY, + PCD_DECSCRIPTARRAY, + PCD_ANDSCRIPTARRAY, + PCD_EORSCRIPTARRAY, + PCD_ORSCRIPTARRAY, + PCD_LSSCRIPTARRAY, + PCD_RSSCRIPTARRAY, + PCD_PRINTSCRIPTCHARARRAY, + PCD_PRINTSCRIPTCHRANGE, +/*380*/ PCD_STRCPYTOSCRIPTCHRANGE, -/*363*/ PCODE_COMMAND_COUNT +/*381*/ PCODE_COMMAND_COUNT }; // Some constants used by ACS scripts From 7280d278d90eaed2c9f216ce767d9e5202e7f18c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 28 Jul 2014 21:03:41 -0500 Subject: [PATCH 276/311] Fix VC2005 warning in F7ZFile::Open --- src/resourcefiles/file_7z.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp index 72e8d5f0e..21c11ed25 100644 --- a/src/resourcefiles/file_7z.cpp +++ b/src/resourcefiles/file_7z.cpp @@ -289,8 +289,8 @@ bool F7ZFile::Open(bool quiet) continue; } - nameUTF16.Resize(nameLength); - nameASCII.Resize(nameLength); + nameUTF16.Resize((unsigned)nameLength); + nameASCII.Resize((unsigned)nameLength); SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]); for (size_t c = 0; c < nameLength; ++c) { From cd28ad78a3258a6e54f9139e547741e12579cf55 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 28 Jul 2014 21:04:30 -0500 Subject: [PATCH 277/311] Used debug GME for debug ZDoom build with VC2005 solution --- zdoom.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zdoom.sln b/zdoom.sln index 988e84d68..11dc1b075 100644 --- a/zdoom.sln +++ b/zdoom.sln @@ -162,8 +162,8 @@ Global {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|Win32.Build.0 = Release|Win32 {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.ActiveCfg = Release|x64 {A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}.Release|x64.Build.0 = Release|x64 - {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.ActiveCfg = Release|Win32 - {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.Build.0 = Release|Win32 + {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.ActiveCfg = Debug|Win32 + {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|Win32.Build.0 = Debug|Win32 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.ActiveCfg = Release|x64 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Debug|x64.Build.0 = Release|x64 {9B465A9E-E5C7-4577-B559-3CA2F7AE7D96}.Release|Win32.ActiveCfg = Release|Win32 From ea7ba9dba3ed1301e52d4e6f982dc31874827b82 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 28 Jul 2014 23:15:50 -0500 Subject: [PATCH 278/311] Add per-actor friction - This is multiplied by the sector's friction. - This is intentionally not serialized yet, while awaiting feedback. --- src/actor.h | 1 + src/p_acs.cpp | 7 ++++++- src/p_map.cpp | 8 +++++++- src/p_spec.cpp | 18 ++---------------- src/p_spec.h | 19 +++++++++++++++++++ src/thingdef/thingdef_properties.cpp | 11 +++++++++++ wadsrc/static/actors/actor.txt | 1 + 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/actor.h b/src/actor.h index 4c2952639..783eb5408 100644 --- a/src/actor.h +++ b/src/actor.h @@ -906,6 +906,7 @@ public: fixed_t wallbouncefactor; // The bounce factor for walls can be different. int bouncecount; // Strife's grenades only bounce twice before exploding fixed_t gravity; // [GRB] Gravity factor + fixed_t Friction; int FastChaseStrafeCount; fixed_t pushfactor; int lastpush; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index baf573b99..16e511b23 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3605,7 +3605,8 @@ enum APROP_MeleeRange = 38, APROP_ViewHeight = 39, APROP_AttackZOffset = 40, - APROP_StencilColor = 41 + APROP_StencilColor = 41, + APROP_Friction = 42, }; // These are needed for ACS's APROP_RenderStyle @@ -3839,6 +3840,9 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) actor->SetShade(value); break; + case APROP_Friction: + actor->Friction = value; + default: // do nothing. break; @@ -3937,6 +3941,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); case APROP_StencilColor:return actor->fillcolor; + case APROP_Friction: return actor->Friction; default: return 0; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 45eb0d95c..db0c09202 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -554,7 +554,13 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) } } } - + + if (mo->Friction != FRACUNIT) + { + friction = clamp(FixedMul(friction, mo->Friction), 0, FRACUNIT); + movefactor = FrictionToMoveFactor(friction); + } + if (frictionfactor) *frictionfactor = movefactor; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 5068cd575..00ed322c0 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1990,26 +1990,12 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) friction = (0x1EB8*amount)/0x80 + 0xD001; // killough 8/28/98: prevent odd situations - if (friction > FRACUNIT) - friction = FRACUNIT; - if (friction < 0) - friction = 0; + friction = clamp(friction, 0, FRACUNIT); // The following check might seem odd. At the time of movement, // the move distance is multiplied by 'friction/0x10000', so a // higher friction value actually means 'less friction'. - - // [RH] Twiddled these values so that velocity on ice (with - // friction 0xf900) is the same as in Heretic/Hexen. - if (friction >= ORIG_FRICTION) // ice -// movefactor = ((0x10092 - friction)*(0x70))/0x158; - movefactor = ((0x10092 - friction) * 1024) / 4352 + 568; - else - movefactor = ((friction - 0xDB34)*(0xA))/0x80; - - // killough 8/28/98: prevent odd situations - if (movefactor < 32) - movefactor = 32; + movefactor = FrictionToMoveFactor(friction); for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; ) { diff --git a/src/p_spec.h b/src/p_spec.h index 245c699d7..dc0eb3646 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -172,6 +172,25 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags); void P_SetSectorFriction (int tag, int amount, bool alterFlag); +inline fixed_t FrictionToMoveFactor(fixed_t friction) +{ + fixed_t movefactor; + + // [RH] Twiddled these values so that velocity on ice (with + // friction 0xf900) is the same as in Heretic/Hexen. + if (friction >= ORIG_FRICTION) // ice +// movefactor = ((0x10092 - friction)*(0x70))/0x158; + movefactor = ((0x10092 - friction) * 1024) / 4352 + 568; + else + movefactor = ((friction - 0xDB34)*(0xA))/0x80; + + // killough 8/28/98: prevent odd situations + if (movefactor < 32) + movefactor = 32; + + return movefactor; +} + void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); // diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 81452c7b0..b5fdc8e42 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1297,6 +1297,17 @@ DEFINE_PROPERTY(gravity, F, Actor) defaults->gravity = i; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(friction, F, Actor) +{ + PROP_FIXED_PARM(i, 0); + + if (i < 0) I_Error ("Friction must not be negative."); + defaults->Friction = i; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 1eb00440c..501933f04 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -18,6 +18,7 @@ ACTOR Actor native //: Thinker FloatSpeed 4 FloatBobPhase -1 // randomly initialize by default Gravity 1 + Friction 1 DamageFactor 1.0 PushFactor 0.25 WeaveIndexXY 0 From f3d8edb4d87e2cfbf9f998172929cc82f7cccb41 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 19:45:04 -0500 Subject: [PATCH 279/311] Fixed: No sprites were loaded for Build maps --- src/p_buildmap.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index f2fd7b0bf..a93ba6465 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -687,6 +687,8 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, { int count = 0; + memset(mapthings, 0, sizeof(*mapthings)*numsprites); + for (int i = 0; i < numsprites; ++i) { mapthings[count].thingid = 0; @@ -699,6 +701,9 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].special = 0; mapthings[count].gravity = FRACUNIT; + mapthings[count].RenderStyle = STYLE_Count; + mapthings[count].alpha = -1; + mapthings[count].health = -1; if (xsprites != NULL && sprites[i].lotag == 710) { // Blood ambient sound From 02e7c56c820d464286dbad216a987904c49d1b93 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 20:22:45 -0500 Subject: [PATCH 280/311] Move SpriteFrames.Clear() from R_InitSprites to FTextureManager::Init - Fixed: Blood sprite rotations were overwritten by the Doom sprite rotations. --- src/r_data/sprites.cpp | 2 -- src/textures/texturemanager.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index c1e59c415..ebf4699da 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -925,8 +925,6 @@ void R_InitSprites () numskins++; } - SpriteFrames.Clear(); - // [RH] Do some preliminary setup if (skins != NULL) delete [] skins; skins = new FPlayerSkin[numskins]; diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index a79769c3d..b8256bc65 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -964,6 +964,7 @@ void FTextureManager::SortTexturesByType(int start, int end) void FTextureManager::Init() { DeleteAll(); + SpriteFrames.Clear(); // Init Build Tile data if it hasn't been done already if (BuildTileFiles.Size() == 0) CountBuildTiles (); FTexture::InitGrayMap(); From 00854dd09e72cf11dddb1a0042baf02513f1c240 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 20:42:17 -0500 Subject: [PATCH 281/311] Don't reopen the reader for encrypted maps - Fixed: Memory leak when loading Blood maps. --- src/p_setup.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index a6462f31c..f84862ef0 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -312,7 +312,6 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) if (map->Encrypted) { // If it's encrypted, then it's a Blood file, presumably a map. - map->MapLumps[0].Reader = map->file = Wads.ReopenLumpNum(lump_name); if (!P_IsBuildMap(map)) { delete map; From d602b272b50ec4b2f25569aaf0d79763aea07dfe Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 20:46:20 -0500 Subject: [PATCH 282/311] Never cache nodes for Build maps --- src/p_glnodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 899005ffa..15b97b9e6 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1014,7 +1014,7 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) // Building nodes in debug is much slower so let's cache them only if cachetime is 0 buildtime = 0; #endif - if (gl_cachenodes && buildtime/1000.f >= gl_cachetime) + if (level.maptype != MAPTYPE_BUILD && gl_cachenodes && buildtime/1000.f >= gl_cachetime) { DPrintf("Caching nodes\n"); CreateCachedNodes(map); From 4296e9caa2558bfc27aa5baa2dd1d7b36e8dfb87 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 20:47:01 -0500 Subject: [PATCH 283/311] Fix typo in comment --- src/p_buildmap.cpp | 2 +- src/s_advsound.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index a93ba6465..defaf6970 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -708,7 +708,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, if (xsprites != NULL && sprites[i].lotag == 710) { // Blood ambient sound mapthings[count].args[0] = xsprites[i].Data3; - // I am totally guessing abount the volume level. 50 seems to be a pretty + // I am totally guessing about the volume level. 50 seems to be a pretty // typical value for Blood's standard maps, so I assume it's 100-based. mapthings[count].args[1] = xsprites[i].Data4; mapthings[count].args[2] = xsprites[i].Data1; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index c2d567f29..67fc544dc 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -2231,7 +2231,7 @@ void AAmbientSound::BeginPlay () // // AmbientSound :: Activate // -// Starts playing a sound (or does nothing of the sound is already playing). +// Starts playing a sound (or does nothing if the sound is already playing). // //========================================================================== From e0e00c4f8c0f964f01c3ae9f48a3b097581bf882 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 20:56:20 -0500 Subject: [PATCH 284/311] Fixed: None of the Blood ambient sounds were registered correctly --- src/s_advsound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 67fc544dc..d424be45d 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1433,7 +1433,7 @@ static void S_AddBloodSFX (int lumpnum) ambient->periodmax = 0; ambient->volume = 1; ambient->attenuation = 1; - ambient->sound = name; + ambient->sound = FSoundID(sfxnum); } } From 449a17c2f4e33f64e1f9f81e1d9d68634085fd19 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 21:09:29 -0500 Subject: [PATCH 285/311] Correctly assign the sample rate for all Blood SFX formats - Blood can do 44100 Hz sounds! --- src/s_advsound.cpp | 19 +++++++++++-------- src/s_sound.cpp | 2 +- src/s_sound.h | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index d424be45d..5b2e4e7c1 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -511,8 +511,6 @@ int S_AddSoundLump (const char *logicalname, int lump) newsfx.LimitRange = 256*256; newsfx.bRandomHeader = false; newsfx.bPlayerReserve = false; - newsfx.bForce11025 = false; - newsfx.bForce22050 = false; newsfx.bLoadRAW = false; newsfx.bPlayerCompat = false; newsfx.b16bit = false; @@ -520,6 +518,7 @@ int S_AddSoundLump (const char *logicalname, int lump) newsfx.bSingular = false; newsfx.bTentative = false; newsfx.bPlayerSilent = false; + newsfx.RawRate = 0; newsfx.link = sfxinfo_t::NO_LINK; newsfx.Rolloff.RolloffType = ROLLOFF_Doom; newsfx.Rolloff.MinDistance = 0; @@ -1414,13 +1413,17 @@ static void S_AddBloodSFX (int lumpnum) { const char *name = Wads.GetLumpFullName(lumpnum); sfxnum = S_AddSound(name, rawlump); - if (sfx->Format == 5) - { - S_sfx[sfxnum].bForce22050 = true; + if (sfx->Format < 5 || sfx->Format > 12) + { // [0..4] + invalid formats + S_sfx[sfxnum].RawRate = 11025; } - else // I don't know any other formats for this - { - S_sfx[sfxnum].bForce11025 = true; + else if (sfx->Format < 9) + { // [5..8] + S_sfx[sfxnum].RawRate = 22050; + } + else + { // [9..12] + S_sfx[sfxnum].RawRate = 44100; } S_sfx[sfxnum].bLoadRAW = true; S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index d1c313967..32a245675 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1334,7 +1334,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) if (sfx->bLoadRAW) { len = Wads.LumpLength (sfx->lumpnum); - frequency = (sfx->bForce22050 ? 22050 : 11025); + frequency = sfx->RawRate; } else { diff --git a/src/s_sound.h b/src/s_sound.h index 346e51ce1..da8bf3cbc 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -49,8 +49,6 @@ struct sfxinfo_t WORD bRandomHeader:1; WORD bPlayerReserve:1; - WORD bForce11025:1; - WORD bForce22050:1; WORD bLoadRAW:1; WORD bPlayerCompat:1; WORD b16bit:1; @@ -59,6 +57,8 @@ struct sfxinfo_t WORD bTentative:1; WORD bPlayerSilent:1; // This player sound is intentionally silent. + WORD RawRate; // Sample rate to use when bLoadRAW is true + int LoopStart; // -1 means no specific loop defined unsigned int link; From a922ae04cca88ad5a46df12784f4965fdb7e24d0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Jul 2014 21:39:05 -0500 Subject: [PATCH 286/311] Use Blood player starts - Blood's maps use thing types, much like Doom's, so getting its player starts is easy. There's no need to synthesize a start from the editor position like with other Build maps. --- src/p_buildmap.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index defaf6970..63e38c616 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -16,6 +16,7 @@ #include "p_setup.h" #include "g_level.h" #include "r_data/colormaps.h" +#include "gi.h" // MACROS ------------------------------------------------------------------ @@ -361,9 +362,8 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * // BUILD info from the map we need. (Sprites are ignored.) LoadSectors (bsec); LoadWalls (bwal, numWalls, bsec); - *mapthings = new FMapThing[numsprites + 1]; - CreateStartSpot ((fixed_t *)infoBlock, *mapthings); - *numspr = 1 + LoadSprites (bspr, xspr, numsprites, bsec, *mapthings + 1); + *mapthings = new FMapThing[numsprites]; + *numspr = LoadSprites (bspr, xspr, numsprites, bsec, *mapthings); delete[] bsec; delete[] bwal; @@ -713,9 +713,19 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, mapthings[count].args[1] = xsprites[i].Data4; mapthings[count].args[2] = xsprites[i].Data1; mapthings[count].args[3] = xsprites[i].Data2; - mapthings[count].args[4] = 0; mapthings[count].type = 14065; } + else if (xsprites != NULL && sprites[i].lotag == 1) + { // Blood player start + if (xsprites[i].Data1 < 4) + mapthings[count].type = 1 + xsprites[i].Data1; + else + mapthings[count].type = gameinfo.player5start + xsprites[i].Data1 - 4; + } + else if (xsprites != NULL && sprites[i].lotag == 2) + { // Bloodbath start + mapthings[count].type = 11; + } else { if (sprites[i].cstat & (16|32|32768)) continue; From e55e7b9a38134be754b8b5b6d05477818a646b12 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 18:22:33 -0500 Subject: [PATCH 287/311] Don't weed out wall and floor sprites when spawning Build sprites --- src/p_buildmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 63e38c616..54bf92527 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -728,7 +728,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, } else { - if (sprites[i].cstat & (16|32|32768)) continue; + if (sprites[i].cstat & 32768) continue; if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; mapthings[count].type = 9988; From 4cf468452cea77af73cfe137c890192f87172d51 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 19:15:08 -0500 Subject: [PATCH 288/311] Remove slopetype from line_t. - Recomputing it in the only two places where it's used is trivial, so it's basically a waste of space to precompute it. --- src/m_bbox.cpp | 39 ++++++++++++++++++--------------------- src/p_map.cpp | 36 ++++++++++++++++++------------------ src/p_setup.cpp | 7 ------- src/po_man.cpp | 12 ------------ src/r_defs.h | 13 ------------- 5 files changed, 36 insertions(+), 71 deletions(-) diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index 6d3a5b744..199da8d68 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -54,19 +54,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const int p1; int p2; - switch (ld->slopetype) - { - case ST_HORIZONTAL: - p1 = m_Box[BOXTOP] > ld->v1->y; - p2 = m_Box[BOXBOTTOM] > ld->v1->y; - if (ld->dx < 0) - { - p1 ^= 1; - p2 ^= 1; - } - break; - - case ST_VERTICAL: + if (ld->dx == 0) + { // ST_VERTICAL p1 = m_Box[BOXRIGHT] < ld->v1->x; p2 = m_Box[BOXLEFT] < ld->v1->x; if (ld->dy < 0) @@ -74,18 +63,26 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const p1 ^= 1; p2 ^= 1; } - break; - - case ST_POSITIVE: + } + else if (ld->dy == 0) + { // ST_HORIZONTAL: + p1 = m_Box[BOXTOP] > ld->v1->y; + p2 = m_Box[BOXBOTTOM] > ld->v1->y; + if (ld->dx < 0) + { + p1 ^= 1; + p2 ^= 1; + } + } + else if ((ld->dy ^ ld->dx) >= 0) + { // ST_POSITIVE: p1 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXTOP], ld); p2 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXBOTTOM], ld); - break; - - case ST_NEGATIVE: - default: // Just to assure GCC that p1 and p2 really do get initialized + } + else + { // ST_NEGATIVE: p1 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXTOP], ld); p2 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXBOTTOM], ld); - break; } return (p1 == p2) ? p1 : -1; diff --git a/src/p_map.cpp b/src/p_map.cpp index db0c09202..96b2b6195 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2244,24 +2244,8 @@ void FSlide::HitSlideLine (line_t* ld) slidemo->z <= slidemo->floorz && P_GetFriction (slidemo, NULL) > ORIG_FRICTION; - if (ld->slopetype == ST_HORIZONTAL) - { - if (icyfloor && (abs(tmymove) > abs(tmxmove))) - { - tmxmove /= 2; // absorb half the velocity - tmymove = -tmymove/2; - if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) - { - S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! - } - } - else - tmymove = 0; // no more movement in the Y direction - return; - } - - if (ld->slopetype == ST_VERTICAL) - { + if (ld->dx == 0) + { // ST_VERTICAL if (icyfloor && (abs(tmxmove) > abs(tmymove))) { tmxmove = -tmxmove/2; // absorb half the velocity @@ -2276,6 +2260,22 @@ void FSlide::HitSlideLine (line_t* ld) return; } + if (ld->dy == 0) + { // ST_HORIZONTAL + if (icyfloor && (abs(tmymove) > abs(tmxmove))) + { + tmxmove /= 2; // absorb half the velocity + tmymove = -tmymove/2; + if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) + { + S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! + } + } + else + tmymove = 0; // no more movement in the Y direction + return; + } + // The wall is angled. Bounce if the angle of approach is // phares // less than 45 degrees. // phares diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f84862ef0..a6dbca868 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1888,13 +1888,6 @@ void P_AdjustLine (line_t *ld) ld->dx = v2->x - v1->x; ld->dy = v2->y - v1->y; - if (ld->dx == 0) - ld->slopetype = ST_VERTICAL; - else if (ld->dy == 0) - ld->slopetype = ST_HORIZONTAL; - else - ld->slopetype = ((ld->dy ^ ld->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE; - if (v1->x < v2->x) { ld->bbox[BOXLEFT] = v1->x; diff --git a/src/po_man.cpp b/src/po_man.cpp index d844133b0..e19acc53a 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -950,18 +950,6 @@ void FPolyObj::UpdateBBox () // Update the line's slopetype line->dx = line->v2->x - line->v1->x; line->dy = line->v2->y - line->v1->y; - if (!line->dx) - { - line->slopetype = ST_VERTICAL; - } - else if (!line->dy) - { - line->slopetype = ST_HORIZONTAL; - } - else - { - line->slopetype = ((line->dy ^ line->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE; - } } CalcCenter(); } diff --git a/src/r_defs.h b/src/r_defs.h index 2e9c0876b..dd2136508 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -882,18 +882,6 @@ struct side_t FArchive &operator<< (FArchive &arc, side_t::part &p); -// -// Move clipping aid for LineDefs. -// -enum slopetype_t -{ - ST_HORIZONTAL, - ST_VERTICAL, - ST_POSITIVE, - ST_NEGATIVE -}; - - struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 @@ -908,7 +896,6 @@ struct line_t side_t *sidedef[2]; //DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided fixed_t bbox[4]; // bounding box, for the extent of the LineDef. - slopetype_t slopetype; // To aid move clipping. sector_t *frontsector, *backsector; int validcount; // if == validcount, already checked int locknumber; // [Dusk] lock number for special From bbc3b69a7c227e319bbaf24bbccd9350ef4136ed Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 19:43:36 -0500 Subject: [PATCH 289/311] Remove polymost stuff - Maybe it will be back someday, but it's been essentially dead for nearly 10 years, so don't hold your breath. --- src/CMakeLists.txt | 1 - src/d_main.cpp | 24 +- src/r_main.cpp | 29 +- src/r_polymost.cpp | 1599 ------------------------------------------ src/r_polymost.h | 55 -- src/r_swrenderer.cpp | 3 - zdoom.vcproj | 8 - 7 files changed, 3 insertions(+), 1716 deletions(-) delete mode 100644 src/r_polymost.cpp delete mode 100644 src/r_polymost.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1564c9e60..1444f1cf3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -896,7 +896,6 @@ add_executable( zdoom WIN32 r_drawt.cpp r_main.cpp r_plane.cpp - r_polymost.cpp r_segs.cpp r_sky.cpp r_things.cpp diff --git a/src/d_main.cpp b/src/d_main.cpp index 90391433a..ab33bfaec 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -108,10 +108,6 @@ #include "r_renderer.h" #include "p_local.h" -#ifdef USE_POLYMOST -#include "r_polymost.h" -#endif - EXTERN_CVAR(Bool, hud_althud) void DrawHUD(); @@ -186,9 +182,6 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO) } } -#ifdef USE_POLYMOST -CVAR(Bool, testpolymost, false, 0) -#endif CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO); CVAR (Int, wipetype, 1, CVAR_ARCHIVE); CVAR (Int, snd_drawoutput, 0, 0); @@ -282,10 +275,6 @@ void D_ProcessEvents (void) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event - #ifdef USE_POLYMOST - if (testpolymost) - Polymost_Responder (ev); - #endif G_Responder (ev); } } @@ -307,9 +296,6 @@ void D_PostEvent (const event_t *ev) } events[eventhead] = *ev; if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling -#ifdef USE_POLYMOST - && !testpolymost -#endif ) { if (Button_Mlook.bDown || freelook) @@ -743,15 +729,7 @@ void D_Display () hw2d = false; -#ifdef USE_POLYMOST - if (testpolymost) - { - drawpolymosttest(); - C_DrawConsole(hw2d); - M_Drawer(); - } - else -#endif + { unsigned int nowtime = I_FPSTime(); TexMan.UpdateAnimations(nowtime); diff --git a/src/r_main.cpp b/src/r_main.cpp index a726bc714..bc3c4c7c0 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -72,8 +72,6 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- void R_SpanInitData (); -void RP_RenderBSPNode (void *node); -bool RP_SetupFrame (bool backside); void R_DeinitSprites(); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -94,14 +92,12 @@ extern "C" int fuzzviewheight; static float CurrentVisibility = 8.f; static fixed_t MaxVisForWall; static fixed_t MaxVisForFloor; -static bool polyclipped; extern bool r_showviewer; bool r_dontmaplines; // PUBLIC DATA DEFINITIONS ------------------------------------------------- CVAR (String, r_viewsize, "", CVAR_NOSET) -CVAR (Int, r_polymost, 0, 0) CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE) fixed_t r_BaseVisibility; @@ -612,14 +608,6 @@ void R_SetupFreelook() } } -void R_SetupPolymost() -{ - if (r_polymost) - { - polyclipped = RP_SetupFrame (false); - } -} - //========================================================================== // // R_EnterMirror @@ -812,11 +800,8 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) } // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function PO_LinkToSubsectors(); - if (r_polymost < 2) - { - R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output. - R_3D_ResetClip(); // reset clips (floor/ceiling) - } + R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output. + R_3D_ResetClip(); // reset clips (floor/ceiling) camera->renderflags = savedflags; WallCycles.Unclock(); @@ -843,16 +828,6 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) MaskedCycles.Unclock(); NetUpdate (); - - if (r_polymost) - { - RP_RenderBSPNode (nodes + numnodes - 1); - if (polyclipped) - { - RP_SetupFrame (true); - RP_RenderBSPNode (nodes + numnodes - 1); - } - } } WallMirrors.Clear (); interpolator.RestoreInterpolations (); diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp deleted file mode 100644 index e7963faa2..000000000 --- a/src/r_polymost.cpp +++ /dev/null @@ -1,1599 +0,0 @@ -/************************************************************************************************** -"POLYMOST" code written by Ken Silverman -Ken Silverman's official web site: http://www.advsys.net/ken -This file has been modified (severely) from Ken Silverman's original release - -Motivation: -When 3D Realms released the Duke Nukem 3D source code, I thought somebody would do a OpenGL or -Direct3D port. Well, after a few months passed, I saw no sign of somebody working on a true -hardware-accelerated port of Build, just people saying it wasn't possible. Eventually, I realized -the only way this was going to happen was for me to do it myself. First, I needed to port Build to -Windows. I could have done it myself, but instead I thought I'd ask my Australian buddy, Jonathon -Fowler, if he would upgrade his Windows port to my favorite compiler (MSVC) - which he did. Once -that was done, I was ready to start the "POLYMOST" project. - -About: -This source file is basically a complete rewrite of the entire rendering part of the Build engine. -There are small pieces in ENGINE.C to activate this code, and other minor hacks in other source -files, but most of it is in here. If you're looking for polymost-related code in the other source -files, you should find most of them by searching for either "polymost" or "rendmode". Speaking of -rendmode, there are now 4 rendering modes in Build: - - rendmode 0: The original code I wrote from 1993-1997 - rendmode 1: Solid-color rendering: my debug code before I did texture mapping - rendmode 2: Software rendering before I started the OpenGL code (Note: this is just a quick - hack to make testing easier - it's not optimized to my usual standards!) - rendmode 3: The OpenGL code - -The original Build engine did hidden surface removal by using a vertical span buffer on the tops -and bottoms of walls. This worked nice back in the day, but it it's not suitable for a polygon -engine. So I decided to write a brand new hidden surface removal algorithm - using the same idea -as the original Build - but one that worked with vectors instead of already rasterized data. - -Brief history: -06/20/2000: I release Build Source code -04/01/2003: 3D Realms releases Duke Nukem 3D source code -10/04/2003: Jonathon Fowler gets his Windows port working in Visual C -10/04/2003: I start writing POLYMOST.BAS, a new hidden surface removal algorithm for Build that - works on a polygon level instead of spans. -10/16/2003: Ported POLYMOST.BAS to C inside JonoF KenBuild's ENGINE.C; later this code was split - out of ENGINE.C and put in this file, POLYMOST.C. -12/10/2003: Started OpenGL code for POLYMOST (rendmode 3) -12/23/2003: 1st public release -01/01/2004: 2nd public release: fixed stray lines, status bar, mirrors, sky, and lots of other bugs. - ----------------------------------------------------------------------------------------------------- - -Todo list (in approximate chronological order): - -High priority: - * BOTH: Do accurate software sorting/chopping for sprites: drawing in wrong order is bad :/ - * BOTH: Fix hall of mirrors near "zenith". Call polymost_drawrooms twice? - * OPENGL: drawmapview() - -Low priority: - * SOFT6D: Do back-face culling of sprites during up/down/tilt transformation (top of drawpoly) - * SOFT6D: Fix depth shading: use saturation&LUT - * SOFT6D: Optimize using hyperbolic mapping (similar to KUBE algo) - * SOFT6D: Slab6-style voxel sprites. How to accelerate? :/ - * OPENGL: KENBUILD: Write flipping code for floor mirrors - * BOTH: KENBUILD: Parallaxing sky modes 1&2 - * BOTH: Masked/1-way walls don't clip correctly to sectors of intersecting ceiling/floor slopes - * BOTH: Editart x-center is not working correctly with Duke's camera/turret sprites - * BOTH: Get rid of horizontal line above Duke full-screen status bar - * BOTH: Combine ceilings/floors into a single triangle strip (should lower poly count by 2x) - * BOTH: Optimize/clean up texture-map setup equations - -**************************************************************************************************/ - -#include -#include -#include -#include "doomtype.h" -#include "r_polymost.h" -#include "c_cvars.h" -#include "c_dispatch.h" -#include "r_main.h" -#include "r_draw.h" -#include "templates.h" -#include "r_sky.h" -#include "g_level.h" -#include "r_bsp.h" -#include "v_palette.h" -#include "v_font.h" -#include "v_video.h" -#include "r_data/colormaps.h" - -EXTERN_CVAR (Int, r_polymost) - -#define SCISDIST 1.0 //1.0: Close plane clipping distance - -static double gyxscale, gxyaspect, gviewxrange, ghalfx, grhalfxdown10, grhalfxdown10x, ghoriz; -static double gcosang, gsinang, gcosang2, gsinang2; -static double gchang, gshang, gctang, gstang; -//static float gtang = 0.0; -CVAR (Float, gtang, 0, 0); -double guo, gux, guy; //Screen-based texture mapping parameters -double gvo, gvx, gvy; -double gdo, gdx, gdy; - -#ifdef _MSC_VER -#pragma warning (disable:4244) -#endif - -PolyClipper::PolyClipper () - : vsps (&EmptyList) -{ - UsedList.Next = UsedList.Prev = &UsedList; -} - -PolyClipper::~PolyClipper () -{ - vspgroup *probe = vsps.NextGroup; - while (probe != NULL) - { - vspgroup *next = probe->NextGroup; - delete probe; - probe = next; - } -} - -PolyClipper::vspgroup::vspgroup (vsptype *sentinel) -{ - int i; - - NextGroup = NULL; - vsp[0].Prev = sentinel; - vsp[0].Next = &vsp[1]; - for (i = 1; i < GROUP_SIZE-1; ++i) - { - vsp[i].Next = &vsp[i+1]; - vsp[i].Prev = &vsp[i-1]; - } - vsp[i].Next = sentinel; - vsp[i].Prev = &vsp[i-1]; - sentinel->Next = &vsp[0]; - sentinel->Prev = &vsp[i]; -} - - /*Init viewport boundary (must be 4 point convex loop): - // (px[0],py[0]).----.(px[1],py[1]) - // / \ - // / \ - // (px[3],py[3]).--------------.(px[2],py[2]) - */ -void PolyClipper::InitMosts (double *px, double *py, int n) -{ - int i, j, k, imin; - int vcnt; - vsptype *vsp[8]; - - EmptyAll (); - vcnt = 1; // 0 is dummy solid node - - if (n < 3) return; - imin = (px[1] < px[0]); - for(i=n-1;i>=2;i--) if (px[i] < px[imin]) imin = i; - - vsp[0] = &UsedList; - vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[imin]; - vsp[vcnt]->Cy[0] = vsp[vcnt]->Fy[0] = py[imin]; - vsp[vcnt]->CTag = vsp[vcnt]->FTag = 1; - vcnt++; - i = imin+1; if (i >= n) i = 0; - j = imin-1; if (j < 0) j = n-1; - do - { - if (px[i] < px[j]) - { - if ((vcnt > 1) && (px[i] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = py[i]; - k = j+1; if (k >= n) k = 0; - //(px[k],py[k]) - //(px[i],?) - //(px[j],py[j]) - vsp[vcnt]->Fy[0] = (px[i]-px[k])*(py[j]-py[k])/(px[j]-px[k]) + py[k]; - if (vcnt > 1) - { - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag; - } - vcnt++; - i++; if (i >= n) i = 0; - } - else if (px[j] < px[i]) - { - if ((vcnt > 1) && (px[j] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[j]; - vsp[vcnt]->Fy[0] = py[j]; - k = i-1; if (k < 0) k = n-1; - //(px[k],py[k]) - //(px[j],?) - //(px[i],py[i]) - vsp[vcnt]->Cy[0] = (px[j]-px[k])*(py[i]-py[k])/(px[i]-px[k]) + py[k]; - if (vcnt > 1) - { - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag; - } - vcnt++; - j--; if (j < 0) j = n-1; - } - else - { - if ((vcnt > 1) && (px[i] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = py[i]; - vsp[vcnt]->Fy[0] = py[j]; - if (vcnt > 1) - { - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - } - vcnt++; - i++; if (i >= n) i = 0; if (i == j) break; - j--; if (j < 0) j = n-1; - } - } while (i != j); - if (px[i] > vsp[vcnt-1]->X) - { - vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = vsp[vcnt]->Fy[0] = py[i]; - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - vcnt++; - } - - assert (vcnt < 8); - - vsp[vcnt-1]->CTag = vsp[vcnt-1]->FTag = vcnt-1; - for(i=0;iCy[1] = vsp[i+1]->Cy[0]; //vsp[i]->CTag = i; - vsp[i]->Fy[1] = vsp[i+1]->Fy[0]; //vsp[i]->FTag = i; - vsp[i]->Next = vsp[i+1]; vsp[i]->Prev = vsp[i-1]; - } - vsp[vcnt-1]->Next = &UsedList; UsedList.Prev = vsp[vcnt-1]; - GTag = vcnt; -} - -void PolyClipper::EmptyAll () -{ - if (UsedList.Next != &UsedList) - { - if (EmptyList.Next != &EmptyList) - { - // Move the used list to the start of the empty list - UsedList.Prev->Next = EmptyList.Next; - EmptyList.Next = UsedList.Next; - UsedList.Next->Prev = &EmptyList; - } - else - { - // The empty list is empty, so we can just move the - // used list to the empty list. - EmptyList.Next = UsedList.Next; - EmptyList.Prev = UsedList.Prev; - } - UsedList.Next = UsedList.Prev = &UsedList; - } -} - -void PolyClipper::AddGroup () -{ - vspgroup *group = new vspgroup (&EmptyList); - group->NextGroup = vsps.NextGroup; - vsps.NextGroup = group; -} - -PolyClipper::vsptype *PolyClipper::GetVsp () -{ - vsptype *vsp; - - if (EmptyList.Next == &EmptyList) - { - AddGroup (); - } - vsp = EmptyList.Next; - EmptyList.Next = vsp->Next; - vsp->Next->Prev = &EmptyList; - return vsp; -} - -void PolyClipper::FreeVsp (vsptype *vsp) -{ - vsp->Next->Prev = vsp->Prev; - vsp->Prev->Next = vsp->Next; - - vsp->Next = EmptyList.Next; - vsp->Next->Prev = vsp; - vsp->Prev = &EmptyList; - EmptyList.Next = vsp; -} - -PolyClipper::vsptype *PolyClipper::vsinsaft (vsptype *i) -{ - vsptype *r; - - // Get an element from the empty list - r = GetVsp (); - - *r = *i; // Copy i to r - - // Insert r after i - r->Prev = i; - r->Next = i->Next; - i->Next->Prev = r; - i->Next = r; - - return r; -} - -bool PolyClipper::TestVisibleMost (float x0, float x1) -{ - vsptype *i, *newi; - - for (i = UsedList.Next; i != &UsedList; i = newi) - { - newi = i->Next; - if ((x0 < newi->X) && (i->X < x1) && (i->CTag >= 0)) return true; - } - return false; -} - -int PolyClipper::DoMost (float x0, float y0, float x1, float y1, pmostcallbacktype callback, void *callbackdata) -{ - double dpx[4], dpy[4]; - float f, slop, dx0, dx1, nx, nx0, ny0, nx1, ny1; - double dx, d, n, t; - float spx[4], spy[4], cy[2], cv[2]; - int j, k, z, scnt, dir, spt[4]; - vsptype *vsp, *nvsp, *vcnt = NULL, *ni; - int did = 1; - - if (x0 < x1) - { - dir = 1; //clip dmost (floor) - y0 -= .01f; y1 -= .01f; - } - else - { - if (x0 == x1) return 0; - f = x0; x0 = x1; x1 = f; - f = y0; y0 = y1; y1 = f; - dir = 0; //clip umost (ceiling) - //y0 += .01f; y1 += .01f; //necessary? - } - - slop = (y1-y0)/(x1-x0); - for (vsp = UsedList.Next; vsp != &UsedList; vsp = nvsp) - { - nvsp = vsp->Next; nx0 = vsp->X; nx1 = nvsp->X; - if ((x0 >= nx1) || (nx0 >= x1) || (vsp->CTag <= 0)) continue; - dx = nx1-nx0; - cy[0] = vsp->Cy[0]; cv[0] = vsp->Cy[1]-cy[0]; - cy[1] = vsp->Fy[0]; cv[1] = vsp->Fy[1]-cy[1]; - - scnt = 0; - - //Test if left edge requires split (x0,y0) (nx0,cy(0)), - if ((x0 > nx0) && (x0 < nx1)) - { - t = (x0-nx0)*cv[dir] - (y0-cy[dir])*dx; - if (((!dir) && (t < 0)) || ((dir) && (t > 0))) - { spx[scnt] = x0; spy[scnt] = y0; spt[scnt] = -1; scnt++; } - } - - //Test for intersection on umost (j == 0) and dmost (j == 1) - for(j=0;j<2;j++) - { - d = (y0-y1)*dx - (x0-x1)*cv[j]; - n = (y0-cy[j])*dx - (x0-nx0)*cv[j]; - if ((fabsf(n) <= fabsf(d)) && (d*n >= 0) && (d != 0)) - { - t = n/d; nx = (x1-x0)*t + x0; - if ((nx > nx0) && (nx < nx1)) - { - spx[scnt] = nx; spy[scnt] = (y1-y0)*t + y0; - spt[scnt] = j; scnt++; - } - } - } - - //Nice hack to avoid full sort later :) - if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2])) - { - f = spx[scnt-1]; spx[scnt-1] = spx[scnt-2]; spx[scnt-2] = f; - f = spy[scnt-1]; spy[scnt-1] = spy[scnt-2]; spy[scnt-2] = f; - j = spt[scnt-1]; spt[scnt-1] = spt[scnt-2]; spt[scnt-2] = j; - } - - //Test if right edge requires split - if ((x1 > nx0) && (x1 < nx1)) - { - t = (x1-nx0)*cv[dir] - (y1-cy[dir])*dx; - if (((!dir) && (t < 0)) || ((dir) && (t > 0))) - { spx[scnt] = x1; spy[scnt] = y1; spt[scnt] = -1; scnt++; } - } - - vsp->Tag = nvsp->Tag = -1; - for(z = 0; z <= scnt; z++, vsp = vcnt) - { - if (z < scnt) - { - vcnt = vsinsaft(vsp); - t = (spx[z]-nx0)/dx; - vsp->Cy[1] = t*cv[0] + cy[0]; - vsp->Fy[1] = t*cv[1] + cy[1]; - vcnt->X = spx[z]; - vcnt->Cy[0] = vsp->Cy[1]; - vcnt->Fy[0] = vsp->Fy[1]; - vcnt->Tag = spt[z]; - } - - ni = vsp->Next; if (ni == &UsedList) continue; //this 'if' fixes many bugs! - dx0 = vsp->X; if (x0 > dx0) continue; - dx1 = ni->X; if (x1 < dx1) continue; - ny0 = (dx0-x0)*slop + y0; - ny1 = (dx1-x0)*slop + y0; - - // dx0 dx1 - // ³ ³ - //---------------------------- - // t0+=0 t1+=0 - // vsp[i].cy[0] vsp[i].cy[1] - //============================ - // t0+=1 t1+=3 - //============================ - // vsp[i].fy[0] vsp[i].fy[1] - // t0+=2 t1+=6 - // - // ny0 ? ny1 ? - - k = 1+3; - if ((vsp->Tag == 0) || (ny0 <= vsp->Cy[0]+.01)) k--; - if ((vsp->Tag == 1) || (ny0 >= vsp->Fy[0]-.01)) k++; - if ((ni->Tag == 0) || (ny1 <= vsp->Cy[1]+.01)) k -= 3; - if ((ni->Tag == 1) || (ny1 >= vsp->Fy[1]-.01)) k += 3; - - if (!dir) - { - switch(k) - { - case 1: case 2: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx0; dpy[2] = ny0; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Cy[0] = ny0; vsp->CTag = GTag; break; - case 3: case 6: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = ny1; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Cy[1] = ny1; vsp->CTag = GTag; break; - case 4: case 5: case 7: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = ny1; - dpx[3] = dx0; dpy[3] = ny0; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->Cy[0] = ny0; vsp->Cy[1] = ny1; vsp->CTag = GTag; break; - case 8: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->CTag = vsp->FTag = -1; break; - default: did = 0; break; - } - } - else - { - switch(k) - { - case 7: case 6: - dpx[0] = dx0; dpy[0] = ny0; - dpx[1] = dx1; dpy[1] = vsp->Fy[1]; - dpx[2] = dx0; dpy[2] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Fy[0] = ny0; vsp->FTag = GTag; break; - case 5: case 2: - dpx[0] = dx0; dpy[0] = vsp->Fy[0]; - dpx[1] = dx1; dpy[1] = ny1; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Fy[1] = ny1; vsp->FTag = GTag; break; - case 4: case 3: case 1: - dpx[0] = dx0; dpy[0] = ny0; - dpx[1] = dx1; dpy[1] = ny1; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->Fy[0] = ny0; vsp->Fy[1] = ny1; vsp->FTag = GTag; break; - case 0: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->CTag = vsp->FTag = -1; break; - default: did = 0; break; - } - } - } - } - - GTag++; - - //Combine neighboring vertical strips with matching collinear top&bottom edges - //This prevents x-splits from propagating through the entire scan - vsp = UsedList.Next; - while (vsp->Next != &UsedList) - { - ni = vsp->Next; - if ((vsp->Cy[0] >= vsp->Fy[0]) && (vsp->Cy[1] >= vsp->Fy[1])) - { vsp->CTag = vsp->FTag = -1; } - if ((vsp->CTag == ni->CTag) && (vsp->FTag == ni->FTag)) - { vsp->Cy[1] = ni->Cy[1]; vsp->Fy[1] = ni->Fy[1]; FreeVsp (ni); } - else vsp = ni; - } - return did; -} - -#include "d_event.h" -static int pmx, pmy; -static int pt, px0, py0, px1, py1; -static struct polypt { float x, y; } polypts[80]; -static BYTE polysize[32]; -static int numpoly, polypt; -PolyClipper TestPoly; - -void drawline2d (float x1, float y1, float x2, float y2, BYTE col) -{ - float dx, dy, fxresm1, fyresm1, f; - long i, x, y, xi, yi, xup16, yup16; - - //Always draw lines in same direction - if ((y2 > y1) || ((y2 == y1) && (x2 > x1))) { f = x1; x1 = x2; x2 = f; f = y1; y1 = y2; y2 = f; } - - dx = x2-x1; dy = y2-y1; if ((dx == 0) && (dy == 0)) return; - fxresm1 = (float)RenderTarget->GetWidth()-.5; fyresm1 = (float)RenderTarget->GetHeight()-.5; - if (x1 >= fxresm1) { if (x2 >= fxresm1) return; y1 += (fxresm1-x1)*dy/dx; x1 = fxresm1; } - else if (x1 < 0) { if (x2 < 0) return; y1 += ( 0-x1)*dy/dx; x1 = 0; } - if (x2 >= fxresm1) { y2 += (fxresm1-x2)*dy/dx; x2 = fxresm1; } - else if (x2 < 0) { y2 += ( 0-x2)*dy/dx; x2 = 0; } - if (y1 >= fyresm1) { if (y2 >= fyresm1) return; x1 += (fyresm1-y1)*dx/dy; y1 = fyresm1; } - else if (y1 < 0) { if (y2 < 0) return; x1 += ( 0-y1)*dx/dy; y1 = 0; } - if (y2 >= fyresm1) { x2 += (fyresm1-y2)*dx/dy; y2 = fyresm1; } - else if (y2 < 0) { x2 += ( 0-y2)*dx/dy; y2 = 0; } - - dx = x2-x1; dy = y2-y1; - i = (long)(MAX(fabsf(dx)+1,fabsf(dy)+1)); f = 65536.f/((float)i); - x = (long)(x1*65536.f)+32768; xi = (long)(dx*f); xup16 = (RenderTarget->GetWidth()<<16); - y = (long)(y1*65536.f)+32768; yi = (long)(dy*f); yup16 = (RenderTarget->GetHeight()<<16); - do - { - if (((unsigned long)x < (unsigned long)xup16) && ((unsigned long)y < (unsigned long)yup16)) - *(ylookup[y>>16]+(x>>16)+dc_destorg) = col; - x += xi; y += yi; i--; - } while (i >= 0); -} - -static int maskhack; - -void fillconvpoly (float x[], float y[], int n, int col, int bcol) -{ - int mini = y[0] >= y[1], maxi = 1 - mini; - int i, j, y2, oz, z, yy, zz, ncol; - float area, xi, xx; - static int lastx[MAXHEIGHT+2]; - - for (z = 2; z < n; ++z) - { - if (y[z] < y[mini]) mini = z; - if (y[z] > y[maxi]) maxi = z; - } - - area = 0; zz = n - 1; - for (z = 0; z < n; ++z) - { - area += (x[zz] - x[z]) * (y[z] + y[zz]); zz = z; - } - if (area <= 0) return; - - i = maxi; y2 = int(y[i]); - do - { - j = i + 1; if (j == n) j = 0; - yy = int(ceilf(y[j])); - if (yy < 0) yy = 0; - if (yy < y2) - { - xi = (x[j] - x[i]) / (y[j] - y[i]); - xx = (y2 - y[j]) * xi + x[j]; - if (y2 >= RenderTarget->GetHeight()) { xx = xx - (y2 - RenderTarget->GetHeight() + 1)*xi; y2 = RenderTarget->GetHeight()-1; } - for (; y2 >= yy; --y2) - { - lastx[y2] = MAX (0, int(ceilf(xx))); xx = xx - xi; - } - } - i = j; - } while (i != mini); - if (y2 == yy) lastx[yy] = lastx[yy+1]; - do - { - j = i + 1; if (j == n) j = 0; - y2 = int(y[j]); - if (y2 >= RenderTarget->GetHeight()) y2 = RenderTarget->GetHeight()-1; - if (y2 > yy) - { - xi = (x[j] - x[i]) / (y[j] - y[i]); - xx = (yy - y[i]) * xi + x[i]; - if (yy < 0) { xx = xx - xi*yy; yy = 0; } - ncol = col; if (yy & 1) ncol = ncol ^ maskhack; - for (; yy <= y2; ++yy) - { - //drawline2d(lastx[yy], yy, int(ceilf(xx)), yy, ncol); xx = xx + xi; - int xxx = MIN(RenderTarget->GetWidth(), int(ceilf(xx))); - if (yy < RenderTarget->GetHeight() && lastx[yy] < xxx) memset(RenderTarget->GetBuffer()+yy*RenderTarget->GetPitch()+lastx[yy], ncol, xxx-lastx[yy]); - xx = xx + xi; - ncol = ncol ^ maskhack; - } - } - i = j; - } while (i != maxi); - - if (col != bcol) - { - oz = n - 1; - for (z = 0; z < n; ++z) - { - drawline2d(x[oz], y[oz], x[z], y[z], bcol); - oz = z; - } - } -} - -void drawtri(float x0, float y0, float x1, float y1, float x2, float y2, int col, int bcol) -{ - float x[3], y[3]; - x[0] = x0; y[0] = y0; - x[1] = x1; y[1] = y1; - x[2] = x2; y[2] = y2; - fillconvpoly(x, y, 3, col, bcol); -} - -void drawquad(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, int col, int bcol) -{ - float x[4], y[4]; - x[0] = x0; y[0] = y0; - x[1] = x1; y[1] = y1; - x[2] = x2; y[2] = y2; - x[3] = x3; y[3] = y3; - fillconvpoly(x, y, 4, col, bcol); // 2 triangles - if (col != bcol) - { - if (fabsf(y0-y2) < fabsf(y1-y3)) - drawline2d(x0,y0,x2,y2,bcol); - else - drawline2d(x1,y1,x3,y3,bcol); - } -} - -void printnum(int x, int y, int num) -{ - char foo[16]; mysnprintf (foo, countof(foo), "%d", num); - RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo, TAG_DONE); -} - -void drawpolymosttest() -{ - float cx0 = 0, cy0 = 0, fx0 = 0, fy0 = 0; - int ccol, fcol; - PolyClipper::vsptype *vsp, *ovsp = &TestPoly.UsedList, *nvsp; - - fcol = 0; ccol = 0; - - RenderTarget->Clear(0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), 0, 0); - for (vsp = ovsp->Next; vsp->Next != &TestPoly.UsedList; ovsp = vsp, vsp = nvsp) - { - nvsp = vsp->Next; - if (vsp->CTag == -1 && vsp->FTag == -1) - { // Hide spans that have been clipped away - vsp->Cy[0] = vsp->Cy[1] = vsp->Fy[0] = vsp->Fy[1] = RenderTarget->GetHeight()/2; - } - - if (vsp->CTag != ovsp->CTag) cx0 = vsp->X, cy0 = vsp->Cy[0]; - if (vsp->CTag != nvsp->CTag) - { // fill the ceiling region - maskhack = 0x18; - drawquad(cx0, 0, nvsp->X, 0, nvsp->X, vsp->Cy[1], cx0, cy0, ccol, ccol); - maskhack = 0; ccol ^= 0x18; - printnum(int(cx0 + nvsp->X) / 2, 2, vsp->CTag); - } - - if(vsp->FTag != ovsp->FTag) fx0 = vsp->X, fy0 = vsp->Fy[0]; - if(vsp->FTag != nvsp->FTag) - { // fill the floor region - maskhack = 0x78; - drawquad(fx0, fy0+1, nvsp->X, vsp->Fy[1]+1, nvsp->X, RenderTarget->GetHeight(), fx0, RenderTarget->GetHeight(), fcol, fcol); - maskhack = 0; fcol ^= 0x78; - printnum(int(fx0 + nvsp->X) / 2, RenderTarget->GetHeight()-10, vsp->FTag); - } - - // fill the unclipped middle region - drawquad(vsp->X, vsp->Cy[0], nvsp->X, vsp->Cy[1], nvsp->X, vsp->Fy[1], vsp->X, vsp->Fy[0], 0xC4, 0xE6); - } - - int x = (pmx + 3) & ~7, y = (pmy + 3) & ~7; - - drawline2d (x - 3, y, x + 3, y, 30); - drawline2d (x, y - 3, x, y + 3, 30); - printnum ( 0, 20, x); - printnum (50, 20, y); - - if (pt > 0 && px0 != px1) - { - if (px0 < px1) - { - drawline2d (px0, py0, px0, RenderTarget->GetHeight()-1, 47); - drawline2d (px1, py1, px1, RenderTarget->GetHeight()-1, 47); - } - else - { - drawline2d (px0, py0, px0, 0, 47); - drawline2d (px1, py1, px1, 0, 47); - } - drawline2d (px0, py0, px1, py1, 47); - } - if (pt == 2) - { - int i = 0; - for (x = 0; x < numpoly; ++x) - { - if (polysize[x] == 3) - { - drawtri (polypts[i ].x, polypts[i ].y, - polypts[i+1].x, polypts[i+1].y, - polypts[i+2].x, polypts[i+2].y, 0x7f, 0x9f); - i += 3; - } - else - { - drawquad (polypts[i ].x, polypts[i ].y, - polypts[i+1].x, polypts[i+1].y, - polypts[i+2].x, polypts[i+2].y, - polypts[i+3].x, polypts[i+3].y, 0x7f, 0x9f); - i += 4; - } - } - } -} - -CCMD(initpolymosttest) -{ - double px[4], py[4]; - int test = 0; - - if (argv.argc() > 1) - test = atoi(argv[1]); - - // Box - px[0] = px[3] = 0; - px[1] = px[2] = screen->GetWidth(); - py[0] = py[1] = screen->GetHeight()/4; - py[2] = py[3] = screen->GetHeight()*3/4; - - switch (test) - { - case 1: // Shorter top edge - px[0] = px[1]/6; - px[1] = px[1]*5/6; - break; - - case 2: // Shorter bottom edge - px[3] = px[2]/6; - px[2] = px[2]*5/6; - break; - - case 3: // Shorter left edge - py[0] = screen->GetHeight()*3/8; - py[3] = screen->GetHeight()*5/8; - break; - - case 4: // Shorter right edge - py[1] = screen->GetHeight()*3/8; - py[2] = screen->GetHeight()*5/8; - break; - - case 5: - px[0] = -1.0048981460288360/2+50; py[0] = -1.0/2+50; - px[1] = 643.00492866407262/2+50; py[1] = -1.0/2+50; - px[2] = 643.00492866407262/2+50; py[2] = 483/2+50; - px[3] = -1.0048981460288360/2+50; py[3] = 483/2+50; - break; - } - TestPoly.InitMosts (px, py, 4); - pmx = screen->GetWidth()/2; - pmy = screen->GetHeight()/2; - pt = 0; -} - -static void testpolycallback (double *dpx, double *dpy, int n, void *foo) -{ - if (numpoly == sizeof(polysize)) return; - if (size_t(polypt + n) > countof(polypts)) return; - polysize[numpoly++] = n; - for (int i = 0; i < n; ++i) - { - polypts[polypt + i].x = dpx[i]; - polypts[polypt + i].y = dpy[i]; - } - polypt += n; -} - -void Polymost_Responder (event_t *ev) -{ - if (ev->type == EV_Mouse && pt < 2) - { - pmx = clamp (pmx + ev->x, 0, screen->GetWidth()-1); - pmy = clamp (pmy - ev->y, 0, screen->GetHeight()-1); - int x = (pmx + 3) & ~7, y = (pmy + 3) & ~7; - if (pt == 0) px0 = x, py0 = y; - if (pt <= 1) px1 = x, py1 = y; - } - else if (ev->type == EV_KeyDown && ev->data1 == KEY_MOUSE1) - { - if (pt == 0) pt = 1; else pt = 0; - } - else if (ev->type == EV_KeyUp && ev->data1 == KEY_MOUSE1) - { - if (pt == 1) { if (px0 != px1) pt++; else pt--; } - if (pt == 2) - { - numpoly = polypt = 0; - TestPoly.DoMost (px0, py0, px1, py1, testpolycallback, NULL); - } - } -} - - - - - - - - -extern fixed_t WallSZ1, WallSZ2, WallTX1, WallTX2, WallTY1, WallTY2, WallCX1, WallCX2, WallCY1, WallCY2; -extern int WallSX1, WallSX2; -extern float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; -extern fixed_t rw_backcz1, rw_backcz2; -extern fixed_t rw_backfz1, rw_backfz2; -extern fixed_t rw_frontcz1, rw_frontcz2; -extern fixed_t rw_frontfz1, rw_frontfz2; -extern fixed_t rw_offset; -extern bool rw_markmirror; -extern bool rw_havehigh; -extern bool rw_havelow; -extern bool markfloor; -extern bool markceiling; -extern FTexture *toptexture; -extern FTexture *bottomtexture; -extern FTexture *midtexture; -extern bool rw_mustmarkfloor, rw_mustmarkceiling; -extern void R_NewWall(bool); -//extern void R_GetExtraLight (int *light, const secplane_t &plane, FExtraLight *el); -extern int doorclosed; -extern int viewpitch; -#include "p_lnspec.h" - -PolyClipper Mosts; -static bool drawback; - -bool RP_SetupFrame (bool backside) -{ - double ox, oy, oz, ox2, oy2, oz2, r, px[6], py[6], pz[6], px2[6], py2[6], pz2[6], sx[6], sy[6]; - int i, j, n, n2; - - drawback = backside; - if (backside) - { - viewangle += ANGLE_180; - viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; - viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; - viewtansin = FixedMul (FocalTangent, viewsin); - viewtancos = FixedMul (FocalTangent, viewcos); - } - //Polymost supports true look up/down :) Here, we convert horizon to angle. - //gchang&gshang are cos&sin of this angle (respectively) -// gyxscale = ((double)xdimenscale)/131072.0; - gyxscale = double(InvZtoScale)/65536.0;///131072.0/320.0; -// gxyaspect = ((double)xyaspect*(double)viewingrange)*(5.0/(65536.0*262144.0)); -// gviewxrange = ((double)viewingrange)*((double)xdimen)/(32768.0*128.0); - gcosang = double(viewcos)/65536.0; - gsinang = double(viewsin)/65536.0; - gcosang2 = gcosang*double(FocalTangent)/65536.0; - gsinang2 = gsinang*double(FocalTangent)/65536.0; - ghalfx = (double)viewwidth*0.5; grhalfxdown10 = 1.0/(((double)ghalfx)*1024); - - //global cos/sin height angle - angle_t pitch = (angle_t)viewpitch; - if (backside) pitch = ANGLE_180 - pitch; - - gshang = double(finesine[pitch>>ANGLETOFINESHIFT])/65536.0; - gchang = double(finecosine[pitch>>ANGLETOFINESHIFT])/65536.0; - ghoriz = double(viewheight)*0.5; - - //global cos/sin tilt angle - gctang = cos(gtang); - gstang = sin(gtang); - if (fabs(gstang) < .001) //This hack avoids nasty precision bugs in domost() - { gstang = 0; if (gctang > 0) gctang = 1.0; else gctang = -1.0; } - - // Generate viewport trapezoid - px[0] = px[3] = 0-1; px[1] = px[2] = viewwidth+3; - py[0] = py[1] = 0-1; py[2] = py[3] = viewheight+3; n = 4; - for(i=0;i= n) j = 0; - if (pz[i] >= SCISDIST/16) { px2[n2] = px[i]; py2[n2] = py[i]; pz2[n2] = pz[i]; n2++; } - if ((pz[i] >= SCISDIST/16) != (pz[j] >= SCISDIST/16)) - { - clipped = true; - r = (SCISDIST/16-pz[i])/(pz[j]-pz[i]); - px2[n2] = (px[j]-px[i])*r + px[i]; - py2[n2] = (py[j]-py[i])*r + py[i]; - pz2[n2] = SCISDIST/16; - if (backside) py2[n2] -= r; - n2++; - } - } - if (n2 < 3) { return true; } - for(i=0;i= (dpx[2]-dpx[1])*(dpy[0]-dpy[1])) return; //for triangle - } - else - { - f = 0; //f is area of polygon / 2 - for(i=n-2,j=n-1,k=0;klinedef == NULL) return; - - //Offset&Rotate 3D coordinates to screen 3D space - x = double(line->v1->x - viewx); y = double(line->v1->y - viewy); - xp0 = x*gsinang - y*gcosang; - yp0 = x*gcosang2 + y*gsinang2; - x = double(line->v2->x - viewx); y = double(line->v2->y - viewy); - xp1 = x*gsinang - y*gcosang; - yp1 = x*gcosang2 + y*gsinang2; - - oxp0 = xp0; oyp0 = yp0; - - //Clip to close parallel-screen plane - // [RH] Why oh why does clipping the left side of the wall against - // a small SCISDIST not work for me? Strictly speaking, it's not - // the clipping of the left side that's the problem, because if I - // rotate the view 180 degrees so the right side of the wall is on - // the left of the screen, then clipping the right side becomes - // problematic. -#define WCLIPDIST (SCISDIST*256.0) - if (yp0 < WCLIPDIST) - { - if (yp1 < WCLIPDIST) return; - t0 = (WCLIPDIST-yp0)/(yp1-yp0); - xp0 = (xp1-xp0)*t0+xp0; - yp0 = WCLIPDIST; - nx0 = (line->v2->x - line->v1->x)*t0 + line->v1->x; - ny0 = (line->v2->y - line->v1->y)*t0 + line->v1->y; - } - else { t0 = 0.f; nx0 = line->v1->x; ny0 = line->v1->y; } - if (yp1 < WCLIPDIST) - { - t1 = (WCLIPDIST-oyp0)/(yp1-oyp0); - xp1 = (xp1-oxp0)*t1+oxp0; - yp1 = WCLIPDIST; - nx1 = (line->v2->x - line->v1->x)*t1 + line->v1->x; - ny1 = (line->v2->y - line->v1->y)*t1 + line->v1->y; - } - else { t1 = 1.f; nx1 = line->v2->x; ny1 = line->v2->y; } - - ryp0 = 1.0/yp0; ryp1 = 1.0/yp1; - - //Generate screen coordinates for front side of wall - x0 = ghalfx*xp0*ryp0 + ghalfx; - x1 = ghalfx*xp1*ryp1 + ghalfx; - if (x1 <= x0) return; - - ryp0 *= gyxscale; ryp1 *= gyxscale; - fixed_t fnx0 = fixed_t(nx0), fny0 = fixed_t(ny0); - fixed_t fnx1 = fixed_t(nx1), fny1 = fixed_t(ny1); - - fcz0 = frontsector->ceilingplane.ZatPoint (fnx0, fny0); - ffz0 = frontsector->floorplane.ZatPoint (fnx0, fny0); - fcz1 = frontsector->ceilingplane.ZatPoint (fnx1, fny1); - ffz1 = frontsector->floorplane.ZatPoint (fnx1, fny1); - bool cc = (t0>0 && x1 > 0); - cy0 = ghoriz - double(fcz0 - viewz) * ryp0; - fy0 = ghoriz - double(ffz0 - viewz) * ryp0; - cy1 = ghoriz - double(fcz1 - viewz) * ryp1; - fy1 = ghoriz - double(ffz1 - viewz) * ryp1; - -/* - tx1 = line->v1->x - viewx; - tx2 = line->v2->x - viewx; - ty1 = line->v1->y - viewy; - ty2 = line->v2->y - viewy; - // Reject lines not facing viewer - if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) - return; - - WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - - WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swap (WallTY1, WallTY2); - } - - if (WallTX1 >= -WallTY1) - { - if (WallTX1 > WallTY1) return; // left edge is off the right side - if (WallTY1 == 0) return; - WallSX1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; - if (WallTX1 >= 0) WallSX1 = MIN (viewwidth, WallSX1+1); // fix for signed divide - WallSZ1 = WallTY1; - } - else - { - if (WallTX2 < -WallTY2) return; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; - if (den == 0) return; - WallSX1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); - } - - if (WallSZ1 < 32) - return; - - if (WallTX2 <= WallTY2) - { - if (WallTX2 < -WallTY2) return; // right edge is off the left side - if (WallTY2 == 0) return; - WallSX2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS; - if (WallTX2 >= 0) WallSX2 = MIN (viewwidth, WallSX2+1); // fix for signed divide - WallSZ2 = WallTY2; - } - else - { - if (WallTX1 > WallTY1) return; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; - if (den == 0) return; - WallSX2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); - } - - if (WallSZ2 < 32 || WallSX2 <= WallSX1) - return; - - if (WallSX1 > WindowRight || WallSX2 < WindowLeft) - return; - if (line->linedef == NULL) - { - return; - } -*/ - - vertex_t *v1, *v2; - - v1 = line->linedef->v1; - v2 = line->linedef->v2; - - if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) - { // The seg is the entire wall. - if (MirrorFlags & RF_XFLIP) - { - WallUoverZorg = (float)WallTX2 * WallTMapScale; - WallUoverZstep = (float)(-WallTY2) * 32.f; - WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale; - WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f; - } - else - { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; - } - } - else - { // The seg is only part of the wall. - if (line->linedef->sidedef[0] != line->sidedef) - { - swapvalues (v1, v2); - } - tx1 = v1->x - viewx; - tx2 = v2->x - viewx; - ty1 = v1->y - viewy; - ty2 = v2->y - viewy; - - fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - fullx1 = -fullx1; - fullx2 = -fullx2; - } - - WallUoverZorg = (float)fullx1 * WallTMapScale; - WallUoverZstep = (float)(-fully1) * 32.f; - WallInvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallInvZstep = (float)(fully2 - fully1) * 32.f; - } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; - - backsector = line->backsector; - - rw_mustmarkfloor = rw_mustmarkceiling = false; - rw_havehigh = rw_havelow = false; - - // Single sided line? - if (backsector == NULL) - { - solid = true; - } - else - { - // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water - backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true); - - doorclosed = 0; // killough 4/16/98 - - bcz0 = backsector->ceilingplane.ZatPoint (fnx0, fny0); - bfz0 = backsector->floorplane.ZatPoint (fnx0, fny0); - bcz1 = backsector->ceilingplane.ZatPoint (fnx1, fny1); - bfz1 = backsector->floorplane.ZatPoint (fnx1, fny1); - ocy0 = ghoriz - double(bcz0 - viewz) * ryp0; - ofy0 = ghoriz - double(bfz0 - viewz) * ryp0; - ocy1 = ghoriz - double(bcz1 - viewz) * ryp1; - ofy1 = ghoriz - double(bfz1 - viewz) * ryp1; - - if (fcz0 > bcz0 || fcz1 > bcz1) - { - rw_havehigh = true; - } - if (ffz0 < bfz0 ||ffz1 < bfz1) - { - rw_havelow = true; - } - - // Closed door. - if ((bcz0 <= ffz0 && bcz1 <= ffz1) || (bfz0 >= fcz0 && bfz1 >= fcz1)) - { - solid = true; - } - else if ( - (backsector->GetTexture(sector_t::ceiling) != skyflatnum || - frontsector->GetTexture(sector_t::ceiling) != skyflatnum) - - // if door is closed because back is shut: - && bcz0 <= bfz0 && bcz1 <= bfz1 - - // preserve a kind of transparent door/lift special effect: - && bcz0 >= fcz0 && bcz1 >= fcz1 - - && ((bfz0 <= ffz0 && bfz1 <= ffz1) || line->sidedef->GetTexture(side_t::bottom).isValid())) - { - // killough 1/18/98 -- This function is used to fix the automap bug which - // showed lines behind closed doors simply because the door had a dropoff. - // - // It assumes that Doom has already ruled out a door being closed because - // of front-back closure (e.g. front floor is taller than back ceiling). - - // This fixes the automap floor height bug -- killough 1/18/98: - // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c - doorclosed = true; - solid = true; - } - else if (frontsector->ceilingplane != backsector->ceilingplane || - frontsector->floorplane != backsector->floorplane) - { - // Window. - solid = false; - } - else if (backsector->lightlevel != frontsector->lightlevel - || backsector->GetTexture(sector_t::floor) != frontsector->GetTexture(sector_t::floor) - || backsector->GetTexture(sector_t::ceiling) != frontsector->GetTexture(sector_t::ceiling) - || curline->sidedef->GetTexture(side_t::mid).isValid() - - // killough 3/7/98: Take flats offsets into account: - || backsector->GetXOffset(sector_t::floor) != frontsector->GetXOffset(sector_t::floor) - || backsector->GetYOffset(sector_t::floor) != frontsector->GetYOffset(sector_t::floor) - || backsector->GetXOffset(sector_t::ceiling) != frontsector->GetXOffset(sector_t::ceiling) - || backsector->GetYOffset(sector_t::ceiling) != frontsector->GetYOffset(sector_t::ceiling) - - || backsector->GetPlaneLight(sector_t::floor) != frontsector->GetPlaneLight(sector_t::floor) - || backsector->GetPlaneLight(sector_t::ceiling) != frontsector->GetPlaneLight(sector_t::ceiling) - || backsector->GetFlags(sector_t::floor) != frontsector->GetFlags(sector_t::floor) - || backsector->GetFlags(sector_t::ceiling) != frontsector->GetFlags(sector_t::ceiling) - - // [RH] Also consider colormaps - || backsector->ColorMap != frontsector->ColorMap - - // [RH] and scaling - || backsector->GetXScale(sector_t::floor) != frontsector->GetXScale(sector_t::floor) - || backsector->GetYScale(sector_t::floor) != frontsector->GetYScale(sector_t::floor) - || backsector->GetXScale(sector_t::ceiling) != frontsector->GetXScale(sector_t::ceiling) - || backsector->GetYScale(sector_t::ceiling) != frontsector->GetYScale(sector_t::ceiling) - - // [RH] and rotation - || backsector->GetAngle(sector_t::floor) != frontsector->GetAngle(sector_t::floor) - || backsector->GetAngle(sector_t::ceiling) != frontsector->GetAngle(sector_t::ceiling) - ) - { - solid = false; - } - else - { - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, identical light levels - // on both sides, and no middle texture. - return; - } - } - - if (line->linedef->special == Line_Horizon) - { - // Be aware: Line_Horizon does not work properly with sloped planes - fcz1 = fcz0 = ffz1 = ffz0 = viewz; - markceiling = markfloor = true; - } - - // must be fixed in case the polymost renderer ever gets developed further! - rw_offset = line->sidedef->GetTextureXOffset(side_t::mid); - - R_NewWall (false); - if (rw_markmirror) - { - WallMirrors.Push (ds_p - drawsegs); - } - - // render it - if (markceiling) - { - Mosts.DoMost (x1, cy1, x0, cy0, wireframe, !cc||1?(void *)0xc3:(void*)0xca); - } - if (markfloor) - { - Mosts.DoMost (x0, fy0, x1, fy1, wireframe, (void *)0xd3); - } - if (midtexture) - { // one sided line - //if(line->linedef-lines==1)Printf ("%g %g %g -> %g %g %g : %g %g -> %g %g\n", yp0, x0, fy0, yp1, x1, fy1, nx0, ny0, nx1, ny1); - if (viewpitch > 0) - Mosts.DoMost (x0, -10000, x1, -10000, wireframe, !cc||1?(void *)0x83:(void*)0x93); - else - Mosts.DoMost (x1, 10000, x0, 10000, wireframe, !cc||1?(void *)0x83:(void*)0x93); - } - else - { // two sided line - if (toptexture != NULL && toptexture->UseType != FTexture::TEX_Null) - { // top wall - Mosts.DoMost (x1, ocy1, x0, ocy0, wireframe, (void *)0xa3); - } - if (bottomtexture != NULL && bottomtexture->UseType != FTexture::TEX_Null) - { // bottom wall - Mosts.DoMost (x0, ofy0, x1, ofy1, wireframe, (void *)0x93); -/* float bfz2 = float(-(rw_backfz2 - viewz)) / 65536.f; - float bfz1 = float(-(rw_backfz1 - viewz)) / 65536.f; - Mosts.DoMost (WallSX1, bfz1 * izs / sz1 + ghoriz, - WallSX2, bfz2 * izs / sz2 + ghoriz, - wireframe, (void *)0x93);*/ - } - } -} - -void RP_Subsector (subsector_t *sub) -{ - int count; - seg_t* line; - sector_t tempsec; // killough 3/7/98: deep water hack - int floorlightlevel; // killough 3/16/98: set floor lightlevel - int ceilinglightlevel; // killough 4/11/98 - - frontsector = sub->sector; - count = sub->numlines; - line = sub->firstline; - - // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect - frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, - &ceilinglightlevel, false); // killough 4/11/98 - - basecolormap = frontsector->ColorMap; - //R_GetExtraLight (&ceilinglightlevel, frontsector->ceilingplane, frontsector->ExtraLights); - - // [RH] set foggy flag - foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE); - r_actualextralight = foggy ? 0 : extralight << 4; - basecolormap = frontsector->ColorMap; -/* ceilingplane = frontsector->ceilingplane.ZatPoint (viewx, viewy) > viewz || - frontsector->ceilingpic == skyflatnum || - (frontsector->CeilingSkyBox != NULL && frontsector->CeilingSkyBox->bAlways) || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && - frontsector->heightsec->floorpic == skyflatnum) ? - R_FindPlane(frontsector->ceilingplane, // killough 3/8/98 - frontsector->ceilingpic, - ceilinglightlevel + r_actualextralight, // killough 4/11/98 - frontsector->ceiling_xoffs, // killough 3/7/98 - frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs, - frontsector->ceiling_xscale, - frontsector->ceiling_yscale, - frontsector->ceiling_angle + frontsector->base_ceiling_angle, - frontsector->sky, - frontsector->CeilingSkyBox, - ) : NULL;*/ - - basecolormap = frontsector->ColorMap; - //R_GetExtraLight (&floorlightlevel, frontsector->floorplane, frontsector->ExtraLights); - - // killough 3/7/98: Add (x,y) offsets to flats, add deep water check - // killough 3/16/98: add floorlightlevel - // killough 10/98: add support for skies transferred from sidedefs -/* floorplane = frontsector->floorplane.ZatPoint (viewx, viewy) < viewz || // killough 3/7/98 - frontsector->floorpic == skyflatnum || - (frontsector->FloorSkyBox != NULL && frontsector->FloorSkyBox->bAlways) || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && - frontsector->heightsec->ceilingpic == skyflatnum) ? - R_FindPlane(frontsector->floorplane, - frontsector->floorpic, - floorlightlevel + r_actualextralight, // killough 3/16/98 - frontsector->floor_xoffs, // killough 3/7/98 - frontsector->floor_yoffs + frontsector->base_floor_yoffs, - frontsector->floor_xscale, - frontsector->floor_yscale, - frontsector->floor_angle + frontsector->base_floor_angle, - frontsector->sky, - frontsector->FloorSkyBox - ) : NULL;*/ - - // killough 9/18/98: Fix underwater slowdown, by passing real sector - // instead of fake one. Improve sprite lighting by basing sprite - // lightlevels on floor & ceiling lightlevels in the surrounding area. - // [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by - // it, otherwise they are lit by the floor. -// R_AddSprites (sub->sector, frontsector->ceilingpic == skyflatnum ? -// ceilinglightlevel : floorlightlevel, FakeSide); - - // [RH] Add particles -// int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel)/2 + r_actualextralight); -// for (WORD i = ParticlesInSubsec[sub-subsectors]; i != NO_PARTICLE; i = Particles[i].snext) -// { -// R_ProjectParticle (Particles + i, subsectors[sub-subsectors].sector, shade, FakeSide); -// } - -#if 0 - if (sub->poly) - { // Render the polyobj in the subsector first - int polyCount = sub->poly->numsegs; - seg_t **polySeg = sub->poly->segs; - while (polyCount--) - { - RP_AddLine (*polySeg++); - } - } -#endif - - while (count--) - { - if (line->sidedef == NULL || !(line->sidedef->Flags & WALLF_POLYOBJ)) - { - RP_AddLine (line); - } - line++; - } -} - -extern "C" const int checkcoord[12][4]; - -static bool RP_CheckBBox (fixed_t *bspcoord) -{ - int boxx; - int boxy; - int boxpos; - - fixed_t x1, y1, x2, y2; - double x, y, xp0, yp0, xp1, yp1, t, sx0, sx1; - - // Find the corners of the box - // that define the edges from current viewpoint. - if (viewx <= bspcoord[BOXLEFT]) - boxx = 0; - else if (viewx < bspcoord[BOXRIGHT]) - boxx = 1; - else - boxx = 2; - - if (viewy >= bspcoord[BOXTOP]) - boxy = 0; - else if (viewy > bspcoord[BOXBOTTOM]) - boxy = 1; - else - boxy = 2; - - boxpos = (boxy<<2)+boxx; - if (boxpos == 5) - return true; - - x1 = bspcoord[checkcoord[boxpos][0]] - viewx; - y1 = bspcoord[checkcoord[boxpos][1]] - viewy; - x2 = bspcoord[checkcoord[boxpos][2]] - viewx; - y2 = bspcoord[checkcoord[boxpos][3]] - viewy; - - // check clip list for an open space - - // Sitting on a line? - if (DMulScale32 (y1, x1-x2, x1, y2-y1) >= 0) - return true; - - //Offset&Rotate 3D coordinates to screen 3D space - x = double(x1); y = double(y1); - xp0 = x*gsinang - y*gcosang; - yp0 = x*gcosang2 + y*gsinang2; - x = double(x2); y = double(y2); - xp1 = x*gsinang - y*gcosang; - yp1 = x*gcosang2 + y*gsinang2; - - //Clip to close parallel-screen plane - if (yp0 < SCISDIST) - { - if (yp1 < SCISDIST) return false; - t = (SCISDIST-yp0)/(yp1-yp0); - xp0 = (xp1-xp0)*t+xp0; - yp0 = SCISDIST; - } - if (yp1 < SCISDIST) - { - t = (SCISDIST-yp0)/(yp1-yp0); - xp1 = (xp1-xp0)*t+xp0; - yp1 = SCISDIST; - } - - //Generate screen coordinates for front side of wall - sx0 = ghalfx*xp0/yp0 + ghalfx; - sx1 = ghalfx*xp1/yp1 + ghalfx; - - // Does not cross a pixel. - if (sx1 <= sx0) - return false; - - return Mosts.TestVisibleMost (sx0, sx1); -} - -void RP_RenderBSPNode (void *node) -{ - if (numnodes == 0) - { - RP_Subsector (subsectors); - return; - } - while (!((size_t)node & 1)) // Keep going until found a subsector - { - node_t *bsp = (node_t *)node; - - // Decide which side the view point is on. - int side = R_PointOnSide (viewx, viewy, bsp); - - // Recursively divide front space (toward the viewer). - RP_RenderBSPNode (bsp->children[side]); - - // Possibly divide back space (away from the viewer). - side ^= 1; - if (!RP_CheckBBox (bsp->bbox[side])) - return; - - node = bsp->children[side]; - } - RP_Subsector ((subsector_t *)((BYTE *)node - 1)); -} - diff --git a/src/r_polymost.h b/src/r_polymost.h deleted file mode 100644 index 8afbefb22..000000000 --- a/src/r_polymost.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************************************** -"POLYMOST" code written by Ken Silverman -**************************************************************************************************/ - -#include "c_cvars.h" - -typedef void (*pmostcallbacktype)(double *dpx, double *dpy, int n, void *userdata); - -class PolyClipper -{ -public: - PolyClipper(); - ~PolyClipper(); - - void InitMosts (double *px, double *py, int n); - bool TestVisibleMost (float x0, float x1); - int DoMost (float x0, float y0, float x1, float y1, pmostcallbacktype callback, void *callbackdata); - -private: - struct vsptype - { - float X, Cy[2], Fy[2]; - int Tag, CTag, FTag; - vsptype *Next, *Prev; - }; - - enum { GROUP_SIZE = 128 }; - - struct vspgroup - { - vspgroup (vsptype *sentinel); - - vspgroup *NextGroup; - vsptype vsp[GROUP_SIZE]; - }; - - vsptype EmptyList; - vsptype UsedList; - vspgroup vsps; - vsptype Solid; - - int GTag; - - vsptype *vsinsaft (vsptype *vsp); - void EmptyAll (); - void AddGroup (); - vsptype *GetVsp (); - void FreeVsp (vsptype *vsp); - - friend void drawpolymosttest(); - -}; - -extern void drawpolymosttest(); -struct event_t; void Polymost_Responder (event_t *ev); diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 56f816d6f..fb54b6f0a 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -40,7 +40,6 @@ #include "r_bsp.h" #include "r_swrenderer.h" #include "r_3dfloors.h" -#include "r_polymost.h" #include "textures/textures.h" #include "r_data/voxels.h" @@ -49,7 +48,6 @@ class FArchive; void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); void R_SetupColormap(player_t *); void R_SetupFreelook(); -void R_SetupPolymost(); void R_InitRenderer(); extern float LastFOV; @@ -245,7 +243,6 @@ void FSoftwareRenderer::SetupFrame(player_t *player) { R_SetupColormap(player); R_SetupFreelook(); - R_SetupPolymost(); } //========================================================================== diff --git a/zdoom.vcproj b/zdoom.vcproj index 3cbfac13a..cabc6c84f 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2309,10 +2309,6 @@ RelativePath=".\src\r_plane.cpp" > - - @@ -2353,10 +2349,6 @@ RelativePath=".\src\r_plane.h" > - - From bc450808b29e2ebfeaf7f2e2aace8f87aab3f7e1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:11:59 -0500 Subject: [PATCH 290/311] Consolidate wall texturing vars into two structs - All transformation and clipping values go into FWallCoords. - All texture mapping values go into FWallTMapVals. --- src/r_bsp.cpp | 116 ++++++++--------- src/r_bsp.h | 22 +++- src/r_segs.cpp | 329 +++++++++++++++++++++++-------------------------- 3 files changed, 226 insertions(+), 241 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 31dfe9907..c1ddb2a3c 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -92,18 +92,8 @@ drawseg_t* ds_p; size_t FirstInterestingDrawseg; TArray InterestingDrawsegs; -fixed_t WallTX1, WallTX2; // x coords at left, right of wall in view space -fixed_t WallTY1, WallTY2; // y coords at left, right of wall in view space - -fixed_t WallCX1, WallCX2; // x coords at left, right of wall in camera space -fixed_t WallCY1, WallCY2; // y coords at left, right of wall in camera space - -int WallSX1, WallSX2; // x coords at left, right of wall in screen space -fixed_t WallSZ1, WallSZ2; // depth at left, right of wall in screen space - -float WallDepthOrg, WallDepthScale; -float WallUoverZorg, WallUoverZstep; -float WallInvZorg, WallInvZstep; +FWallCoords WallC; +FWallTmapVals WallT; static BYTE FakeSide; @@ -419,7 +409,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y)) { // Check that the window is actually visible - for (int z = WallSX1; z < WallSX2; ++z) + for (int z = WallC.SX1; z < WallC.SX2; ++z) { if (floorclip[z] > ceilingclip[z]) { @@ -549,66 +539,66 @@ void R_AddLine (seg_t *line) if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; - WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); + WallC.TX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); + WallC.TX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); + WallC.TY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); + WallC.TY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); if (MirrorFlags & RF_XFLIP) { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swapvalues (WallTY1, WallTY2); + int t = 256-WallC.TX1; + WallC.TX1 = 256-WallC.TX2; + WallC.TX2 = t; + swapvalues (WallC.TY1, WallC.TY2); } - if (WallTX1 >= -WallTY1) + if (WallC.TX1 >= -WallC.TY1) { - if (WallTX1 > WallTY1) return; // left edge is off the right side - if (WallTY1 == 0) return; - WallSX1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; - if (WallTX1 >= 0) WallSX1 = MIN (viewwidth, WallSX1+1); // fix for signed divide - WallSZ1 = WallTY1; + if (WallC.TX1 > WallC.TY1) return; // left edge is off the right side + if (WallC.TY1 == 0) return; + WallC.SX1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; + if (WallC.TX1 >= 0) WallC.SX1 = MIN (viewwidth, WallC.SX1+1); // fix for signed divide + WallC.SZ1 = WallC.TY1; } else { - if (WallTX2 < -WallTY2) return; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; + if (WallC.TX2 < -WallC.TY2) return; // wall is off the left side + fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; if (den == 0) return; - WallSX1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); + WallC.SX1 = 0; + WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); } - if (WallSZ1 < 32) + if (WallC.SZ1 < 32) return; - if (WallTX2 <= WallTY2) + if (WallC.TX2 <= WallC.TY2) { - if (WallTX2 < -WallTY2) return; // right edge is off the left side - if (WallTY2 == 0) return; - WallSX2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS; - if (WallTX2 >= 0) WallSX2 = MIN (viewwidth, WallSX2+1); // fix for signed divide - WallSZ2 = WallTY2; + if (WallC.TX2 < -WallC.TY2) return; // right edge is off the left side + if (WallC.TY2 == 0) return; + WallC.SX2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; + if (WallC.TX2 >= 0) WallC.SX2 = MIN (viewwidth, WallC.SX2+1); // fix for signed divide + WallC.SZ2 = WallC.TY2; } else { - if (WallTX1 > WallTY1) return; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; + if (WallC.TX1 > WallC.TY1) return; // wall is off the right side + fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; if (den == 0) return; - WallSX2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); + WallC.SX2 = viewwidth; + WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); } - if (WallSZ2 < 32 || WallSX2 <= WallSX1) + if (WallC.SZ2 < 32 || WallC.SX2 <= WallC.SX1) return; - if (WallSX1 > WindowRight || WallSX2 < WindowLeft) + if (WallC.SX1 > WindowRight || WallC.SX2 < WindowLeft) return; if (line->linedef == NULL) { - if (R_CheckClipWallSegment (WallSX1, WallSX2)) + if (R_CheckClipWallSegment (WallC.SX1, WallC.SX2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -624,17 +614,17 @@ void R_AddLine (seg_t *line) { // The seg is the entire wall. if (MirrorFlags & RF_XFLIP) { - WallUoverZorg = (float)WallTX2 * WallTMapScale; - WallUoverZstep = (float)(-WallTY2) * 32.f; - WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale; - WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f; + WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; + WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; } else { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; + WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; + WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; } } else @@ -659,13 +649,13 @@ void R_AddLine (seg_t *line) fullx2 = -fullx2; } - WallUoverZorg = (float)fullx1 * WallTMapScale; - WallUoverZstep = (float)(-fully1) * 32.f; - WallInvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallInvZstep = (float)(fully2 - fully1) * 32.f; + WallT.UoverZorg = (float)fullx1 * WallTMapScale; + WallT.UoverZstep = (float)(-fully1) * 32.f; + WallT.InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; + WallT.InvZstep = (float)(fully2 - fully1) * 32.f; } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; + WallT.DepthScale = WallT.InvZstep * WallTMapScale2; + WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; if (!(fake3D & FAKE3D_FAKEBACK)) { @@ -791,7 +781,7 @@ void R_AddLine (seg_t *line) // mark their subsectors as visible for automap texturing. if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) { - if (R_CheckClipWallSegment(WallSX1, WallSX2)) + if (R_CheckClipWallSegment(WallC.SX1, WallC.SX2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -805,8 +795,8 @@ void R_AddLine (seg_t *line) if (line->linedef->special == Line_Horizon) { // Be aware: Line_Horizon does not work properly with sloped planes - clearbufshort (walltop+WallSX1, WallSX2 - WallSX1, centery); - clearbufshort (wallbottom+WallSX1, WallSX2 - WallSX1, centery); + clearbufshort (walltop+WallC.SX1, WallC.SX2 - WallC.SX1, centery); + clearbufshort (wallbottom+WallC.SX1, WallC.SX2 - WallC.SX1, centery); } else { @@ -831,7 +821,7 @@ void R_AddLine (seg_t *line) #endif } - if (R_ClipWallSegment (WallSX1, WallSX2, solid)) + if (R_ClipWallSegment (WallC.SX1, WallC.SX2, solid)) { InSubsector->flags |= SSECF_DRAWN; } diff --git a/src/r_bsp.h b/src/r_bsp.h index da20fb90c..d2fcb67e1 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -26,6 +26,25 @@ #include "tarray.h" #include +struct FWallCoords +{ + fixed_t TX1, TX2; // x coords at left, right of wall in view space + fixed_t TY1, TY2; // y coords at left, right of wall in view space + + fixed_t CX1, CX2; // x coords at left, right of wall in camera space + fixed_t CY1, CY2; // y coords at left, right of wall in camera space + + int SX1, SX2; // x coords at left, right of wall in screen space + fixed_t SZ1, SZ2; // depth at left, right of wall in screen space +}; + +struct FWallTmapVals +{ + float DepthOrg, DepthScale; + float UoverZorg, UoverZstep; + float InvZorg, InvZstep; +}; + enum { FAKED_Center, @@ -33,7 +52,6 @@ enum FAKED_AboveCeiling }; - struct drawseg_t { seg_t* curline; @@ -58,7 +76,7 @@ struct drawseg_t int fake; // ident fake drawseg, don't draw and clip sprites // backups ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures - float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; + FWallTmapVals tmapvals; }; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 4fec863ff..e1896b883 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -90,9 +90,8 @@ int OWallMost (short *mostbuf, fixed_t z); int WallMost (short *mostbuf, const secplane_t &plane); void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); -extern fixed_t WallSZ1, WallSZ2, WallTX1, WallTX2, WallTY1, WallTY2, WallCX1, WallCX2, WallCY1, WallCY2; -extern int WallSX1, WallSX2; -extern float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; +extern FWallCoords WallC; +extern FWallTmapVals WallT; int wallshade; @@ -389,10 +388,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) goto clearfog; } - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; if (fake3D & FAKE3D_CLIPTOP) { @@ -480,10 +479,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } else { // Texture does wrap vertically. - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; if (CurrentSkybox) { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor @@ -600,20 +599,15 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; - WallTX1 = ds->cx; - WallTY1 = ds->cy; - WallTX2 = WallTX1 + ds->cdx; - WallTY2 = WallTY1 + ds->cdy; - WallDepthScale = ds->WallDepthScale; - WallDepthOrg = ds->WallDepthOrg; - WallUoverZorg = ds->WallUoverZorg; - WallUoverZstep = ds->WallUoverZstep; - WallInvZorg = ds->WallInvZorg; - WallInvZstep = ds->WallInvZstep; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; + WallC.TX1 = ds->cx; + WallC.TY1 = ds->cy; + WallC.TX2 = ds->cx + ds->cdx; + WallC.TY2 = ds->cy + ds->cdy; + WallT = ds->tmapvals; OWallMost(wallupper, sclipTop - viewz); OWallMost(walllower, sclipBottom - viewz); @@ -1227,8 +1221,8 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, up = uwal; down = most1; - assert(WallSX1 <= x1); - assert(WallSX2 > x2); + assert(WallC.SX1 <= x1); + assert(WallC.SX2 > x2); // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) @@ -2048,7 +2042,7 @@ void R_NewWall (bool needlights) { if (rw_havehigh) { // front ceiling is above back ceiling - memcpy (&walltop[WallSX1], &wallupper[WallSX1], (WallSX2 - WallSX1)*sizeof(walltop[0])); + memcpy (&walltop[WallC.SX1], &wallupper[WallC.SX1], (WallC.SX2 - WallC.SX1)*sizeof(walltop[0])); rw_havehigh = false; } else if (rw_havelow && frontsector->ceilingplane != backsector->ceilingplane) @@ -2280,8 +2274,8 @@ void R_NewWall (bool needlights) wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) + r_actualextralight); GlobVis = r_WallVisibility; - rw_lightleft = SafeDivScale12 (GlobVis, WallSZ1); - rw_lightstep = (SafeDivScale12 (GlobVis, WallSZ2) - rw_lightleft) / (WallSX2 - WallSX1); + rw_lightleft = SafeDivScale12 (GlobVis, WallC.SZ1); + rw_lightstep = (SafeDivScale12 (GlobVis, WallC.SZ2) - rw_lightleft) / (WallC.SX2 - WallC.SX1); } else { @@ -2355,24 +2349,19 @@ void R_StoreWallRange (int start, int stop) } rw_offset = sidedef->GetTextureXOffset(side_t::mid); - rw_light = rw_lightleft + rw_lightstep * (start - WallSX1); + rw_light = rw_lightleft + rw_lightstep * (start - WallC.SX1); - ds_p->sx1 = WallSX1; - ds_p->sx2 = WallSX2; - ds_p->sz1 = WallSZ1; - ds_p->sz2 = WallSZ2; - ds_p->cx = WallTX1; - ds_p->cy = WallTY1; - ds_p->cdx = WallTX2 - WallTX1; - ds_p->cdy = WallTY2 - WallTY1; - ds_p->WallDepthScale = WallDepthScale; - ds_p->WallDepthOrg = WallDepthOrg; - ds_p->WallUoverZorg = WallUoverZorg; - ds_p->WallUoverZstep = WallUoverZstep; - ds_p->WallInvZorg = WallInvZorg; - ds_p->WallInvZstep = WallInvZstep; - ds_p->siz1 = (DWORD)DivScale32 (1, WallSZ1) >> 1; - ds_p->siz2 = (DWORD)DivScale32 (1, WallSZ2) >> 1; + ds_p->sx1 = WallC.SX1; + ds_p->sx2 = WallC.SX2; + ds_p->sz1 = WallC.SZ1; + ds_p->sz2 = WallC.SZ2; + ds_p->cx = WallC.TX1; + ds_p->cy = WallC.TY1; + ds_p->cdx = WallC.TX2 - WallC.TX1; + ds_p->cdy = WallC.TY2 - WallC.TY1; + ds_p->tmapvals = WallT; + ds_p->siz1 = (DWORD)DivScale32 (1, WallC.SZ1) >> 1; + ds_p->siz2 = (DWORD)DivScale32 (1, WallC.SZ2) >> 1; ds_p->x1 = rw_x = start; ds_p->x2 = stop-1; ds_p->curline = curline; @@ -2465,7 +2454,7 @@ void R_StoreWallRange (int start, int stop) if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && - (WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= TOO_CLOSE_Z)) + (WallC.SZ1 >= TOO_CLOSE_Z && WallC.SZ2 >= TOO_CLOSE_Z)) { fixed_t *swal; fixed_t *lwal; @@ -2613,59 +2602,59 @@ int OWallMost (short *mostbuf, fixed_t z) fixed_t s1, s2, s3, s4; z = -(z >> 4); - s1 = MulScale16 (globaluclip, WallSZ1); s2 = MulScale16 (globaluclip, WallSZ2); - s3 = MulScale16 (globaldclip, WallSZ1); s4 = MulScale16 (globaldclip, WallSZ2); + s1 = MulScale16 (globaluclip, WallC.SZ1); s2 = MulScale16 (globaluclip, WallC.SZ2); + s3 = MulScale16 (globaldclip, WallC.SZ1); s4 = MulScale16 (globaldclip, WallC.SZ2); bad = (zs3)<<2)+((z>s4)<<3); #if 1 if ((bad&3) == 3) { - memset (&mostbuf[WallSX1], 0, (WallSX2 - WallSX1)*sizeof(mostbuf[0])); + memset (&mostbuf[WallC.SX1], 0, (WallC.SX2 - WallC.SX1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) { - clearbufshort (&mostbuf[WallSX1], WallSX2 - WallSX1, viewheight); + clearbufshort (&mostbuf[WallC.SX1], WallC.SX2 - WallC.SX1, viewheight); return bad; } #endif - ix1 = WallSX1; iy1 = WallSZ1; - ix2 = WallSX2; iy2 = WallSZ2; + ix1 = WallC.SX1; iy1 = WallC.SZ1; + ix2 = WallC.SX2; iy2 = WallC.SZ2; #if 1 if (bad & 3) { int t = DivScale30 (z-s1, s2-s1); - int inty = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); if ((bad & 3) == 2) { - if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); + if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*sizeof(mostbuf[0])); + if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); } } if (bad & 12) { int t = DivScale30 (z-s3, s4-s3); - int inty = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); if ((bad & 12) == 8) { - if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2 - xcross, viewheight); + if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2 - xcross, viewheight); } else { - if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross - WallSX1, viewheight); + if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross - WallC.SX1, viewheight); } } @@ -2683,12 +2672,12 @@ int OWallMost (short *mostbuf, fixed_t z) double max = viewheight; double zz = z / 65536.0; #if 0 - double z1 = zz * InvZtoScale / WallSZ1; - double z2 = zz * InvZtoScale / WallSZ2 - z1; - z2 /= (WallSX2 - WallSX1); + double z1 = zz * InvZtoScale / WallC.SZ1; + double z2 = zz * InvZtoScale / WallC.SZ2 - z1; + z2 /= (WallC.SX2 - WallC.SX1); z1 += centeryfrac / 65536.0; - for (int x = WallSX1; x < WallSX2; ++x) + for (int x = WallC.SX1; x < WallC.SX2; ++x) { mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); z1 += z2; @@ -2696,18 +2685,18 @@ int OWallMost (short *mostbuf, fixed_t z) #else double top, bot, i; - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; double cy = centeryfrac / 65536.0; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { double frac = top / bot; - double scale = frac * WallDepthScale + WallDepthOrg; + double scale = frac * WallT.DepthScale + WallT.DepthOrg; mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max)); - top += WallUoverZstep; - bot += WallInvZstep; + top += WallT.UoverZstep; + bot += WallT.InvZstep; } #endif #endif @@ -2734,21 +2723,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v2->x; y = curline->v2->y; - if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) + if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) { - int frac = SafeDivScale30 (WallTY1 + WallTX1, den); + int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallSX2 > WallSX1 + 1) + if (WallC.SX2 > WallC.SX1 + 1) { x = curline->v1->x; y = curline->v1->y; - if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) + if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) { - int frac = SafeDivScale30 (WallTY2 - WallTX2, den); + int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } @@ -2763,21 +2752,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v1->x; y = curline->v1->y; - if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) + if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) { - int frac = SafeDivScale30 (WallTY1 + WallTX1, den); + int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallSX2 > WallSX1 + 1) + if (WallC.SX2 > WallC.SX1 + 1) { x = curline->v2->x; y = curline->v2->y; - if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) + if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) { - int frac = SafeDivScale30 (WallTY2 - WallTX2, den); + int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } @@ -2789,12 +2778,12 @@ int WallMost (short *mostbuf, const secplane_t &plane) } } - s1 = MulScale12 (globaluclip, WallSZ1); s2 = MulScale12 (globaluclip, WallSZ2); - s3 = MulScale12 (globaldclip, WallSZ1); s4 = MulScale12 (globaldclip, WallSZ2); + s1 = MulScale12 (globaluclip, WallC.SZ1); s2 = MulScale12 (globaluclip, WallC.SZ2); + s3 = MulScale12 (globaldclip, WallC.SZ1); s4 = MulScale12 (globaldclip, WallC.SZ2); bad = (z1s3)<<2)+((z2>s4)<<3); - ix1 = WallSX1; ix2 = WallSX2; - iy1 = WallSZ1; iy2 = WallSZ2; + ix1 = WallC.SX1; ix2 = WallC.SX2; + iy1 = WallC.SZ1; iy2 = WallC.SZ2; oz1 = z1; oz2 = z2; if ((bad&3) == 3) @@ -2814,9 +2803,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaluclip>>16) int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); - int inty = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,t); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1, inty); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1, inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2824,13 +2813,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&3) == 2) { - if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); + if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*sizeof(mostbuf[0])); + if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); } } @@ -2838,9 +2827,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaldclip>>16) int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); - int inty = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,t); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1,inty); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1,inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2848,13 +2837,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&12) == 8) { - if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2-xcross, viewheight); + if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2-xcross, viewheight); } else { - if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross-WallSX1, viewheight); + if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross-WallC.SX1, viewheight); } } @@ -2884,9 +2873,9 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; - if (WallSX1 > 0) + if (WallC.SX1 > 0) { - for (x = WallSX1; x < WallSX2; x++) + for (x = WallC.SX1; x < WallC.SX2; x++) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2899,7 +2888,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } fix = walxrepeat - 1 - fix; - for (x = WallSX2-1; x >= WallSX1; x--) + for (x = WallC.SX2-1; x >= WallC.SX1; x--) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2917,11 +2906,11 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) double top, bot, i; double xrepeat = fabs((double)walxrepeat); - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { double frac = top / bot; if (walxrepeat < 0) @@ -2932,9 +2921,9 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) { lwall[x] = xs_RoundToInt(frac * xrepeat); } - swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg); - top += WallUoverZstep; - bot += WallInvZstep; + swall[x] = xs_RoundToInt(frac * WallT.DepthScale + WallT.DepthOrg); + top += WallT.UoverZstep; + bot += WallT.InvZstep; } PrepWallRoundFix(lwall, walxrepeat); } @@ -2945,14 +2934,14 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) double xrepeat = fabs((double)walxrepeat); double topstep; - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; top *= xrepeat; - topstep = WallUoverZstep * xrepeat; + topstep = WallT.UoverZstep * xrepeat; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { if (walxrepeat < 0) { @@ -2963,7 +2952,7 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) lwall[x] = xs_RoundToInt(top / bot); } top += topstep; - bot += WallInvZstep; + bot += WallT.InvZstep; } PrepWallRoundFix(lwall, walxrepeat); } @@ -3044,14 +3033,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, // to a wall, we use the wall's angle instead of the decal's. This is // pretty much the same as what R_AddLine() does. - fixed_t savetx1, savetx2, savety1, savety2, savesz1, savesz2; - - savetx1 = WallTX1; - savetx2 = WallTX2; - savety1 = WallTY1; - savety2 = WallTY2; - savesz1 = WallSZ1; - savesz2 = WallSZ2; + FWallCoords savecoord = WallC; x2 = WallSpriteTile->GetWidth(); x1 = WallSpriteTile->LeftOffset; @@ -3068,76 +3050,76 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, ly = decaly - FixedMul (x1, finesine[ang]) - viewy; ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy; - WallTX1 = DMulScale20 (lx, viewsin, -ly, viewcos); - WallTX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); + WallC.TX1 = DMulScale20 (lx, viewsin, -ly, viewcos); + WallC.TX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); - WallTY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); - WallTY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); + WallC.TY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); + WallC.TY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); if (MirrorFlags & RF_XFLIP) { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swapvalues (WallTY1, WallTY2); + int t = 256-WallC.TX1; + WallC.TX1 = 256-WallC.TX2; + WallC.TX2 = t; + swapvalues (WallC.TY1, WallC.TY2); } - if (WallTX1 >= -WallTY1) + if (WallC.TX1 >= -WallC.TY1) { - if (WallTX1 > WallTY1) goto done; // left edge is off the right side - if (WallTY1 == 0) goto done; - x1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; - if (WallTX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide - WallSZ1 = WallTY1; + if (WallC.TX1 > WallC.TY1) goto done; // left edge is off the right side + if (WallC.TY1 == 0) goto done; + x1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; + if (WallC.TX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide + WallC.SZ1 = WallC.TY1; } else { - if (WallTX2 < -WallTY2) goto done; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; + if (WallC.TX2 < -WallC.TY2) goto done; // wall is off the left side + fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; if (den == 0) goto done; x1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); + WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); } - if (WallSZ1 < TOO_CLOSE_Z) + if (WallC.SZ1 < TOO_CLOSE_Z) goto done; - if (WallTX2 <= WallTY2) + if (WallC.TX2 <= WallC.TY2) { - if (WallTX2 < -WallTY2) goto done; // right edge is off the left side - if (WallTY2 == 0) goto done; - x2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS; - if (WallTX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide - WallSZ2 = WallTY2; + if (WallC.TX2 < -WallC.TY2) goto done; // right edge is off the left side + if (WallC.TY2 == 0) goto done; + x2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; + if (WallC.TX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide + WallC.SZ2 = WallC.TY2; } else { - if (WallTX1 > WallTY1) goto done; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; + if (WallC.TX1 > WallC.TY1) goto done; // wall is off the right side + fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; if (den == 0) goto done; x2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); + WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); } - if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallSZ2 < TOO_CLOSE_Z) + if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallC.SZ2 < TOO_CLOSE_Z) goto done; if (MirrorFlags & RF_XFLIP) { - WallUoverZorg = (float)WallTX2 * WallTMapScale; - WallUoverZstep = (float)(-WallTY2) * 32.f; - WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale; - WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f; + WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; + WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; } else { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; + WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; + WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; + WallT.DepthScale = WallT.InvZstep * WallTMapScale2; + WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; // Get the top and bottom clipping arrays switch (decal->RenderFlags & RF_CLIPMASK) @@ -3210,11 +3192,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, goto done; } - swapvalues (x1, WallSX1); - swapvalues (x2, WallSX2); + swapvalues (x1, WallC.SX1); + swapvalues (x2, WallC.SX2); PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS); - swapvalues (x1, WallSX1); - swapvalues (x2, WallSX2); + swapvalues (x1, WallC.SX1); + swapvalues (x2, WallC.SX2); if (flipx) { @@ -3239,7 +3221,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - WallSX1) * rw_lightstep; + rw_light = rw_lightleft + (x1 - WallC.SX1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = usecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) @@ -3346,12 +3328,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, R_FinishSetPatchStyle (); done: - WallTX1 = savetx1; - WallTX2 = savetx2; - WallTY1 = savety1; - WallTY2 = savety2; - WallSZ1 = savesz1; - WallSZ2 = savesz2; + WallC = savecoord; } static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) From fc63e9db3ca384e8d6228d56739f7bc95646ffc8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:23:04 -0500 Subject: [PATCH 291/311] Pass WallC as a parameter to (O)WallMost instead of referencing it globally --- src/r_bsp.cpp | 11 ++-- src/r_segs.cpp | 136 ++++++++++++++++++++++++------------------------- src/r_segs.h | 3 ++ 3 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index c1ddb2a3c..97938bf79 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -51,13 +51,12 @@ #include "doomstat.h" #include "r_state.h" #include "r_bsp.h" +#include "r_segs.h" #include "v_palette.h" #include "r_sky.h" #include "po_man.h" #include "r_data/colormaps.h" -int WallMost (short *mostbuf, const secplane_t &plane); - seg_t* curline; side_t* sidedef; line_t* linedef; @@ -693,12 +692,12 @@ void R_AddLine (seg_t *line) if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) { rw_havehigh = true; - WallMost (wallupper, backsector->ceilingplane); + WallMost (wallupper, backsector->ceilingplane, &WallC); } if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) { rw_havelow = true; - WallMost (walllower, backsector->floorplane); + WallMost (walllower, backsector->floorplane, &WallC); } // Closed door. @@ -800,8 +799,8 @@ void R_AddLine (seg_t *line) } else { - rw_ceilstat = WallMost (walltop, frontsector->ceilingplane); - rw_floorstat = WallMost (wallbottom, frontsector->floorplane); + rw_ceilstat = WallMost (walltop, frontsector->ceilingplane, &WallC); + rw_floorstat = WallMost (wallbottom, frontsector->floorplane, &WallC); // [RH] treat off-screen walls as solid #if 0 // Maybe later... diff --git a/src/r_segs.cpp b/src/r_segs.cpp index e1896b883..9567e0874 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -86,8 +86,6 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -int OWallMost (short *mostbuf, fixed_t z); -int WallMost (short *mostbuf, const secplane_t &plane); void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); extern FWallCoords WallC; @@ -217,13 +215,13 @@ void ClipMidtex(int x1, int x2) { short most[MAXWIDTH]; - WallMost(most, curline->frontsector->ceilingplane); + WallMost(most, curline->frontsector->ceilingplane, &WallC); for (int i = x1; i <= x2; ++i) { if (wallupper[i] < most[i]) wallupper[i] = most[i]; } - WallMost(most, curline->frontsector->floorplane); + WallMost(most, curline->frontsector->floorplane, &WallC); for (int i = x1; i <= x2; ++i) { if (walllower[i] > most[i]) @@ -395,19 +393,19 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) if (fake3D & FAKE3D_CLIPTOP) { - OWallMost (wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz); + OWallMost(wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz, &WallC); } else { - OWallMost (wallupper, textop); + OWallMost(wallupper, textop, &WallC); } if (fake3D & FAKE3D_CLIPBOTTOM) { - OWallMost (walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz); + OWallMost(walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz, &WallC); } else { - OWallMost (walllower, textop - texheight); + OWallMost(walllower, textop - texheight, &WallC); } for (i = x1; i <= x2; i++) @@ -497,7 +495,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) if (fake3D & FAKE3D_CLIPTOP) { - OWallMost (wallupper, sclipTop - viewz); + OWallMost(wallupper, sclipTop - viewz, &WallC); for (i = x1; i <= x2; i++) { if (wallupper[i] < mceilingclip[i]) @@ -507,7 +505,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } if (fake3D & FAKE3D_CLIPBOTTOM) { - OWallMost (walllower, sclipBottom - viewz); + OWallMost(walllower, sclipBottom - viewz, &WallC); for (i = x1; i <= x2; i++) { if (walllower[i] > mfloorclip[i]) @@ -609,8 +607,8 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) WallC.TY2 = ds->cy + ds->cdy; WallT = ds->tmapvals; - OWallMost(wallupper, sclipTop - viewz); - OWallMost(walllower, sclipBottom - viewz); + OWallMost(wallupper, sclipTop - viewz, &WallC); + OWallMost(walllower, sclipBottom - viewz, &WallC); for (i = x1; i <= x2; i++) { @@ -1227,7 +1225,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) { - int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane); + int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC); if (j != 3) { for (int j = x1; j <= x2; ++j) @@ -1309,7 +1307,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; while (partition > bot) { - int j = OWallMost(most3, partition - viewz); + int j = OWallMost(most3, partition - viewz, &WallC); if (j != 3) { for (int j = x1; j <= x2; ++j) @@ -1333,7 +1331,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; while (partition < top) { - int j = OWallMost(most3, partition - viewz); + int j = OWallMost(most3, partition - viewz, &WallC); if (j != 12) { for (int j = x1; j <= x2; ++j) @@ -2052,7 +2050,7 @@ void R_NewWall (bool needlights) // wall but nothing to draw for it. // Recalculate walltop so that the wall is clipped by the back sector's // ceiling instead of the front sector's ceiling. - WallMost (walltop, backsector->ceilingplane); + WallMost (walltop, backsector->ceilingplane, &WallC); } // Putting sky ceilings on the front and back of a line alters the way unpegged // positioning works. @@ -2596,65 +2594,65 @@ void R_StoreWallRange (int start, int stop) ds_p++; } -int OWallMost (short *mostbuf, fixed_t z) +int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) { int bad, y, ix1, ix2, iy1, iy2; fixed_t s1, s2, s3, s4; z = -(z >> 4); - s1 = MulScale16 (globaluclip, WallC.SZ1); s2 = MulScale16 (globaluclip, WallC.SZ2); - s3 = MulScale16 (globaldclip, WallC.SZ1); s4 = MulScale16 (globaldclip, WallC.SZ2); + s1 = MulScale16 (globaluclip, wallc->SZ1); s2 = MulScale16 (globaluclip, wallc->SZ2); + s3 = MulScale16 (globaldclip, wallc->SZ1); s4 = MulScale16 (globaldclip, wallc->SZ2); bad = (zs3)<<2)+((z>s4)<<3); #if 1 if ((bad&3) == 3) { - memset (&mostbuf[WallC.SX1], 0, (WallC.SX2 - WallC.SX1)*sizeof(mostbuf[0])); + memset (&mostbuf[wallc->SX1], 0, (wallc->SX2 - wallc->SX1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) { - clearbufshort (&mostbuf[WallC.SX1], WallC.SX2 - WallC.SX1, viewheight); + clearbufshort (&mostbuf[wallc->SX1], wallc->SX2 - wallc->SX1, viewheight); return bad; } #endif - ix1 = WallC.SX1; iy1 = WallC.SZ1; - ix2 = WallC.SX2; iy2 = WallC.SZ2; + ix1 = wallc->SX1; iy1 = wallc->SZ1; + ix2 = wallc->SX2; iy2 = wallc->SZ2; #if 1 if (bad & 3) { int t = DivScale30 (z-s1, s2-s1); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); if ((bad & 3) == 2) { - if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); } } if (bad & 12) { int t = DivScale30 (z-s3, s4-s3); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); if ((bad & 12) == 8) { - if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2 - xcross, viewheight); + if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2 - xcross, viewheight); } else { - if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross - WallC.SX1, viewheight); + if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross - wallc->SX1, viewheight); } } @@ -2672,12 +2670,12 @@ int OWallMost (short *mostbuf, fixed_t z) double max = viewheight; double zz = z / 65536.0; #if 0 - double z1 = zz * InvZtoScale / WallC.SZ1; - double z2 = zz * InvZtoScale / WallC.SZ2 - z1; - z2 /= (WallC.SX2 - WallC.SX1); + double z1 = zz * InvZtoScale / wallc->SZ1; + double z2 = zz * InvZtoScale / wallc->SZ2 - z1; + z2 /= (wallc->SX2 - wallc->SX1); z1 += centeryfrac / 65536.0; - for (int x = WallC.SX1; x < WallC.SX2; ++x) + for (int x = wallc->SX1; x < wallc->SX2; ++x) { mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); z1 += z2; @@ -2685,12 +2683,12 @@ int OWallMost (short *mostbuf, fixed_t z) #else double top, bot, i; - i = WallC.SX1 - centerx; + i = wallc->SX1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; double cy = centeryfrac / 65536.0; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = wallc->SX1; x < wallc->SX2; x++) { double frac = top / bot; double scale = frac * WallT.DepthScale + WallT.DepthOrg; @@ -2708,11 +2706,11 @@ int OWallMost (short *mostbuf, fixed_t z) return bad; } -int WallMost (short *mostbuf, const secplane_t &plane) +int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { if ((plane.a | plane.b) == 0) { - return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz); + return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz, wallc); } fixed_t x, y, den, z1, z2, oz1, oz2; @@ -2723,21 +2721,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v2->x; y = curline->v2->y; - if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) + if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); + int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallC.SX2 > WallC.SX1 + 1) + if (wallc->SX2 > wallc->SX1 + 1) { x = curline->v1->x; y = curline->v1->y; - if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) + if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); + int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } @@ -2752,21 +2750,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v1->x; y = curline->v1->y; - if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) + if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); + int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallC.SX2 > WallC.SX1 + 1) + if (wallc->SX2 > wallc->SX1 + 1) { x = curline->v2->x; y = curline->v2->y; - if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) + if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); + int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } @@ -2778,12 +2776,12 @@ int WallMost (short *mostbuf, const secplane_t &plane) } } - s1 = MulScale12 (globaluclip, WallC.SZ1); s2 = MulScale12 (globaluclip, WallC.SZ2); - s3 = MulScale12 (globaldclip, WallC.SZ1); s4 = MulScale12 (globaldclip, WallC.SZ2); + s1 = MulScale12 (globaluclip, wallc->SZ1); s2 = MulScale12 (globaluclip, wallc->SZ2); + s3 = MulScale12 (globaldclip, wallc->SZ1); s4 = MulScale12 (globaldclip, wallc->SZ2); bad = (z1s3)<<2)+((z2>s4)<<3); - ix1 = WallC.SX1; ix2 = WallC.SX2; - iy1 = WallC.SZ1; iy2 = WallC.SZ2; + ix1 = wallc->SX1; ix2 = wallc->SX2; + iy1 = wallc->SZ1; iy2 = wallc->SZ2; oz1 = z1; oz2 = z2; if ((bad&3) == 3) @@ -2803,9 +2801,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaluclip>>16) int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1, inty); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1, inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2813,13 +2811,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&3) == 2) { - if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); } } @@ -2827,9 +2825,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaldclip>>16) int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1,inty); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1,inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2837,13 +2835,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&12) == 8) { - if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2-xcross, viewheight); + if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2-xcross, viewheight); } else { - if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross-WallC.SX1, viewheight); + if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross-wallc->SX1, viewheight); } } diff --git a/src/r_segs.h b/src/r_segs.h index d46a3a523..838b019a9 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -31,6 +31,9 @@ extern short *openings; extern ptrdiff_t lastopening; extern size_t maxopenings; +int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc); +int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc); + ptrdiff_t R_NewOpening (ptrdiff_t len); void R_CheckDrawSegs (); From b0b9c57e8525bdfb2a0cb8d5c152168c8b52ca96 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:32:21 -0500 Subject: [PATCH 292/311] Pass x1 and x2 to Prep(L)Wall as params --- src/r_segs.cpp | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 9567e0874..b2a5d930f 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -86,8 +86,8 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); extern FWallCoords WallC; extern FWallTmapVals WallT; @@ -621,7 +621,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) walllower[i] = mfloorclip[i]; } - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2); wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale); R_FinishSetPatchStyle(); } @@ -1831,7 +1831,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (midtexture->bWorldPanning) @@ -1874,7 +1874,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (toptexture->bWorldPanning) @@ -1920,7 +1920,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (bottomtexture->bWorldPanning) @@ -2265,7 +2265,7 @@ void R_NewWall (bool needlights) bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) : FRACUNIT; - PrepWall (swall, lwall, sidedef->TexelLength * lwallscale); + PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.SX1, WallC.SX2); if (fixedcolormap == NULL && fixedlightlev < 0) { @@ -2864,16 +2864,16 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) return bad; } -static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) +static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // fix for rounding errors walxrepeat = abs(walxrepeat); fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; - if (WallC.SX1 > 0) + if (x1 > 0) { - for (x = WallC.SX1; x < WallC.SX2; x++) + for (x = x1; x < x2; x++) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2886,7 +2886,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } fix = walxrepeat - 1 - fix; - for (x = WallC.SX2-1; x >= WallC.SX1; x--) + for (x = x2-1; x >= x1; x--) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2899,16 +2899,16 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // swall = scale, lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); - i = WallC.SX1 - centerx; + i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = x1; x < x2; x++) { double frac = top / bot; if (walxrepeat < 0) @@ -2923,23 +2923,23 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) top += WallT.UoverZstep; bot += WallT.InvZstep; } - PrepWallRoundFix(lwall, walxrepeat); + PrepWallRoundFix(lwall, walxrepeat, x1, x2); } -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); double topstep; - i = WallC.SX1 - centerx; + i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; top *= xrepeat; topstep = WallT.UoverZstep * xrepeat; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = x1; x < x2; x++) { if (walxrepeat < 0) { @@ -2952,7 +2952,7 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) top += topstep; bot += WallT.InvZstep; } - PrepWallRoundFix(lwall, walxrepeat); + PrepWallRoundFix(lwall, walxrepeat, x1, x2); } // pass = 0: when seg is first drawn @@ -3190,11 +3190,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, goto done; } - swapvalues (x1, WallC.SX1); - swapvalues (x2, WallC.SX2); - PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS); - swapvalues (x1, WallC.SX1); - swapvalues (x2, WallC.SX2); + PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS, x1, x2); if (flipx) { From a600a816c3587db91a06b71ec3cbff6b40f4360c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 21:02:22 -0500 Subject: [PATCH 293/311] Consolidate some common code for texture mapping setup - R_AddLine() and R_RenderDecal() had nearly identical code for setting up texture mapping. These have now been spun off into methods of FWallCoords and FWallTmapVals. --- src/r_bsp.cpp | 199 +++++++++++++++++++++++++++---------------------- src/r_bsp.h | 6 ++ src/r_segs.cpp | 70 ++--------------- 3 files changed, 122 insertions(+), 153 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 97938bf79..02a89f371 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -538,58 +538,7 @@ void R_AddLine (seg_t *line) if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; - WallC.TX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallC.TX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - - WallC.TY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallC.TY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallC.TX1; - WallC.TX1 = 256-WallC.TX2; - WallC.TX2 = t; - swapvalues (WallC.TY1, WallC.TY2); - } - - if (WallC.TX1 >= -WallC.TY1) - { - if (WallC.TX1 > WallC.TY1) return; // left edge is off the right side - if (WallC.TY1 == 0) return; - WallC.SX1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; - if (WallC.TX1 >= 0) WallC.SX1 = MIN (viewwidth, WallC.SX1+1); // fix for signed divide - WallC.SZ1 = WallC.TY1; - } - else - { - if (WallC.TX2 < -WallC.TY2) return; // wall is off the left side - fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; - if (den == 0) return; - WallC.SX1 = 0; - WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); - } - - if (WallC.SZ1 < 32) - return; - - if (WallC.TX2 <= WallC.TY2) - { - if (WallC.TX2 < -WallC.TY2) return; // right edge is off the left side - if (WallC.TY2 == 0) return; - WallC.SX2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; - if (WallC.TX2 >= 0) WallC.SX2 = MIN (viewwidth, WallC.SX2+1); // fix for signed divide - WallC.SZ2 = WallC.TY2; - } - else - { - if (WallC.TX1 > WallC.TY1) return; // wall is off the right side - fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; - if (den == 0) return; - WallC.SX2 = viewwidth; - WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); - } - - if (WallC.SZ2 < 32 || WallC.SX2 <= WallC.SX1) + if (WallC.Init(tx1, ty1, tx2, ty2, 32)) return; if (WallC.SX1 > WindowRight || WallC.SX2 < WindowLeft) @@ -611,20 +560,7 @@ void R_AddLine (seg_t *line) if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) { // The seg is the entire wall. - if (MirrorFlags & RF_XFLIP) - { - WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; - WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; - } - else - { - WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; - WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; - } + WallT.InitFromWallCoords(&WallC); } else { // The seg is only part of the wall. @@ -632,29 +568,8 @@ void R_AddLine (seg_t *line) { swapvalues (v1, v2); } - tx1 = v1->x - viewx; - tx2 = v2->x - viewx; - ty1 = v1->y - viewy; - ty2 = v2->y - viewy; - - fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - fullx1 = -fullx1; - fullx2 = -fullx2; - } - - WallT.UoverZorg = (float)fullx1 * WallTMapScale; - WallT.UoverZstep = (float)(-fully1) * 32.f; - WallT.InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallT.InvZstep = (float)(fully2 - fully1) * 32.f; + WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy); } - WallT.DepthScale = WallT.InvZstep * WallTMapScale2; - WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; if (!(fake3D & FAKE3D_FAKEBACK)) { @@ -826,6 +741,114 @@ void R_AddLine (seg_t *line) } } +// +// FWallCoords :: Init +// +// Transform and clip coordinates. Returns true if it was clipped away +// +bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close) +{ + TX1 = DMulScale20(x1, viewsin, -y1, viewcos); + TX2 = DMulScale20(x2, viewsin, -y2, viewcos); + + TY1 = DMulScale20(x1, viewtancos, y1, viewtansin); + TY2 = DMulScale20(x2, viewtancos, y2, viewtansin); + + if (MirrorFlags & RF_XFLIP) + { + int t = 256 - TX1; + TX1 = 256 - TX2; + TX2 = t; + swapvalues(TY1, TY2); + } + + if (TX1 >= -TY1) + { + if (TX1 > TY1) return true; // left edge is off the right side + if (TY1 == 0) return true; + SX1 = (centerxfrac + Scale(TX1, centerxfrac, TY1)) >> FRACBITS; + if (TX1 >= 0) SX1 = MIN(viewwidth, SX1+1); // fix for signed divide + SZ1 = TY1; + } + else + { + if (TX2 < -TY2) return true; // wall is off the left side + fixed_t den = TX1 - TX2 - TY2 + TY1; + if (den == 0) return true; + SX1 = 0; + SZ1 = TY1 + Scale(TY2 - TY1, TX1 + TY1, den); + } + + if (SZ1 < too_close) + return true; + + if (TX2 <= TY2) + { + if (TX2 < -TY2) return true; // right edge is off the left side + if (TY2 == 0) return true; + SX2 = (centerxfrac + Scale(TX2, centerxfrac, TY2)) >> FRACBITS; + if (TX2 >= 0) SX2 = MIN(viewwidth, SX2+1); // fix for signed divide + SZ2 = TY2; + } + else + { + if (TX1 > TY1) return true; // wall is off the right side + fixed_t den = TY2 - TY1 - TX2 + TX1; + if (den == 0) return true; + SX2 = viewwidth; + SZ2 = TY1 + Scale(TY2 - TY1, TX1 - TY1, den); + } + + if (SZ2 < too_close || SX2 <= SX1) + return true; + + return false; +} + +void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) +{ + if (MirrorFlags & RF_XFLIP) + { + UoverZorg = (float)wallc->TX2 * WallTMapScale; + UoverZstep = (float)(-wallc->TY2) * 32.f; + InvZorg = (float)(wallc->TX2 - wallc->TX1) * WallTMapScale; + InvZstep = (float)(wallc->TY1 - wallc->TY2) * 32.f; + } + else + { + UoverZorg = (float)wallc->TX1 * WallTMapScale; + UoverZstep = (float)(-wallc->TY1) * 32.f; + InvZorg = (float)(wallc->TX1 - wallc->TX2) * WallTMapScale; + InvZstep = (float)(wallc->TY2 - wallc->TY1) * 32.f; + } + InitDepth(); +} + +void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) +{ // Coordinates should have already had viewx,viewy subtracted + fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); + fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); + fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); + fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); + + if (MirrorFlags & RF_XFLIP) + { + fullx1 = -fullx1; + fullx2 = -fullx2; + } + + UoverZorg = (float)fullx1 * WallTMapScale; + UoverZstep = (float)(-fully1) * 32.f; + InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; + InvZstep = (float)(fully2 - fully1) * 32.f; + InitDepth(); +} + +void FWallTmapVals::InitDepth() +{ + DepthScale = InvZstep * WallTMapScale2; + DepthOrg = -UoverZstep * WallTMapScale2; +} // // R_CheckBBox diff --git a/src/r_bsp.h b/src/r_bsp.h index d2fcb67e1..53a0b2b0b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -36,6 +36,8 @@ struct FWallCoords int SX1, SX2; // x coords at left, right of wall in screen space fixed_t SZ1, SZ2; // depth at left, right of wall in screen space + + bool Init(int x1, int y1, int x2, int y2, int too_close); }; struct FWallTmapVals @@ -43,6 +45,10 @@ struct FWallTmapVals float DepthOrg, DepthScale; float UoverZorg, UoverZstep; float InvZorg, InvZstep; + + void InitFromWallCoords(const FWallCoords *wallc); + void InitFromLine(int x1, int y1, int x2, int y2); + void InitDepth(); }; enum diff --git a/src/r_segs.cpp b/src/r_segs.cpp index b2a5d930f..f985a732d 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -3048,76 +3048,16 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, ly = decaly - FixedMul (x1, finesine[ang]) - viewy; ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy; - WallC.TX1 = DMulScale20 (lx, viewsin, -ly, viewcos); - WallC.TX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); - - WallC.TY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); - WallC.TY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallC.TX1; - WallC.TX1 = 256-WallC.TX2; - WallC.TX2 = t; - swapvalues (WallC.TY1, WallC.TY2); - } - - if (WallC.TX1 >= -WallC.TY1) - { - if (WallC.TX1 > WallC.TY1) goto done; // left edge is off the right side - if (WallC.TY1 == 0) goto done; - x1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; - if (WallC.TX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide - WallC.SZ1 = WallC.TY1; - } - else - { - if (WallC.TX2 < -WallC.TY2) goto done; // wall is off the left side - fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; - if (den == 0) goto done; - x1 = 0; - WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); - } - - if (WallC.SZ1 < TOO_CLOSE_Z) + if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z)) goto done; - if (WallC.TX2 <= WallC.TY2) - { - if (WallC.TX2 < -WallC.TY2) goto done; // right edge is off the left side - if (WallC.TY2 == 0) goto done; - x2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; - if (WallC.TX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide - WallC.SZ2 = WallC.TY2; - } - else - { - if (WallC.TX1 > WallC.TY1) goto done; // wall is off the right side - fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; - if (den == 0) goto done; - x2 = viewwidth; - WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); - } + x1 = WallC.SX1; + x2 = WallC.SX2; - if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallC.SZ2 < TOO_CLOSE_Z) + if (x1 > clipper->x2 || x2 <= clipper->x1) goto done; - if (MirrorFlags & RF_XFLIP) - { - WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; - WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; - } - else - { - WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; - WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; - } - WallT.DepthScale = WallT.InvZstep * WallTMapScale2; - WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; + WallT.InitFromWallCoords(&WallC); // Get the top and bottom clipping arrays switch (decal->RenderFlags & RF_CLIPMASK) From 15251e7a2167ab4e8ff54f6a9a9910ccf3140f7a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 22:18:08 -0500 Subject: [PATCH 294/311] Set face/wall/floor flags from Build sprites --- src/p_buildmap.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 54bf92527..32651b5bb 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -732,11 +732,10 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; mapthings[count].type = 9988; - mapthings[count].args[0] = sprites[i].picnum & 255; - mapthings[count].args[1] = sprites[i].picnum >> 8; + mapthings[count].args[0] = sprites[i].picnum; mapthings[count].args[2] = sprites[i].xrepeat; mapthings[count].args[3] = sprites[i].yrepeat; - mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1); + mapthings[count].args[4] = sprites[i].cstat; } count++; } @@ -874,22 +873,22 @@ void ACustomSprite::BeginPlay () char name[9]; Super::BeginPlay (); - mysnprintf (name, countof(name), "BTIL%04d", (args[0] + args[1]*256) & 0xffff); + mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff); picnum = TexMan.GetTexture (name, FTexture::TEX_Build); scaleX = args[2] * (FRACUNIT/64); scaleY = args[3] * (FRACUNIT/64); - if (args[4] & 2) + int cstat = args[4]; + if (cstat & 2) { RenderStyle = STYLE_Translucent; - if (args[4] & 1) - alpha = TRANSLUC66; - else - alpha = TRANSLUC33; + alpha = (cstat & 512) ? TRANSLUC66 : TRANSLUC33; } - if (args[4] & 4) + if (cstat & 4) renderflags |= RF_XFLIP; - if (args[4] & 8) + if (cstat & 8) renderflags |= RF_YFLIP; + // set face/wall/floor flags + renderflags |= ((cstat >> 4) & 3) << 12; } From 9716a61219d7cd26225ccbf18605bd2766a29632 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 2 Aug 2014 19:32:38 +1200 Subject: [PATCH 295/311] Add CVar for drawing weapons in the althud --- src/g_shared/shared_hud.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 964a28e2b..3806e5f9d 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -70,6 +70,7 @@ CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy. CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score +CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD @@ -972,7 +973,7 @@ void DrawHUD() CPlayer->mo->FindInventory(), 5, hudheight-20); i=DrawKeys(CPlayer, hudwidth-4, hudheight-10); i=DrawAmmo(CPlayer, hudwidth-5, i); - DrawWeapons(CPlayer, hudwidth-5, i); + if (hud_showweapons) DrawWeapons(CPlayer, hudwidth - 5, i); DrawInventory(CPlayer, 144, hudheight-28); if (CPlayer->camera && CPlayer->camera->player) { From 6ef67e1d3e078c193245e3d9bc96e1931704d4f6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 2 Aug 2014 13:14:25 +0300 Subject: [PATCH 296/311] Fixed build on compilers other than MSVC No more "Call to 'LittleShort' is ambiguous" error --- src/p_acs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 16e511b23..2ca6fe909 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1677,7 +1677,7 @@ void FBehavior::SerializeVarSet (FArchive &arc, SDWORD *vars, int max) static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset) { - unsigned count = (LittleShort(((unsigned *)chunk)[1]) - 2) / 4; + unsigned count = (LittleShort(static_cast(((unsigned *)chunk)[1]) - 2)) / 4; int *sizes = (int *)((BYTE *)chunk + 10); arrays->Count = count; if (count > 0) From a1b579e5fccd16b7aaf73d0bb0c8c4018fc11830 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Aug 2014 01:20:12 +0200 Subject: [PATCH 297/311] - added menu entry for newly added hud_showweapons CVAR. --- wadsrc/static/menudef.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 7099e6cc7..324c94e6b 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -816,6 +816,7 @@ OptionMenu "AltHUDOptions" Option "Show item count", "hud_showitems", "OnOff" Option "Show stamina and accuracy", "hud_showstats", "OnOff" Option "Show berserk", "hud_berserk_health", "OnOff" + Option "Show weapons", "hud_showweapons", "OnOff" Option "Show time", "hud_showtime", "AltHUDTime" Option "Time color", "hud_timecolor", "TextColors" Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0 From d0043bed78082c7faf749236c9939d90a081b25e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 2 Aug 2014 22:35:57 -0500 Subject: [PATCH 298/311] Q&D port of decal code to draw generic wall sprites - This still doesn't use all the sprite properties correctly. It also looks like they're going to need different code to build the clipping arrays. But at least wall sprites are drawn at the proper angle now! --- src/r_bsp.h | 8 ++ src/r_segs.cpp | 36 +------ src/r_segs.h | 9 ++ src/r_things.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++++-- src/r_things.h | 21 +++- 5 files changed, 279 insertions(+), 47 deletions(-) diff --git a/src/r_bsp.h b/src/r_bsp.h index 53a0b2b0b..d15beca0c 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -26,6 +26,11 @@ #include "tarray.h" #include +// The 3072 below is just an arbitrary value picked to avoid +// drawing lines the player is too close to that would overflow +// the texture calculations. +#define TOO_CLOSE_Z 3072 + struct FWallCoords { fixed_t TX1, TX2; // x coords at left, right of wall in view space @@ -51,6 +56,9 @@ struct FWallTmapVals void InitDepth(); }; +extern FWallCoords WallC; +extern FWallTmapVals WallT; + enum { FAKED_Center, diff --git a/src/r_segs.cpp b/src/r_segs.cpp index f985a732d..25395a596 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -64,11 +64,6 @@ CVAR(Bool, r_np2, true, 0) #define HEIGHTBITS 12 #define HEIGHTSHIFT (FRACBITS-HEIGHTBITS) -// The 3072 below is just an arbitrary value picked to avoid -// drawing lines the player is too close to that would overflow -// the texture calculations. -#define TOO_CLOSE_Z 3072 - extern fixed_t globaluclip, globaldclip; @@ -86,10 +81,6 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); -extern FWallCoords WallC; -extern FWallTmapVals WallT; int wallshade; @@ -139,7 +130,6 @@ static fixed_t rw_bottomtexturescaley; FTexture *rw_pic; static fixed_t *maskedtexturecol; -static FTexture *WallSpriteTile; static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass); static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)); @@ -3216,8 +3206,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { // calculate lighting dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } - - WallSpriteColumn (R_DrawMaskedColumn); + R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; } @@ -3230,7 +3219,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rt_initcols(); for (int zz = 4; zz; --zz) { - WallSpriteColumn (R_DrawMaskedColumnHoriz); + R_WallSpriteColumn (R_DrawMaskedColumnHoriz); dc_x++; } rt_draw4cols (dc_x - 4); @@ -3242,8 +3231,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { // calculate lighting dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } - - WallSpriteColumn (R_DrawMaskedColumn); + R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; } } @@ -3264,21 +3252,3 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, done: WallC = savecoord; } - -static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) -{ - unsigned int texturecolumn = lwall[dc_x] >> FRACBITS; - dc_iscale = MulScale16 (swall[dc_x], rw_offset); - spryscale = SafeDivScale32 (1, dc_iscale); - if (sprflipvert) - sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale); - else - sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); - - const BYTE *column; - const FTexture::Span *spans; - column = WallSpriteTile->GetColumn (texturecolumn, &spans); - dc_texturefrac = 0; - drawfunc (column, spans); - rw_light += rw_lightstep; -} diff --git a/src/r_segs.h b/src/r_segs.h index 838b019a9..b8bf96511 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -33,6 +33,8 @@ extern size_t maxopenings; int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc); int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc); +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); ptrdiff_t R_NewOpening (ptrdiff_t len); @@ -40,4 +42,11 @@ void R_CheckDrawSegs (); void R_RenderSegLoop (); +extern fixed_t swall[MAXWIDTH]; +extern fixed_t lwall[MAXWIDTH]; +extern fixed_t rw_light; // [RH] Scale lights with viewsize adjustments +extern fixed_t rw_lightstep; +extern fixed_t rw_lightleft; +extern fixed_t rw_offset; + #endif diff --git a/src/r_things.cpp b/src/r_things.cpp index 7243ac6f9..1d2c07a2a 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -114,6 +114,8 @@ FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES]; static int spriteshade; +FTexture *WallSpriteTile; + // constant arrays // used for psprite clipping and initializing clipping short zeroarray[MAXWIDTH]; @@ -145,6 +147,8 @@ static vissprite_t **spritesorter; static int spritesortersize = 0; static int vsprcount; +static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip); + void R_DeinitSprites() { @@ -401,6 +405,151 @@ void R_DrawVisSprite (vissprite_t *vis) NetUpdate (); } +void R_DrawWallSprite(vissprite_t *spr) +{ + int x1, x2; + fixed_t yscale; + int shade = LIGHT2SHADE(140); + + x1 = MAX(spr->x1, spr->wallc.SX1); + x2 = MIN(spr->x2, spr->wallc.SX2 + 1); + if (x1 >= x2) + return; + WallT.InitFromWallCoords(&spr->wallc); + PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); + dc_texturemid = spr->gzt - viewz; + yscale = FRACUNIT; + if (spr->renderflags & RF_XFLIP) + { + int right = (spr->pic->GetWidth() << FRACBITS) - 1; + + for (int i = x1; i < x2; i++) + { + lwall[i] = right - lwall[i]; + } + } + // Prepare lighting + bool calclighting = false; + FDynamicColormap *usecolormap = basecolormap; + bool rereadcolormap = true; + + // Decals that are added to the scene must fade to black. + if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0) + { + usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate); + rereadcolormap = false; + } + + rw_light = rw_lightleft + (x1 - spr->wallc.SX1) * rw_lightstep; + if (fixedlightlev >= 0) + dc_colormap = usecolormap->Maps + fixedlightlev; + else if (fixedcolormap != NULL) + dc_colormap = fixedcolormap; + else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) + dc_colormap = usecolormap->Maps; + else + calclighting = true; + + // Draw it + WallSpriteTile = spr->pic; + if (spr->renderflags & RF_YFLIP) + { + sprflipvert = true; + yscale = -yscale; + dc_texturemid = dc_texturemid - (spr->pic->GetHeight() << FRACBITS); + } + else + { + sprflipvert = false; + } + + // rw_offset is used as the texture's vertical scale + rw_offset = SafeDivScale30(1, yscale); + + dc_x = x1; + ESPSResult mode; + + mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.alpha, spr->Translation, spr->FillColor); + + // R_SetPatchStyle can modify basecolormap. + if (rereadcolormap) + { + usecolormap = basecolormap; + } + + if (mode == DontDraw) + { + return; + } + else + { + int stop4; + + if (mode == DoDraw0) + { // 1 column at a time + stop4 = dc_x; + } + else // DoDraw1 + { // up to 4 columns at a time + stop4 = x2 & ~3; + } + + while ((dc_x < stop4) && (dc_x & 3)) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + R_WallSpriteColumn(R_DrawMaskedColumn); + dc_x++; + } + + while (dc_x < stop4) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + rt_initcols(); + for (int zz = 4; zz; --zz) + { + R_WallSpriteColumn(R_DrawMaskedColumnHoriz); + dc_x++; + } + rt_draw4cols(dc_x - 4); + } + + while (dc_x < x2) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + R_WallSpriteColumn(R_DrawMaskedColumn); + dc_x++; + } + } + R_FinishSetPatchStyle(); +} + +void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) +{ + unsigned int texturecolumn = lwall[dc_x] >> FRACBITS; + dc_iscale = MulScale16 (swall[dc_x], rw_offset); + spryscale = SafeDivScale32 (1, dc_iscale); + if (sprflipvert) + sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale); + else + sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); + + const BYTE *column; + const FTexture::Span *spans; + column = WallSpriteTile->GetColumn (texturecolumn, &spans); + dc_texturefrac = 0; + drawfunc (column, spans); + rw_light += rw_lightstep; +} + void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot) { ESPSResult mode; @@ -521,12 +670,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY); fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac); - // transform the origin point - tr_x = fx - viewx; - tr_y = fy - viewy; - - tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin); - tex = NULL; voxel = NULL; @@ -618,6 +761,18 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; } + if ((thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) + { + R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, flip); + return; + } + + // transform the origin point + tr_x = fx - viewx; + tr_y = fy - viewy; + + tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin); + // thing is behind view plane? if (voxel == NULL && tz < MINZ) return; @@ -782,7 +937,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->heightsec = heightsec; vis->sector = thing->Sector; - vis->cx = tx2; vis->depth = tz; vis->gx = fx; vis->gy = fy; @@ -807,12 +961,14 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { vis->voxel = voxel->Voxel; vis->bIsVoxel = true; + vis->bWallSprite = false; DrewAVoxel = true; } else { vis->pic = tex; vis->bIsVoxel = false; + vis->bWallSprite = false; } // The software renderer cannot invert the source without inverting the overlay @@ -874,6 +1030,78 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } +static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip) +{ + FWallCoords wallc; + int x1, x2; + fixed_t lx1, lx2, ly1, ly2; + fixed_t gzb, gzt, tz; + FTexture *pic = TexMan(picnum, true); + angle_t ang = (thing->angle + ANGLE_90) >> ANGLETOFINESHIFT; + vissprite_t *vis; + + // Determine left and right edges of sprite. The sprite's angle is its normal, + // so the edges are 90 degrees each side of it. + x2 = pic->GetScaledWidth(); + x1 = pic->GetScaledLeftOffset(); + + x1 *= xscale; + x2 *= xscale; + + lx1 = fx - FixedMul(x1, finecosine[ang]) - viewx; + ly1 = fy - FixedMul(x1, finesine[ang]) - viewy; + lx2 = lx1 + FixedMul(x2, finecosine[ang]); + ly2 = ly1 + FixedMul(x2, finesine[ang]); + + // Is it off-screen? + if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z)) + return; + + if (wallc.SX1 > WindowRight || wallc.SX2 <= WindowLeft) + return; + + // Sprite sorting should probably treat these as walls, not sprites, + // but right now, I just want to get them drawing. + tz = DMulScale20(fx - viewx, viewtancos, fy - viewy, viewtansin); + + int scaled_to = pic->GetScaledTopOffset(); + int scaled_bo = scaled_to - pic->GetScaledHeight(); + gzt = fz + yscale * scaled_to; + gzb = fz + yscale * scaled_bo; + + vis = R_NewVisSprite(); + vis->x1 = wallc.SX1 < WindowLeft ? WindowLeft : wallc.SX1; + vis->x2 = wallc.SX2 >= WindowRight ? WindowRight-1 : wallc.SX2-1; + vis->idepth = (unsigned)DivScale32(1, tz) >> 1; + vis->depth = tz; + vis->sector = thing->Sector; + vis->heightsec = NULL; + vis->gx = fx; + vis->gy = fy; + vis->gz = fz; + vis->gzb = gzb; + vis->gzt = gzt; + vis->deltax = fx - viewx; + vis->deltay = fy - viewy; + vis->renderflags = thing->renderflags; + if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D + vis->Style.RenderStyle = thing->RenderStyle; + vis->FillColor = thing->fillcolor; + vis->Translation = thing->Translation; + vis->FakeFlatStat = 0; + vis->Style.alpha = thing->alpha; + vis->fakefloor = NULL; + vis->fakeceiling = NULL; + vis->ColormapNum = 0; + vis->bInMirror = MirrorFlags & RF_XFLIP; + vis->pic = pic; + vis->bIsVoxel = false; + vis->bWallSprite = true; + vis->ColormapNum = GETPALOOKUP( + (fixed_t)DivScale12 (r_SpriteVisibility, MAX(tz, MINZ)), spriteshade); + vis->Style.colormap = basecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT); + vis->wallc = wallc; +} // // R_AddSprites @@ -1904,7 +2132,14 @@ void R_DrawSprite (vissprite_t *spr) { mfloorclip = clipbot; mceilingclip = cliptop; - R_DrawVisSprite (spr); + if (!spr->bWallSprite) + { + R_DrawVisSprite(spr); + } + else + { + R_DrawWallSprite(spr); + } } else { @@ -2161,7 +2396,6 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis->yscale = xscale; vis->depth = tz; vis->idepth = (DWORD)DivScale32 (1, tz) >> 1; - vis->cx = tx; vis->gx = particle->x; vis->gy = particle->y; vis->gz = particle->z; // kg3D diff --git a/src/r_things.h b/src/r_things.h index 2219eee20..3ce1a4d4d 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -23,6 +23,7 @@ #ifndef __R_THINGS__ #define __R_THINGS__ +#include "r_bsp.h" // A vissprite_t is a thing // that will be drawn during a refresh. @@ -31,7 +32,6 @@ struct vissprite_t { short x1, x2; - fixed_t cx; // for line side calculation fixed_t gx, gy, gz; // origin in world coordinates angle_t angle; fixed_t gzb, gzt; // global bottom / top for silhouette clipping @@ -43,18 +43,26 @@ struct vissprite_t fixed_t floorclip; union { - // Used by regular sprites + FTexture *pic; + struct FVoxel *voxel; + }; + union + { + // Used by face sprites struct { - FTexture *pic; fixed_t texturemid; fixed_t startfrac; // horizontal position of x1 fixed_t xiscale; // negative if flipped }; + // Used by wall sprites + struct + { + FWallCoords wallc; + }; // Used by voxels struct { - struct FVoxel *voxel; fixed_t vx, vy, vz; // view origin angle_t vang; // view angle }; @@ -64,6 +72,7 @@ struct vissprite_t F3DFloor *fakefloor; F3DFloor *fakeceiling; BYTE bIsVoxel:1; // [RH] Use voxel instead of pic + BYTE bWallSprite:1; // [RH] This is a wall sprite BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on @@ -99,9 +108,11 @@ extern fixed_t pspritexscale; extern fixed_t pspriteyscale; extern fixed_t pspritexiscale; +extern FTexture *WallSpriteTile; + void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans); - +void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)); void R_CacheSprite (spritedef_t *sprite); void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), size_t first); From 5400ce1a218d3391b20953b9837ae356ac7c163a Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 7 Aug 2014 15:50:21 +0200 Subject: [PATCH 299/311] +MTHRUSPECIES on puffs --- src/p_map.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 96b2b6195..8aeab1a84 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3466,7 +3466,29 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p // //========================================================================== -static ETraceStatus CheckForGhost (FTraceResults &res, void *userdata) +struct Origin +{ + AActor *Caller; +}; + +static ETraceStatus CheckForSameSpecie(FTraceResults &res, void *userdata) +{ + if (res.HitType != TRACE_HitActor) + { + return TRACE_Stop; + } + + Origin *data = (Origin *)userdata; + + // check for physical attacks on the same specie + if (res.Actor->GetSpecies() == data->Caller->GetSpecies() || res.Actor->flags4 & MF4_SPECTRAL) + { + return TRACE_Skip; + } + + return TRACE_Stop; +} +static ETraceStatus CheckForGhost(FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { @@ -3481,8 +3503,24 @@ static ETraceStatus CheckForGhost (FTraceResults &res, void *userdata) return TRACE_Stop; } +static ETraceStatus CheckForSpecieAndGhost(FTraceResults &res, void *userdata) +{ + if (res.HitType != TRACE_HitActor) + { + return TRACE_Stop; + } -static ETraceStatus CheckForSpectral (FTraceResults &res, void *userdata) + Origin *data = (Origin *)userdata; + + // check for physical attacks + if (res.Actor->GetSpecies() == data->Caller->GetSpecies() || res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL) + { + return TRACE_Skip; + } + + return TRACE_Stop; +} +static ETraceStatus CheckForSpectral(FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { @@ -3511,9 +3549,12 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, { fixed_t vx, vy, vz, shootz; FTraceResults trace; + Origin TData; + TData.Caller = t1; angle_t srcangle = angle; int srcpitch = pitch; bool hitGhosts; + bool hitSameSpecie; bool killPuff = false; AActor *puff = NULL; int pflag = 0; @@ -3561,6 +3602,8 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) || (puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST)); + hitSameSpecie = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES)); + // if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type. // All other explicitly passed damage types (currenty only MDK) will be preserved. if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) && @@ -3575,7 +3618,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, if (!Trace (t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING|ML_BLOCKHITSCAN, t1, trace, - tflags, hitGhosts ? CheckForGhost : CheckForSpectral)) + tflags, hitGhosts ? (hitSameSpecie ? CheckForSpecieAndGhost : CheckForGhost) : hitSameSpecie ? CheckForSameSpecie : CheckForSpectral, &TData)) { // hit nothing if (puffDefaults == NULL) { From 8c4c011ca217210a2806ef9f9847215644845a75 Mon Sep 17 00:00:00 2001 From: Leonard2 Date: Thu, 7 Aug 2014 18:05:39 +0200 Subject: [PATCH 300/311] MTHRUSPECIES on puffs You were right it's cleaner that way --- src/p_map.cpp | 1735 ++++++++++++++++++++++++------------------------- 1 file changed, 849 insertions(+), 886 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 8aeab1a84..68c2c1530 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -53,19 +53,19 @@ #include "r_data/r_translate.h" #include "g_level.h" -CVAR (Bool, cl_bloodsplats, true, CVAR_ARCHIVE) -CVAR (Int, sv_smartaim, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) -CVAR (Bool, cl_doautoaim, false, CVAR_ARCHIVE) +CVAR(Bool, cl_bloodsplats, true, CVAR_ARCHIVE) +CVAR(Int, sv_smartaim, 0, CVAR_ARCHIVE | CVAR_SERVERINFO) +CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE) -static void CheckForPushSpecial (line_t *line, int side, AActor *mobj, bool windowcheck); -static void SpawnShootDecal (AActor *t1, const FTraceResults &trace); -static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false); +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windowcheck); +static void SpawnShootDecal(AActor *t1, const FTraceResults &trace); +static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff, + fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false); -static FRandom pr_tracebleed ("TraceBleed"); -static FRandom pr_checkthing ("CheckThing"); -static FRandom pr_lineattack ("LineAttack"); -static FRandom pr_crunch ("DoCrunch"); +static FRandom pr_tracebleed("TraceBleed"); +static FRandom pr_checkthing("CheckThing"); +static FRandom pr_lineattack("LineAttack"); +static FRandom pr_crunch("DoCrunch"); // keep track of special lines as they are hit, // but don't process them until the move is proven valid @@ -82,19 +82,19 @@ msecnode_t* sector_list = NULL; // phares 3/16/98 // //========================================================================== -static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPosition &tmf, int flags) +static bool PIT_FindFloorCeiling(line_t *ld, const FBoundingBox &box, FCheckPosition &tmf, int flags) { if (box.Right() <= ld->bbox[BOXLEFT] || box.Left() >= ld->bbox[BOXRIGHT] || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP] ) + || box.Bottom() >= ld->bbox[BOXTOP]) return true; - if (box.BoxOnLineSide (ld) != -1) + if (box.BoxOnLineSide(ld) != -1) return true; // A line has been hit - + if (!ld->backsector) { // One sided line return true; @@ -105,33 +105,33 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos // set openrange, opentop, openbottom if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) - && ld->backsector->e->XFloor.ffloors.Size()==0 && ld->frontsector->e->XFloor.ffloors.Size()==0) + (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | + (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | + (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) + && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0) { - P_LineOpening (open, tmf.thing, ld, sx=tmf.x, sy=tmf.y, tmf.x, tmf.y, flags); + P_LineOpening(open, tmf.thing, ld, sx = tmf.x, sy = tmf.y, tmf.x, tmf.y, flags); } else { // Find the point on the line closest to the actor's center, and use - // that to calculate openings + // that to calculate openings double dx = ld->dx; double dy = ld->dy; fixed_t r = xs_CRoundToInt(((double)(tmf.x - ld->v1->x) * dx + - (double)(tmf.y - ld->v1->y) * dy) / - (dx*dx + dy*dy) * 16777216.f); + (double)(tmf.y - ld->v1->y) * dy) / + (dx*dx + dy*dy) * 16777216.f); if (r <= 0) { - P_LineOpening (open, tmf.thing, ld, sx=ld->v1->x, sy=ld->v1->y, tmf.x, tmf.y, flags); + P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tmf.x, tmf.y, flags); } - else if (r >= (1<<24)) + else if (r >= (1 << 24)) { - P_LineOpening (open, tmf.thing, ld, sx=ld->v2->x, sy=ld->v2->y, tmf.thing->x, tmf.thing->y, flags); + P_LineOpening(open, tmf.thing, ld, sx = ld->v2->x, sy = ld->v2->y, tmf.thing->x, tmf.thing->y, flags); } else { - P_LineOpening (open, tmf.thing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx), - sy=ld->v1->y + MulScale24 (r, ld->dy), tmf.x, tmf.y, flags); + P_LineOpening(open, tmf.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx), + sy = ld->v1->y + MulScale24(r, ld->dy), tmf.x, tmf.y, flags); } } @@ -156,7 +156,7 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos if (open.lowfloor < tmf.dropoffz) tmf.dropoffz = open.lowfloor; - + return true; } @@ -172,12 +172,12 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) sector_t *sec; if (!(flags & FFCF_ONLYSPAWNPOS)) { - sec = !(flags & FFCF_SAMESECTOR) ? P_PointInSector (tmf.x, tmf.y) : tmf.thing->Sector; + sec = !(flags & FFCF_SAMESECTOR) ? P_PointInSector(tmf.x, tmf.y) : tmf.thing->Sector; tmf.floorsector = sec; tmf.ceilingsector = sec; - tmf.floorz = tmf.dropoffz = sec->floorplane.ZatPoint (tmf.x, tmf.y); - tmf.ceilingz = sec->ceilingplane.ZatPoint (tmf.x, tmf.y); + tmf.floorz = tmf.dropoffz = sec->floorplane.ZatPoint(tmf.x, tmf.y); + tmf.ceilingz = sec->ceilingplane.ZatPoint(tmf.x, tmf.y); tmf.floorpic = sec->GetTexture(sector_t::floor); tmf.ceilingpic = sec->GetTexture(sector_t::ceiling); } @@ -187,7 +187,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) } #ifdef _3DFLOORS - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + for (unsigned int i = 0; ie->XFloor.ffloors.Size(); i++) { F3DFloor* rover = sec->e->XFloor.ffloors[i]; @@ -204,7 +204,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) tmf.floorpic = *rover->top.texture; } } - if (ff_bottom <= tmf.ceilingz && ff_bottom > tmf.z + tmf.thing->height) + if (ff_bottom <= tmf.ceilingz && ff_bottom > tmf.z + tmf.thing->height) { tmf.ceilingz = ff_bottom; tmf.ceilingpic = *rover->bottom.texture; @@ -219,7 +219,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) // //========================================================================== -void P_FindFloorCeiling (AActor *actor, int flags) +void P_FindFloorCeiling(AActor *actor, int flags) { FCheckPosition tmf; @@ -309,14 +309,14 @@ void P_FindFloorCeiling (AActor *actor, int flags) // //========================================================================== -bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag) +bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag) { FCheckPosition tmf; sector_t *oldsec = thing->Sector; - + // kill anything occupying the position - - + + // The base floor/ceiling is from the subsector that contains the point. // Any contacted lines the step closer together will adjust them. tmf.thing = thing; @@ -326,8 +326,8 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr tmf.touchmidtex = false; tmf.abovemidtex = false; P_GetFloorCeilingZ(tmf, 0); - - spechit.Clear (); + + spechit.Clear(); bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); @@ -359,7 +359,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr continue; fixed_t blockdist = th->radius + tmf.thing->radius; - if ( abs(th->x - tmf.x) >= blockdist || abs(th->y - tmf.y) >= blockdist) + if (abs(th->x - tmf.x) >= blockdist || abs(th->y - tmf.y) >= blockdist) continue; // [RH] Z-Check @@ -370,7 +370,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP)) { if (z > th->z + th->height || // overhead - z+thing->height < th->z) // underneath + z + thing->height < th->z) // underneath continue; } } @@ -380,14 +380,14 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr // ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them. if ((StompAlwaysFrags && !(th->flags6 & MF6_NOTELEFRAG)) || (th->flags7 & MF7_ALWAYSTELEFRAG)) { - P_DamageMobj (th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS); + P_DamageMobj(th, thing, thing, TELEFRAG_DAMAGE, NAME_Telefrag, DMG_THRUSTLESS); continue; } return false; } - + // the move is ok, so link the thing into its new position - thing->SetOrigin (x, y, z); + thing->SetOrigin(x, y, z); thing->floorz = tmf.floorz; thing->ceilingz = tmf.ceilingz; thing->floorsector = tmf.floorsector; @@ -399,12 +399,12 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr if (thing->flags2 & MF2_FLOORCLIP) { - thing->AdjustFloorClip (); + thing->AdjustFloorClip(); } if (thing == players[consoleplayer].camera) { - R_ResetViewInterpolation (); + R_ResetViewInterpolation(); } thing->PrevX = x; @@ -430,7 +430,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr // //========================================================================== -void P_PlayerStartStomp (AActor *actor) +void P_PlayerStartStomp(AActor *actor) { AActor *th; FBlockThingsIterator it(FBoundingBox(actor->x, actor->y, actor->radius)); @@ -456,7 +456,7 @@ void P_PlayerStartStomp (AActor *actor) if (actor->z + actor->height < th->z) continue; // underneath - P_DamageMobj (th, actor, actor, TELEFRAG_DAMAGE, NAME_Telefrag); + P_DamageMobj(th, actor, actor, TELEFRAG_DAMAGE, NAME_Telefrag); } } @@ -466,13 +466,13 @@ void P_PlayerStartStomp (AActor *actor) // //========================================================================== -inline fixed_t secfriction (const sector_t *sec) +inline fixed_t secfriction(const sector_t *sec) { fixed_t friction = Terrains[TerrainTypes[sec->GetTexture(sector_t::floor)]].Friction; return friction != 0 ? friction : sec->friction; } -inline fixed_t secmovefac (const sector_t *sec) +inline fixed_t secmovefac(const sector_t *sec) { fixed_t movefactor = Terrains[TerrainTypes[sec->GetTexture(sector_t::floor)]].MoveFactor; return movefactor != 0 ? movefactor : sec->movefactor; @@ -488,7 +488,7 @@ inline fixed_t secmovefac (const sector_t *sec) // //========================================================================== -int P_GetFriction (const AActor *mo, int *frictionfactor) +int P_GetFriction(const AActor *mo, int *frictionfactor) { int friction = ORIG_FRICTION; int movefactor = ORIG_FRICTION_FACTOR; @@ -505,12 +505,12 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) friction = FRICTION_FLY; } else if ((!(mo->flags & MF_NOGRAVITY) && mo->waterlevel > 1) || - (mo->waterlevel == 1 && mo->z > mo->floorz + 6*FRACUNIT)) + (mo->waterlevel == 1 && mo->z > mo->floorz + 6 * FRACUNIT)) { friction = secfriction(mo->Sector); movefactor = secmovefac(mo->Sector) >> 1; } - else if (var_friction && !(mo->flags & (MF_NOCLIP|MF_NOGRAVITY))) + else if (var_friction && !(mo->flags & (MF_NOCLIP | MF_NOGRAVITY))) { // When the object is straddling sectors with the same // floor height that have different frictions, use the lowest // friction value (muddy has precedence over icy). @@ -528,7 +528,7 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) if (!(rover->flags & FF_SOLID)) continue; // Player must be on top of the floor to be affected... - if (mo->z != rover->top.plane->ZatPoint(mo->x,mo->y)) continue; + if (mo->z != rover->top.plane->ZatPoint(mo->x, mo->y)) continue; newfriction = secfriction(rover->model); if (newfriction < friction || friction == ORIG_FRICTION) { @@ -547,14 +547,14 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) if ((newfriction < friction || friction == ORIG_FRICTION) && (mo->z <= sec->floorplane.ZatPoint(mo->x, mo->y) || (sec->GetHeightSec() != NULL && - mo->z <= sec->heightsec->floorplane.ZatPoint(mo->x, mo->y)))) + mo->z <= sec->heightsec->floorplane.ZatPoint(mo->x, mo->y)))) { friction = newfriction; movefactor = secmovefac(sec); } } } - + if (mo->Friction != FRACUNIT) { friction = clamp(FixedMul(friction, mo->Friction), 0, FRACUNIT); @@ -577,7 +577,7 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) // //========================================================================== -int P_GetMoveFactor (const AActor *mo, int *frictionp) +int P_GetMoveFactor(const AActor *mo, int *frictionp) { int movefactor, friction; @@ -592,9 +592,9 @@ int P_GetMoveFactor (const AActor *mo, int *frictionp) int velocity = P_AproxDistance(mo->velx, mo->vely); - if (velocity > MORE_FRICTION_VELOCITY<<2) + if (velocity > MORE_FRICTION_VELOCITY << 2) movefactor <<= 3; - else if (velocity > MORE_FRICTION_VELOCITY<<1) + else if (velocity > MORE_FRICTION_VELOCITY << 1) movefactor <<= 2; else if (velocity > MORE_FRICTION_VELOCITY) movefactor <<= 1; @@ -620,37 +620,37 @@ int P_GetMoveFactor (const AActor *mo, int *frictionp) //========================================================================== static // killough 3/26/98: make static -bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) +bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm) { bool rail = false; if (box.Right() <= ld->bbox[BOXLEFT] || box.Left() >= ld->bbox[BOXRIGHT] || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP] ) + || box.Bottom() >= ld->bbox[BOXTOP]) return true; - if (box.BoxOnLineSide (ld) != -1) + if (box.BoxOnLineSide(ld) != -1) return true; // A line has been hit -/* -= -= The moving thing's destination position will cross the given line. -= If this should not be allowed, return false. -= If the line is special, keep track of it to process later if the move -= is proven ok. NOTE: specials are NOT sorted by order, so two special lines -= that are only 8 pixels apart could be crossed in either order. -*/ - + /* + = + = The moving thing's destination position will cross the given line. + = If this should not be allowed, return false. + = If the line is special, keep track of it to process later if the move + = is proven ok. NOTE: specials are NOT sorted by order, so two special lines + = that are only 8 pixels apart could be crossed in either order. + */ + if (!ld->backsector) { // One sided line if (tm.thing->flags2 & MF2_BLASTED) { - P_DamageMobj (tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); + P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); } tm.thing->BlockingLine = ld; - CheckForPushSpecial (ld, 0, tm.thing, false); + CheckForPushSpecial(ld, 0, tm.thing, false); return false; } @@ -663,13 +663,13 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) bool NotBlocked = ((tm.thing->flags3 & MF3_NOBLOCKMONST) || ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY))); - if (!(Projectile) || (ld->flags & (ML_BLOCKEVERYTHING|ML_BLOCKPROJECTILE))) + if (!(Projectile) || (ld->flags & (ML_BLOCKEVERYTHING | ML_BLOCKPROJECTILE))) { if (ld->flags & ML_RAILING) { rail = true; } - else if ((ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) || // explicitly blocking everything + else if ((ld->flags & (ML_BLOCKING | ML_BLOCKEVERYTHING)) || // explicitly blocking everything (!(NotBlocked) && (ld->flags & ML_BLOCKMONSTERS)) || // block monsters only (tm.thing->player != NULL && (ld->flags & ML_BLOCK_PLAYERS)) || // block players ((Projectile) && (ld->flags & ML_BLOCKPROJECTILE)) || // block projectiles @@ -677,21 +677,21 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) { if (tm.thing->flags2 & MF2_BLASTED) { - P_DamageMobj (tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); + P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); } tm.thing->BlockingLine = ld; // Calculate line side based on the actor's original position, not the new one. - CheckForPushSpecial (ld, P_PointOnLineSide(tm.thing->x, tm.thing->y, ld), tm.thing, false); + CheckForPushSpecial(ld, P_PointOnLineSide(tm.thing->x, tm.thing->y, ld), tm.thing, false); return false; } } // [RH] Steep sectors count as dropoffs (unless already in one) if (!(tm.thing->flags & MF_DROPOFF) && - !(tm.thing->flags & (MF_NOGRAVITY|MF_NOCLIP))) + !(tm.thing->flags & (MF_NOGRAVITY | MF_NOCLIP))) { secplane_t frontplane = ld->frontsector->floorplane; - secplane_t backplane = ld->backsector->floorplane; + secplane_t backplane = ld->backsector->floorplane; #ifdef _3DFLOORS // Check 3D floors as well frontplane = P_FindFloorPlane(ld->frontsector, tm.thing->x, tm.thing->y, tm.thing->floorz); @@ -719,57 +719,57 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) } } - fixed_t sx=0, sy=0; + fixed_t sx = 0, sy = 0; FLineOpening open; // set openrange, opentop, openbottom if ((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) - && ld->backsector->e->XFloor.ffloors.Size()==0 && ld->frontsector->e->XFloor.ffloors.Size()==0) + (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | + (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | + (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) + && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0) { - P_LineOpening (open, tm.thing, ld, sx=tm.x, sy=tm.y, tm.x, tm.y); + P_LineOpening(open, tm.thing, ld, sx = tm.x, sy = tm.y, tm.x, tm.y); } else { // Find the point on the line closest to the actor's center, and use - // that to calculate openings + // that to calculate openings float dx = (float)ld->dx; float dy = (float)ld->dy; fixed_t r = (fixed_t)(((float)(tm.x - ld->v1->x) * dx + - (float)(tm.y - ld->v1->y) * dy) / - (dx*dx + dy*dy) * 16777216.f); -/* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r, - ld->frontsector->floorplane.a, - ld->frontsector->floorplane.b, - ld->frontsector->floorplane.c, - ld->frontsector->floorplane.ic, - ld->backsector->floorplane.a, - ld->backsector->floorplane.b, - ld->backsector->floorplane.c, - ld->backsector->floorplane.ic);*/ + (float)(tm.y - ld->v1->y) * dy) / + (dx*dx + dy*dy) * 16777216.f); + /* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r, + ld->frontsector->floorplane.a, + ld->frontsector->floorplane.b, + ld->frontsector->floorplane.c, + ld->frontsector->floorplane.ic, + ld->backsector->floorplane.a, + ld->backsector->floorplane.b, + ld->backsector->floorplane.c, + ld->backsector->floorplane.ic);*/ if (r <= 0) { - P_LineOpening (open, tm.thing, ld, sx=ld->v1->x, sy=ld->v1->y, tm.x, tm.y); + P_LineOpening(open, tm.thing, ld, sx = ld->v1->x, sy = ld->v1->y, tm.x, tm.y); } - else if (r >= (1<<24)) + else if (r >= (1 << 24)) { - P_LineOpening (open, tm.thing, ld, sx=ld->v2->x, sy=ld->v2->y, tm.thing->x, tm.thing->y); + P_LineOpening(open, tm.thing, ld, sx = ld->v2->x, sy = ld->v2->y, tm.thing->x, tm.thing->y); } else { - P_LineOpening (open, tm.thing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx), - sy=ld->v1->y + MulScale24 (r, ld->dy), tm.x, tm.y); + P_LineOpening(open, tm.thing, ld, sx = ld->v1->x + MulScale24(r, ld->dx), + sy = ld->v1->y + MulScale24(r, ld->dy), tm.x, tm.y); } // the floorplane on both sides is identical with the current one // so don't mess around with the z-position - if (ld->frontsector->floorplane==ld->backsector->floorplane && - ld->frontsector->floorplane==tm.thing->Sector->floorplane && + if (ld->frontsector->floorplane == ld->backsector->floorplane && + ld->frontsector->floorplane == tm.thing->Sector->floorplane && !ld->frontsector->e->XFloor.ffloors.Size() && !ld->backsector->e->XFloor.ffloors.Size() && !open.abovemidtex) { - open.bottom=INT_MIN; + open.bottom = INT_MIN; } /* Printf (" %d %d %d\n", sx, sy, openbottom);*/ } @@ -783,9 +783,9 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) // from either side. How long until somebody reports this as a bug and I'm // forced to say, "It's not a bug. It's a feature?" Ugh. (!(level.flags2 & LEVEL2_RAILINGHACK) || - open.bottom == tm.thing->Sector->floorplane.ZatPoint (sx, sy))) + open.bottom == tm.thing->Sector->floorplane.ZatPoint(sx, sy))) { - open.bottom += 32*FRACUNIT; + open.bottom += 32 * FRACUNIT; } // adjust floor / ceiling heights @@ -815,11 +815,11 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) if (open.lowfloor < tm.dropoffz) tm.dropoffz = open.lowfloor; - + // if contacted a special line, add it to the list if (ld->special) { - spechit.Push (ld); + spechit.Push(ld); } return true; @@ -831,24 +831,24 @@ bool PIT_CheckLine (line_t *ld, const FBoundingBox &box, FCheckPosition &tm) // //========================================================================== -bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) +bool PIT_CheckThing(AActor *thing, FCheckPosition &tm) { fixed_t topz; bool solid; int damage; - if (!((thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY)) + if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY)) return true; // can't hit thing fixed_t blockdist = thing->radius + tm.thing->radius; - if ( abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist) + if (abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist) return true; // don't clip against self if (thing == tm.thing) return true; - if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS) + if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS) return true; if ((tm.thing->flags6 & MF6_THRUSPECIES) && (tm.thing->GetSpecies() == thing->GetSpecies())) @@ -856,7 +856,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) tm.thing->BlockingMobj = thing; topz = thing->z + thing->height; - if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT|MF_MISSILE|MF_SKULLFLY|MF_NOGRAVITY)) && + if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) && (thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE)) { // [RH] Let monsters walk on actors as well as floors @@ -868,8 +868,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // way to do this, so I restrict them to only walking on bridges instead. // Uncommenting the if here makes it almost impossible for them to walk on // anything, bridge or otherwise. -// if (abs(thing->x - tmx) <= thing->radius && -// abs(thing->y - tmy) <= thing->radius) + // if (abs(thing->x - tmx) <= thing->radius && + // abs(thing->y - tmy) <= thing->radius) { tm.stepthing = thing; tm.floorz = topz; @@ -897,7 +897,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) { // ... but not if they did not overlap in z-direction before but would after the move. unblocking = !((tm.thing->z >= thing->z + thing->height && tm.z < thing->z + thing->height) || - (tm.thing->z + tm.thing->height <= thing->z && tm.z + tm.thing->height > thing->z)); + (tm.thing->z + tm.thing->height <= thing->z && tm.z + tm.thing->height > thing->z)); } } } @@ -957,7 +957,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // Check for skulls slamming into things if (tm.thing->flags & MF_SKULLFLY) { - bool res = tm.thing->Slam (tm.thing->BlockingMobj); + bool res = tm.thing->Slam(tm.thing->BlockingMobj); tm.thing->BlockingMobj = NULL; return res; } @@ -980,15 +980,15 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // ideally this should take the mass factor into account thing->velx += tm.thing->velx; thing->vely += tm.thing->vely; - if ((thing->velx + thing->vely) > 3*FRACUNIT) + if ((thing->velx + thing->vely) > 3 * FRACUNIT) { int newdam; damage = (tm.thing->Mass / 100) + 1; - newdam = P_DamageMobj (thing, tm.thing, tm.thing, damage, tm.thing->DamageType); - P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); + newdam = P_DamageMobj(thing, tm.thing, tm.thing, damage, tm.thing->DamageType); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, tm.thing); damage = (thing->Mass / 100) + 1; - newdam = P_DamageMobj (tm.thing, thing, thing, damage >> 2, tm.thing->DamageType); - P_TraceBleed (newdam > 0 ? newdam : damage, tm.thing, thing); + newdam = P_DamageMobj(tm.thing, thing, thing, damage >> 2, tm.thing->DamageType); + P_TraceBleed(newdam > 0 ? newdam : damage, tm.thing, thing); } return false; } @@ -1007,7 +1007,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) return true; } - if ((tm.thing->flags6 & MF6_MTHRUSPECIES) + if ((tm.thing->flags6 & MF6_MTHRUSPECIES) && tm.thing->target // NULL pointer check && (tm.thing->target->GetSpecies() == thing->GetSpecies())) return true; @@ -1019,8 +1019,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } int clipheight; - - if (thing->projectilepassheight > 0) + + if (thing->projectilepassheight > 0) { clipheight = thing->projectilepassheight; } @@ -1038,7 +1038,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) { // Over thing return true; } - if (tm.thing->z+tm.thing->height < thing->z) + if (tm.thing->z + tm.thing->height < thing->z) { // Under thing return true; } @@ -1051,7 +1051,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) return (tm.thing->target == thing || !(thing->flags & MF_SOLID)); } - switch (tm.thing->SpecialMissileHit (thing)) + switch (tm.thing->SpecialMissileHit(thing)) { case 0: return false; case 1: return true; @@ -1063,7 +1063,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // [Graf Zahl] Why do I have the feeling that this didn't really work anymore now // that ZDoom supports friendly monsters? - + if (tm.thing->target != NULL) { @@ -1077,10 +1077,10 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) if (!thing->player && !tm.thing->target->player) { int infight; - if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight=1; - else if (level.flags2 & LEVEL2_NOINFIGHTING) infight=-1; + if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight = 1; + else if (level.flags2 & LEVEL2_NOINFIGHTING) infight = -1; else infight = infighting; - + if (infight < 0) { // -1: Monsters cannot hurt each other, but make exceptions for @@ -1092,7 +1092,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) if (thing->flags3 & MF3_ISMONSTER) { // Monsters that are clearly hostile can always hurt each other - if (!thing->IsHostile (tm.thing->target)) + if (!thing->IsHostile(tm.thing->target)) { // The same if the shooter hates the target if (thing->tid == 0 || tm.thing->target->TIDtoHate != thing->tid) @@ -1107,7 +1107,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) { // 0: Monsters cannot hurt same species except // cases where they are clearly supposed to do that - if (thing->IsFriend (tm.thing->target)) + if (thing->IsFriend(tm.thing->target)) { // Friends never harm each other return false; @@ -1121,7 +1121,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) { // Don't hurt same species or any relative - // but only if the target isn't one's hostile. - if (!thing->IsHostile (tm.thing->target)) + if (!thing->IsHostile(tm.thing->target)) { // Allow hurting monsters the shooter hates. if (thing->tid == 0 || tm.thing->target->TIDtoHate != thing->tid) @@ -1152,11 +1152,11 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) if (!(thing->flags & MF_NOBLOOD) && !(thing->flags2 & MF2_REFLECTIVE) && !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && - !(thing->flags2 & (MF2_INVULNERABLE|MF2_DORMANT))) + !(thing->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) { // Ok to spawn blood - P_RipperBlood (tm.thing, thing); + P_RipperBlood(tm.thing, thing); } - S_Sound (tm.thing, CHAN_BODY, "misc/ripslop", 1, ATTN_IDLE); + S_Sound(tm.thing, CHAN_BODY, "misc/ripslop", 1, ATTN_IDLE); // Do poisoning (if using new style poison) if (tm.thing->PoisonDamage > 0 && tm.thing->PoisonDuration != INT_MIN) @@ -1164,11 +1164,11 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) P_PoisonMobj(thing, tm.thing, tm.thing->target, tm.thing->PoisonDamage, tm.thing->PoisonDuration, tm.thing->PoisonPeriod, tm.thing->PoisonDamageType); } - damage = tm.thing->GetMissileDamage (3, 2); - int newdam = P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); + damage = tm.thing->GetMissileDamage(3, 2); + int newdam = P_DamageMobj(thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { - P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, tm.thing); } if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) @@ -1181,7 +1181,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } } } - spechit.Clear (); + spechit.Clear(); return true; } } @@ -1193,30 +1193,30 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } // Do damage - damage = tm.thing->GetMissileDamage ((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1); - if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN)) + damage = tm.thing->GetMissileDamage((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1); + if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN)) { - int newdam = P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); + int newdam = P_DamageMobj(thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); if (damage > 0) { if ((tm.thing->flags5 & MF5_BLOODSPLATTER) && !(thing->flags & MF_NOBLOOD) && !(thing->flags2 & MF2_REFLECTIVE) && - !(thing->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)) && + !(thing->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)) && !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && (pr_checkthing() < 192)) { - P_BloodSplatter (tm.thing->x, tm.thing->y, tm.thing->z, thing); + P_BloodSplatter(tm.thing->x, tm.thing->y, tm.thing->z, thing); } if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { - P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, tm.thing); } } } else { - P_GiveBody (thing, -damage); + P_GiveBody(thing, -damage); } return false; // don't traverse any more } @@ -1230,8 +1230,8 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } } solid = (thing->flags & MF_SOLID) && - !(thing->flags & MF_NOCLIP) && - ((tm.thing->flags & MF_SOLID) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS)); + !(thing->flags & MF_NOCLIP) && + ((tm.thing->flags & MF_SOLID) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS)); // Check for special pickup if ((thing->flags & MF_SPECIAL) && (tm.thing->flags & MF_PICKUP) @@ -1240,7 +1240,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // up things that are above your true height. && thing->z < tm.thing->z + tm.thing->height - tm.thing->MaxStepHeight) { // Can be picked up by tmthing - P_TouchSpecialThing (thing, tm.thing); // can remove thing + P_TouchSpecialThing(thing, tm.thing); // can remove thing } // killough 3/16/98: Allow non-solid moving objects to move through solid @@ -1258,7 +1258,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) /* =============================================================================== - MOVEMENT CLIPPING +MOVEMENT CLIPPING =============================================================================== */ @@ -1290,7 +1290,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) // //========================================================================== -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly) +bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly) { sector_t *newsec; AActor *thingblocker; @@ -1301,13 +1301,13 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b tm.x = x; tm.y = y; - newsec = P_PointInSector (x,y); + newsec = P_PointInSector(x, y); tm.ceilingline = thing->BlockingLine = NULL; - -// The base floor / ceiling is from the subsector that contains the point. -// Any contacted lines the step closer together will adjust them. - tm.floorz = tm.dropoffz = newsec->floorplane.ZatPoint (x, y); - tm.ceilingz = newsec->ceilingplane.ZatPoint (x, y); + + // The base floor / ceiling is from the subsector that contains the point. + // Any contacted lines the step closer together will adjust them. + tm.floorz = tm.dropoffz = newsec->floorplane.ZatPoint(x, y); + tm.ceilingz = newsec->ceilingplane.ZatPoint(x, y); tm.floorpic = newsec->GetTexture(sector_t::floor); tm.floorsector = newsec; tm.ceilingpic = newsec->GetTexture(sector_t::ceiling); @@ -1317,7 +1317,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b //Added by MC: Fill the tmsector. tm.sector = newsec; - + #ifdef _3DFLOORS //Check 3D floors if (!thing->IsNoClip2() && newsec->e->XFloor.ffloors.Size()) @@ -1325,25 +1325,25 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b F3DFloor* rover; fixed_t delta1; fixed_t delta2; - int thingtop = thing->z + (thing->height==0? 1:thing->height); - - for(unsigned i=0;ie->XFloor.ffloors.Size();i++) + int thingtop = thing->z + (thing->height == 0 ? 1 : thing->height); + + for (unsigned i = 0; ie->XFloor.ffloors.Size(); i++) { rover = newsec->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y); - fixed_t ff_top=rover->top.plane->ZatPoint(x, y); - - delta1 = thing->z - (ff_bottom + ((ff_top-ff_bottom)/2)); - delta2 = thingtop - (ff_bottom + ((ff_top-ff_bottom)/2)); + fixed_t ff_bottom = rover->bottom.plane->ZatPoint(x, y); + fixed_t ff_top = rover->top.plane->ZatPoint(x, y); - if(ff_top > tm.floorz && abs(delta1) < abs(delta2)) + delta1 = thing->z - (ff_bottom + ((ff_top - ff_bottom) / 2)); + delta2 = thingtop - (ff_bottom + ((ff_top - ff_bottom) / 2)); + + if (ff_top > tm.floorz && abs(delta1) < abs(delta2)) { tm.floorz = tm.dropoffz = ff_top; tm.floorpic = *rover->top.texture; } - if(ff_bottom < tm.ceilingz && abs(delta1) >= abs(delta2)) + if (ff_bottom < tm.ceilingz && abs(delta1) >= abs(delta2)) { tm.ceilingz = ff_bottom; tm.ceilingpic = *rover->bottom.texture; @@ -1351,13 +1351,13 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b } } #endif - + validcount++; - spechit.Clear (); + spechit.Clear(); if ((thing->flags & MF_NOCLIP) && !(thing->flags & MF_SKULLFLY)) return true; - + // Check things first, possibly picking things up. thing->BlockingMobj = NULL; thingblocker = NULL; @@ -1376,9 +1376,9 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b { if (!PIT_CheckThing(th, tm)) { // [RH] If a thing can be stepped up on, we need to continue checking - // other things in the blocks and see if we hit something that is - // definitely blocking. Otherwise, we need to check the lines, or we - // could end up stuck inside a wall. + // other things in the blocks and see if we hit something that is + // definitely blocking. Otherwise, we need to check the lines, or we + // could end up stuck inside a wall. AActor *BlockingMobj = thing->BlockingMobj; if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ)) @@ -1386,8 +1386,8 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b thing->height = realheight; return false; } - else if (!BlockingMobj->player && !(thing->flags & (MF_FLOAT|MF_MISSILE|MF_SKULLFLY)) && - BlockingMobj->z+BlockingMobj->height-thing->z <= thing->MaxStepHeight) + else if (!BlockingMobj->player && !(thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY)) && + BlockingMobj->z + BlockingMobj->height - thing->z <= thing->MaxStepHeight) { if (thingblocker == NULL || BlockingMobj->z > thingblocker->z) @@ -1401,7 +1401,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b { if (thingblocker) { // There is something to step up on. Return this thing as - // the blocker so that we don't step up. + // the blocker so that we don't step up. thing->height = realheight; return false; } @@ -1469,7 +1469,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b return (thing->BlockingMobj = thingblocker) == NULL; } -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly) +bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, bool actorsonly) { FCheckPosition tm; return P_CheckPosition(thing, x, y, tm, actorsonly); @@ -1484,7 +1484,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly) // //---------------------------------------------------------------------------- -bool P_TestMobjLocation (AActor *mobj) +bool P_TestMobjLocation(AActor *mobj) { int flags; @@ -1511,15 +1511,15 @@ bool P_TestMobjLocation (AActor *mobj) // Checks if the new Z position is legal //============================================================================= -AActor *P_CheckOnmobj (AActor *thing) +AActor *P_CheckOnmobj(AActor *thing) { fixed_t oldz; bool good; AActor *onmobj; oldz = thing->z; - P_FakeZMovement (thing); - good = P_TestMobjZ (thing, false, &onmobj); + P_FakeZMovement(thing); + good = P_TestMobjZ(thing, false, &onmobj); thing->z = oldz; return good ? NULL : onmobj; @@ -1531,7 +1531,7 @@ AActor *P_CheckOnmobj (AActor *thing) // //============================================================================= -bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj) +bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj) { AActor *onmobj = NULL; if (actor->flags & MF_NOCLIP) @@ -1561,7 +1561,7 @@ bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj) { // Can't hit thing continue; } - if (thing->flags & (MF_SPECIAL|MF_NOCLIP)) + if (thing->flags & (MF_SPECIAL | MF_NOCLIP)) { // [RH] Specials and noclippers don't block moves continue; } @@ -1582,11 +1582,11 @@ bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj) { // Don't clip against whoever shot the missile. continue; } - if (actor->z > thing->z+thing->height) + if (actor->z > thing->z + thing->height) { // over thing continue; } - else if (actor->z+actor->height <= thing->z) + else if (actor->z + actor->height <= thing->z) { // under thing continue; } @@ -1609,32 +1609,32 @@ bool P_TestMobjZ (AActor *actor, bool quick, AActor **pOnmobj) // Fake the zmovement so that we can check if a move is legal //============================================================================= -void P_FakeZMovement (AActor *mo) +void P_FakeZMovement(AActor *mo) { -// -// adjust height -// + // + // adjust height + // mo->z += mo->velz; if ((mo->flags&MF_FLOAT) && mo->target) { // float down towards target if too close if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT)) { - fixed_t dist = P_AproxDistance (mo->x - mo->target->x, mo->y - mo->target->y); - fixed_t delta = (mo->target->z + (mo->height>>1)) - mo->z; - if (delta < 0 && dist < -(delta*3)) + fixed_t dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y); + fixed_t delta = (mo->target->z + (mo->height >> 1)) - mo->z; + if (delta < 0 && dist < -(delta * 3)) mo->z -= mo->FloatSpeed; - else if (delta > 0 && dist < (delta*3)) + else if (delta > 0 && dist < (delta * 3)) mo->z += mo->FloatSpeed; } } if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz) && !mo->IsNoClip2()) { - mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8; + mo->z += finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8; } -// -// clip movement -// + // + // clip movement + // if (mo->z <= mo->floorz) { // hit the floor mo->z = mo->floorz; @@ -1652,13 +1652,13 @@ void P_FakeZMovement (AActor *mo) // //=========================================================================== -static void CheckForPushSpecial (line_t *line, int side, AActor *mobj, bool windowcheck) +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windowcheck) { if (line->special && !(mobj->flags6 & MF6_NOTRIGGER)) { if (windowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) { // Make sure this line actually blocks us and is not a window - // or similar construct we are standing inside of. + // or similar construct we are standing inside of. fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(mobj->x, mobj->y); fixed_t fzb = line->frontsector->floorplane.ZatPoint(mobj->x, mobj->y); fixed_t bzt = line->backsector->ceilingplane.ZatPoint(mobj->x, mobj->y); @@ -1667,29 +1667,29 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj, bool wind fzb <= mobj->z && bzb <= mobj->z) { // we must also check if some 3D floor in the backsector may be blocking - #ifdef _3DFLOORS - for(unsigned int i=0;ibacksector->e->XFloor.ffloors.Size();i++) +#ifdef _3DFLOORS + for (unsigned int i = 0; ibacksector->e->XFloor.ffloors.Size(); i++) + { + F3DFloor* rover = line->backsector->e->XFloor.ffloors[i]; + + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + + fixed_t ff_bottom = rover->bottom.plane->ZatPoint(mobj->x, mobj->y); + fixed_t ff_top = rover->top.plane->ZatPoint(mobj->x, mobj->y); + + if (ff_bottom < mobj->z + mobj->height && ff_top > mobj->z) { - F3DFloor* rover = line->backsector->e->XFloor.ffloors[i]; - - if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(mobj->x, mobj->y); - fixed_t ff_top = rover->top.plane->ZatPoint(mobj->x, mobj->y); - - if (ff_bottom < mobj->z + mobj->height && ff_top > mobj->z) - { - goto isblocking; - } + goto isblocking; } - #endif + } +#endif return; } } -isblocking: + isblocking: if (mobj->flags2 & MF2_PUSHWALL) { - P_ActivateLine (line, mobj, side, SPAC_Push); + P_ActivateLine(line, mobj, side, SPAC_Push); } else if (mobj->flags2 & MF2_IMPACT) { @@ -1697,13 +1697,13 @@ isblocking: !(mobj->flags & MF_MISSILE) || (mobj->target == NULL)) { - P_ActivateLine (line, mobj, side, SPAC_Impact); + P_ActivateLine(line, mobj, side, SPAC_Impact); } else { - P_ActivateLine (line, mobj->target, side, SPAC_Impact); + P_ActivateLine(line, mobj->target, side, SPAC_Impact); } - } + } } } @@ -1715,11 +1715,11 @@ isblocking: // //========================================================================== -bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, - int dropoff, // killough 3/15/98: allow dropoff as option - const secplane_t *onfloor, // [RH] Let P_TryMove keep the thing on the floor - FCheckPosition &tm, - bool missileCheck) // [GZ] Fired missiles ignore the drop-off test +bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, + int dropoff, // killough 3/15/98: allow dropoff as option + const secplane_t *onfloor, // [RH] Let P_TryMove keep the thing on the floor + FCheckPosition &tm, + bool missileCheck) // [GZ] Fired missiles ignore the drop-off test { fixed_t oldx; fixed_t oldy; @@ -1734,10 +1734,10 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, oldz = thing->z; if (onfloor) { - thing->z = onfloor->ZatPoint (x, y); + thing->z = onfloor->ZatPoint(x, y); } thing->flags6 |= MF6_INTRYMOVE; - if (!P_CheckPosition (thing, x, y, tm)) + if (!P_CheckPosition(thing, x, y, tm)) { AActor *BlockingMobj = thing->BlockingMobj; // Solid wall or thing @@ -1751,11 +1751,11 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, { goto pushline; } - else if (BlockingMobj->z+BlockingMobj->height-thing->z + else if (BlockingMobj->z + BlockingMobj->height - thing->z > thing->MaxStepHeight - || (BlockingMobj->Sector->ceilingplane.ZatPoint (x, y) - - (BlockingMobj->z+BlockingMobj->height) < thing->height) - || (tm.ceilingz-(BlockingMobj->z+BlockingMobj->height) + || (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y) + - (BlockingMobj->z + BlockingMobj->height) < thing->height) + || (tm.ceilingz - (BlockingMobj->z + BlockingMobj->height) < thing->height)) { goto pushline; @@ -1790,7 +1790,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, } tm.floatok = true; - + if (!(thing->flags & MF_TELEPORT) && tm.ceilingz - thing->z < thing->height && !(thing->flags3 & MF3_CEILINGHUGGER) @@ -1801,19 +1801,19 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, if (thing->flags2 & MF2_FLY && thing->flags & MF_NOGRAVITY) { #if 1 - if (thing->z+thing->height > tm.ceilingz) + if (thing->z + thing->height > tm.ceilingz) goto pushline; #else // When flying, slide up or down blocking lines until the actor // is not blocked. - if (thing->z+thing->height > tm.ceilingz) + if (thing->z + thing->height > tm.ceilingz) { - thing->velz = -8*FRACUNIT; + thing->velz = -8 * FRACUNIT; goto pushline; } - else if (thing->z < tm.floorz && tm.floorz-tm.dropoffz > thing->MaxDropOffHeight) + else if (thing->z < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight) { - thing->velz = 8*FRACUNIT; + thing->velz = 8 * FRACUNIT; goto pushline; } #endif @@ -1824,7 +1824,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, { // [RH] Don't let normal missiles climb steps goto pushline; } - if (tm.floorz-thing->z > thing->MaxStepHeight) + if (tm.floorz - thing->z > thing->MaxStepHeight) { // too big a step up goto pushline; } @@ -1833,7 +1833,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, fixed_t savedz = thing->z; bool good; thing->z = tm.floorz; - good = P_TestMobjZ (thing); + good = P_TestMobjZ(thing); thing->z = savedz; if (!good) { @@ -1848,7 +1848,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, // If it's a bouncer, let it bounce off its new floor, too. if (thing->BounceFlags & BOUNCE_Floors) { - thing->FloorBounceMissile (tm.floorsector->floorplane); + thing->FloorBounceMissile(tm.floorsector->floorplane); } else { @@ -1866,15 +1866,15 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, dropoff = false; } - if (dropoff==2 && // large jump down (e.g. dogs) - (tm.floorz-tm.dropoffz > 128*FRACUNIT || thing->target == NULL || thing->target->z >tm.dropoffz)) + if (dropoff == 2 && // large jump down (e.g. dogs) + (tm.floorz - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->z >tm.dropoffz)) { dropoff = false; } // killough 3/15/98: Allow certain objects to drop off - if ((!dropoff && !(thing->flags & (MF_DROPOFF|MF_FLOAT|MF_MISSILE))) || (thing->flags5&MF5_NODROPOFF)) + if ((!dropoff && !(thing->flags & (MF_DROPOFF | MF_FLOAT | MF_MISSILE))) || (thing->flags5&MF5_NODROPOFF)) { if (!(thing->flags5&MF5_AVOIDINGDROPOFF)) { @@ -1885,11 +1885,11 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, { floorz = MAX(thing->z, tm.floorz); } - + if (floorz - tm.dropoffz > thing->MaxDropOffHeight && - !(thing->flags2 & MF2_BLASTED) && !missileCheck) + !(thing->flags2 & MF2_BLASTED) && !missileCheck) { // Can't move over a dropoff unless it's been blasted - // [GZ] Or missile-spawned + // [GZ] Or missile-spawned thing->z = oldz; thing->flags6 &= ~MF6_INTRYMOVE; return false; @@ -1909,18 +1909,18 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, } if (thing->flags2 & MF2_CANTLEAVEFLOORPIC && (tm.floorpic != thing->floorpic - || tm.floorz - thing->z != 0)) + || tm.floorz - thing->z != 0)) { // must stay within a sector of a certain floor type thing->z = oldz; thing->flags6 &= ~MF6_INTRYMOVE; return false; } - + //Added by MC: To prevent bot from getting into dangerous sectors. if (thing->player && thing->player->isbot && thing->flags & MF_SHOOTABLE) { if (tm.sector != thing->Sector - && bglobal.IsDangerous (tm.sector)) + && bglobal.IsDangerous(tm.sector)) { thing->player->prev = thing->player->dest; thing->player->dest = NULL; @@ -1930,7 +1930,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, thing->flags6 &= ~MF6_INTRYMOVE; return false; } - } + } } // [RH] Check status of eyes against fake floor/ceiling in case @@ -1938,7 +1938,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, bool oldAboveFakeFloor, oldAboveFakeCeiling; fixed_t viewheight; - + viewheight = thing->player ? thing->player->viewheight : thing->height / 2; oldAboveFakeFloor = oldAboveFakeCeiling = false; // pacify GCC @@ -1946,21 +1946,21 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, { fixed_t eyez = oldz + viewheight; - oldAboveFakeFloor = eyez > oldsec->heightsec->floorplane.ZatPoint (thing->x, thing->y); - oldAboveFakeCeiling = eyez > oldsec->heightsec->ceilingplane.ZatPoint (thing->x, thing->y); + oldAboveFakeFloor = eyez > oldsec->heightsec->floorplane.ZatPoint(thing->x, thing->y); + oldAboveFakeCeiling = eyez > oldsec->heightsec->ceilingplane.ZatPoint(thing->x, thing->y); } // Borrowed from MBF: if (thing->BounceFlags & BOUNCE_MBF && // killough 8/13/98 - !(thing->flags & (MF_MISSILE|MF_NOGRAVITY)) && - !thing->IsSentient() && tm.floorz - thing->z > 16*FRACUNIT) + !(thing->flags & (MF_MISSILE | MF_NOGRAVITY)) && + !thing->IsSentient() && tm.floorz - thing->z > 16 * FRACUNIT) { // too big a step up for MBF bouncers under gravity thing->flags6 &= ~MF6_INTRYMOVE; return false; } // the move is ok, so link the thing into its new position - thing->UnlinkFromWorld (); + thing->UnlinkFromWorld(); oldx = thing->x; oldy = thing->y; @@ -1974,11 +1974,11 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, thing->x = x; thing->y = y; - thing->LinkToWorld (); + thing->LinkToWorld(); if (thing->flags2 & MF2_FLOORCLIP) { - thing->AdjustFloorClip (); + thing->AdjustFloorClip(); } // [RH] Don't activate anything if just predicting @@ -1989,36 +1989,36 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, } // if any special lines were hit, do the effect - if (!(thing->flags & (MF_TELEPORT|MF_NOCLIP))) + if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) { - while (spechit.Pop (ld)) + while (spechit.Pop(ld)) { // see if the line was crossed - side = P_PointOnLineSide (thing->x, thing->y, ld); - oldside = P_PointOnLineSide (oldx, oldy, ld); + side = P_PointOnLineSide(thing->x, thing->y, ld); + oldside = P_PointOnLineSide(oldx, oldy, ld); if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) { if (thing->player) { - P_ActivateLine (ld, thing, oldside, SPAC_Cross); + P_ActivateLine(ld, thing, oldside, SPAC_Cross); } else if (thing->flags2 & MF2_MCROSS) { - P_ActivateLine (ld, thing, oldside, SPAC_MCross); + P_ActivateLine(ld, thing, oldside, SPAC_MCross); } else if (thing->flags2 & MF2_PCROSS) { - P_ActivateLine (ld, thing, oldside, SPAC_PCross); + P_ActivateLine(ld, thing, oldside, SPAC_PCross); } else if ((ld->special == Teleport || - ld->special == Teleport_NoFog || - ld->special == Teleport_Line)) + ld->special == Teleport_NoFog || + ld->special == Teleport_Line)) { // [RH] Just a little hack for BOOM compatibility - P_ActivateLine (ld, thing, oldside, SPAC_MCross); + P_ActivateLine(ld, thing, oldside, SPAC_MCross); } else { - P_ActivateLine (ld, thing, oldside, SPAC_AnyCross); + P_ActivateLine(ld, thing, oldside, SPAC_AnyCross); } } } @@ -2030,27 +2030,27 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, { const sector_t *hs = newsec->heightsec; fixed_t eyez = thing->z + viewheight; - fixed_t fakez = hs->floorplane.ZatPoint (x, y); + fixed_t fakez = hs->floorplane.ZatPoint(x, y); if (!oldAboveFakeFloor && eyez > fakez) { // View went above fake floor - newsec->SecActTarget->TriggerAction (thing, SECSPAC_EyesSurface); + newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesSurface); } else if (oldAboveFakeFloor && eyez <= fakez) { // View went below fake floor - newsec->SecActTarget->TriggerAction (thing, SECSPAC_EyesDive); + newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesDive); } if (!(hs->MoreFlags & SECF_FAKEFLOORONLY)) { - fakez = hs->ceilingplane.ZatPoint (x, y); + fakez = hs->ceilingplane.ZatPoint(x, y); if (!oldAboveFakeCeiling && eyez > fakez) { // View went above fake ceiling - newsec->SecActTarget->TriggerAction (thing, SECSPAC_EyesAboveC); + newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesAboveC); } else if (oldAboveFakeCeiling && eyez <= fakez) { // View went below fake ceiling - newsec->SecActTarget->TriggerAction (thing, SECSPAC_EyesBelowC); + newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesBelowC); } } } @@ -2070,29 +2070,29 @@ pushline: } thing->z = oldz; - if (!(thing->flags&(MF_TELEPORT|MF_NOCLIP))) + if (!(thing->flags&(MF_TELEPORT | MF_NOCLIP))) { int numSpecHitTemp; if (tm.thing->flags2 & MF2_BLASTED) { - P_DamageMobj (tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); + P_DamageMobj(tm.thing, NULL, NULL, tm.thing->Mass >> 5, NAME_Melee); } - numSpecHitTemp = (int)spechit.Size (); + numSpecHitTemp = (int)spechit.Size(); while (numSpecHitTemp > 0) { // see which lines were pushed ld = spechit[--numSpecHitTemp]; - side = P_PointOnLineSide (thing->x, thing->y, ld); - CheckForPushSpecial (ld, side, thing, true); + side = P_PointOnLineSide(thing->x, thing->y, ld); + CheckForPushSpecial(ld, side, thing, true); } } return false; } -bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, - int dropoff, // killough 3/15/98: allow dropoff as option - const secplane_t *onfloor) // [RH] Let P_TryMove keep the thing on the floor +bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, + int dropoff, // killough 3/15/98: allow dropoff as option + const secplane_t *onfloor) // [RH] Let P_TryMove keep the thing on the floor { FCheckPosition tm; return P_TryMove(thing, x, y, dropoff, onfloor, tm); @@ -2112,7 +2112,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) FCheckPosition tm; fixed_t newz = thing->z; - if (!P_CheckPosition (thing, x, y, tm)) + if (!P_CheckPosition(thing, x, y, tm)) { return false; } @@ -2142,12 +2142,12 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) } if (thing->flags2 & MF2_FLY && thing->flags & MF_NOGRAVITY) { - if (thing->z+thing->height > tm.ceilingz) + if (thing->z + thing->height > tm.ceilingz) return false; } if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER)) { - if (tm.floorz-newz > thing->MaxStepHeight) + if (tm.floorz - newz > thing->MaxStepHeight) { // too big a step up return false; } @@ -2159,7 +2159,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) { // [RH] Check to make sure there's nothing in the way for the step up fixed_t savedz = thing->z; thing->z = newz = tm.floorz; - bool good = P_TestMobjZ (thing); + bool good = P_TestMobjZ(thing); thing->z = savedz; if (!good) { @@ -2170,7 +2170,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) if (thing->flags2 & MF2_CANTLEAVEFLOORPIC && (tm.floorpic != thing->floorpic - || tm.floorz - newz != 0)) + || tm.floorz - newz != 0)) { // must stay within a sector of a certain floor type return false; } @@ -2202,12 +2202,12 @@ struct FSlide fixed_t tmymove; void HitSlideLine(line_t *ld); - void SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); - void SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps); + void SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); + void SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps); // The bouncing code uses the same data structure - bool BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); - bool BounceWall (AActor *mo); + bool BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); + bool BounceWall(AActor *mo); }; //========================================================================== @@ -2219,17 +2219,17 @@ struct FSlide // //========================================================================== -void FSlide::HitSlideLine (line_t* ld) +void FSlide::HitSlideLine(line_t* ld) { int side; angle_t lineangle; angle_t moveangle; angle_t deltaangle; - + fixed_t movelen; bool icyfloor; // is floor icy? // phares - // | + // | // Under icy conditions, if the angle of approach to the wall // V // is more than 45 degrees, then you'll bounce and lose half // your velocity. If less than 45 degrees, you'll slide along @@ -2238,21 +2238,21 @@ void FSlide::HitSlideLine (line_t* ld) // Check for the special cases of horz or vert walls. // killough 10/98: only bounce if hit hard (prevents wobbling) - icyfloor = - (P_AproxDistance(tmxmove, tmymove) > 4*FRACUNIT) && + icyfloor = + (P_AproxDistance(tmxmove, tmymove) > 4 * FRACUNIT) && var_friction && // killough 8/28/98: calc friction on demand slidemo->z <= slidemo->floorz && - P_GetFriction (slidemo, NULL) > ORIG_FRICTION; + P_GetFriction(slidemo, NULL) > ORIG_FRICTION; if (ld->dx == 0) { // ST_VERTICAL if (icyfloor && (abs(tmxmove) > abs(tmymove))) { - tmxmove = -tmxmove/2; // absorb half the velocity + tmxmove = -tmxmove / 2; // absorb half the velocity tmymove /= 2; if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { - S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff!// ^ + S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff!// ^ } } // | else // phares @@ -2265,10 +2265,10 @@ void FSlide::HitSlideLine (line_t* ld) if (icyfloor && (abs(tmymove) > abs(tmxmove))) { tmxmove /= 2; // absorb half the velocity - tmymove = -tmymove/2; + tmymove = -tmymove / 2; if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { - S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! + S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! } } else @@ -2279,30 +2279,30 @@ void FSlide::HitSlideLine (line_t* ld) // The wall is angled. Bounce if the angle of approach is // phares // less than 45 degrees. // phares - side = P_PointOnLineSide (slidemo->x, slidemo->y, ld); + side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); - lineangle = R_PointToAngle2 (0,0, ld->dx, ld->dy); + lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); if (side == 1) lineangle += ANG180; - moveangle = R_PointToAngle2 (0,0, tmxmove, tmymove); + moveangle = R_PointToAngle2(0, 0, tmxmove, tmymove); moveangle += 10; // prevents sudden path reversal due to // phares - // rounding error // | - deltaangle = moveangle-lineangle; // V - movelen = P_AproxDistance (tmxmove, tmymove); - if (icyfloor && (deltaangle > ANG45) && (deltaangle < ANG90+ANG45)) + // rounding error // | + deltaangle = moveangle - lineangle; // V + movelen = P_AproxDistance(tmxmove, tmymove); + if (icyfloor && (deltaangle > ANG45) && (deltaangle < ANG90 + ANG45)) { moveangle = lineangle - deltaangle; movelen /= 2; // absorb if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { - S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! + S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! } moveangle >>= ANGLETOFINESHIFT; - tmxmove = FixedMul (movelen, finecosine[moveangle]); - tmymove = FixedMul (movelen, finesine[moveangle]); + tmxmove = FixedMul(movelen, finecosine[moveangle]); + tmymove = FixedMul(movelen, finesine[moveangle]); } // ^ else // | { // phares @@ -2311,7 +2311,7 @@ void FSlide::HitSlideLine (line_t* ld) if (i_compatflags & COMPATF_WALLRUN) { fixed_t newlen; - + if (deltaangle > ANG180) deltaangle += ANG180; // I_Error ("SlideLine: ang>ANG180"); @@ -2319,17 +2319,17 @@ void FSlide::HitSlideLine (line_t* ld) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - newlen = FixedMul (movelen, finecosine[deltaangle]); + newlen = FixedMul(movelen, finecosine[deltaangle]); - tmxmove = FixedMul (newlen, finecosine[lineangle]); - tmymove = FixedMul (newlen, finesine[lineangle]); + tmxmove = FixedMul(newlen, finecosine[lineangle]); + tmymove = FixedMul(newlen, finesine[lineangle]); } else { divline_t dll, dlv; fixed_t inter1, inter2, inter3; - P_MakeDivline (ld, &dll); + P_MakeDivline(ld, &dll); dlv.x = slidemo->x; dlv.y = slidemo->y; @@ -2340,13 +2340,13 @@ void FSlide::HitSlideLine (line_t* ld) dlv.dx = tmxmove; dlv.dy = tmymove; - inter2 = P_InterceptVector (&dll, &dlv); - inter3 = P_InterceptVector (&dlv, &dll); + inter2 = P_InterceptVector(&dll, &dlv); + inter3 = P_InterceptVector(&dlv, &dll); if (inter3 != 0) { - tmxmove = Scale (inter2-inter1, dll.dx, inter3); - tmymove = Scale (inter2-inter1, dll.dy, inter3); + tmxmove = Scale(inter2 - inter1, dll.dx, inter3); + tmymove = Scale(inter2 - inter1, dll.dy, inter3); } else { @@ -2363,7 +2363,7 @@ void FSlide::HitSlideLine (line_t* ld) // //========================================================================== -void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) +void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) { FLineOpening open; FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES); @@ -2372,26 +2372,26 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ while ((in = it.Next())) { line_t* li; - + if (!in->isaline) { // should never happen - Printf ("PTR_SlideTraverse: not a line?"); + Printf("PTR_SlideTraverse: not a line?"); continue; } - + li = in->d.line; - - if ( !(li->flags & ML_TWOSIDED) || !li->backsector ) + + if (!(li->flags & ML_TWOSIDED) || !li->backsector) { - if (P_PointOnLineSide (slidemo->x, slidemo->y, li)) + if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) { // don't hit the back side - continue; + continue; } goto isblocking; } - if (li->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) + if (li->flags & (ML_BLOCKING | ML_BLOCKEVERYTHING)) { goto isblocking; } @@ -2406,12 +2406,12 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ } // set openrange, opentop, openbottom - P_LineOpening (open, slidemo, li, it.Trace().x + FixedMul (it.Trace().dx, in->frac), - it.Trace().y + FixedMul (it.Trace().dy, in->frac)); - + P_LineOpening(open, slidemo, li, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); + if (open.range < slidemo->height) goto isblocking; // doesn't fit - + if (open.top - slidemo->z < slidemo->height) goto isblocking; // mobj is too high @@ -2423,7 +2423,7 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ { // [RH] Check to make sure there's nothing in the way for the step up fixed_t savedz = slidemo->z; slidemo->z = open.bottom; - bool good = P_TestMobjZ (slidemo); + bool good = P_TestMobjZ(slidemo); slidemo->z = savedz; if (!good) { @@ -2432,11 +2432,11 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ } // this line doesn't block movement - continue; - + continue; + // the line does block movement, // see if it is closer than best so far - isblocking: + isblocking: if (in->frac < bestslidefrac) { secondslidefrac = bestslidefrac; @@ -2444,7 +2444,7 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ bestslidefrac = in->frac; bestslideline = li; } - + return; // stop } } @@ -2463,7 +2463,7 @@ void FSlide::SlideTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_ // //========================================================================== -void FSlide::SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) +void FSlide::SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) { fixed_t leadx, leady; fixed_t trailx, traily; @@ -2477,11 +2477,11 @@ void FSlide::SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) if (mo->player && mo->player->mo == mo && mo->reactiontime > 0) return; // player coming right out of a teleporter. - - retry: + +retry: if (!--hitcount) goto stairstep; // don't loop forever - + // trace along the three leading corners if (tryx > 0) { @@ -2505,42 +2505,42 @@ void FSlide::SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) traily = mo->y + mo->radius; } - bestslidefrac = FRACUNIT+1; - - SlideTraverse (leadx, leady, leadx+tryx, leady+tryy); - SlideTraverse (trailx, leady, trailx+tryx, leady+tryy); - SlideTraverse (leadx, traily, leadx+tryx, traily+tryy); + bestslidefrac = FRACUNIT + 1; + + SlideTraverse(leadx, leady, leadx + tryx, leady + tryy); + SlideTraverse(trailx, leady, trailx + tryx, leady + tryy); + SlideTraverse(leadx, traily, leadx + tryx, traily + tryy); // move up to the wall - if (bestslidefrac == FRACUNIT+1) + if (bestslidefrac == FRACUNIT + 1) { // the move must have hit the middle, so stairstep - stairstep: + stairstep: // killough 3/15/98: Allow objects to drop off ledges xmove = 0, ymove = tryy; - walkplane = P_CheckSlopeWalk (mo, xmove, ymove); - if (!P_TryMove (mo, mo->x + xmove, mo->y + ymove, true, walkplane)) + walkplane = P_CheckSlopeWalk(mo, xmove, ymove); + if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true, walkplane)) { xmove = tryx, ymove = 0; - walkplane = P_CheckSlopeWalk (mo, xmove, ymove); - P_TryMove (mo, mo->x + xmove, mo->y + ymove, true, walkplane); + walkplane = P_CheckSlopeWalk(mo, xmove, ymove); + P_TryMove(mo, mo->x + xmove, mo->y + ymove, true, walkplane); } return; } // fudge a bit to make sure it doesn't hit - bestslidefrac -= FRACUNIT/32; + bestslidefrac -= FRACUNIT / 32; if (bestslidefrac > 0) { - newx = FixedMul (tryx, bestslidefrac); - newy = FixedMul (tryy, bestslidefrac); + newx = FixedMul(tryx, bestslidefrac); + newy = FixedMul(tryy, bestslidefrac); // [BL] We need to abandon this function if we end up going through a teleporter const fixed_t startvelx = mo->velx; const fixed_t startvely = mo->vely; // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove (mo, mo->x+newx, mo->y+newy, true)) + if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) goto stairstep; if (mo->velx != startvelx || mo->vely != startvely) @@ -2548,16 +2548,16 @@ void FSlide::SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) } // Now continue along the wall. - bestslidefrac = FRACUNIT - (bestslidefrac + FRACUNIT/32); // remainder + bestslidefrac = FRACUNIT - (bestslidefrac + FRACUNIT / 32); // remainder if (bestslidefrac > FRACUNIT) bestslidefrac = FRACUNIT; else if (bestslidefrac <= 0) return; - tryx = tmxmove = FixedMul (tryx, bestslidefrac); - tryy = tmymove = FixedMul (tryy, bestslidefrac); + tryx = tmxmove = FixedMul(tryx, bestslidefrac); + tryy = tmymove = FixedMul(tryy, bestslidefrac); - HitSlideLine (bestslideline); // clip the moves + HitSlideLine(bestslideline); // clip the moves mo->velx = tmxmove * numsteps; mo->vely = tmymove * numsteps; @@ -2571,16 +2571,16 @@ void FSlide::SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) mo->player->vely = mo->vely; } - walkplane = P_CheckSlopeWalk (mo, tmxmove, tmymove); + walkplane = P_CheckSlopeWalk(mo, tmxmove, tmymove); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove, true, walkplane)) + if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true, walkplane)) { goto retry; } } -void P_SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) +void P_SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) { FSlide slide; slide.SlideMove(mo, tryx, tryy, numsteps); @@ -2592,7 +2592,7 @@ void P_SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) // //============================================================================ -const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove) +const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymove) { static secplane_t copyplane; if (actor->flags & MF_NOGRAVITY) @@ -2601,40 +2601,40 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo } const secplane_t *plane = &actor->floorsector->floorplane; - fixed_t planezhere = plane->ZatPoint (actor->x, actor->y); + fixed_t planezhere = plane->ZatPoint(actor->x, actor->y); #ifdef _3DFLOORS - for(unsigned int i=0;ifloorsector->e->XFloor.ffloors.Size();i++) + for (unsigned int i = 0; ifloorsector->e->XFloor.ffloors.Size(); i++) { - F3DFloor * rover= actor->floorsector->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + F3DFloor * rover = actor->floorsector->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; fixed_t thisplanez = rover->top.plane->ZatPoint(actor->x, actor->y); - if (thisplanez>planezhere && thisplanez<=actor->z + actor->MaxStepHeight) + if (thisplanez>planezhere && thisplanez <= actor->z + actor->MaxStepHeight) { copyplane = *rover->top.plane; if (copyplane.c<0) copyplane.FlipVert(); plane = ©plane; - planezhere=thisplanez; + planezhere = thisplanez; } } if (actor->floorsector != actor->Sector) { - for(unsigned int i=0;iSector->e->XFloor.ffloors.Size();i++) + for (unsigned int i = 0; iSector->e->XFloor.ffloors.Size(); i++) { - F3DFloor * rover= actor->Sector->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + F3DFloor * rover = actor->Sector->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; fixed_t thisplanez = rover->top.plane->ZatPoint(actor->x, actor->y); - if (thisplanez>planezhere && thisplanez<=actor->z + actor->MaxStepHeight) + if (thisplanez>planezhere && thisplanez <= actor->z + actor->MaxStepHeight) { copyplane = *rover->top.plane; if (copyplane.c<0) copyplane.FlipVert(); plane = ©plane; - planezhere=thisplanez; + planezhere = thisplanez; } } } @@ -2643,7 +2643,7 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo if (actor->floorsector != actor->Sector) { // this additional check prevents sliding on sloped dropoffs - if (planezhere>actor->floorz+4*FRACUNIT) + if (planezhere>actor->floorz + 4 * FRACUNIT) return NULL; } @@ -2659,10 +2659,10 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo destx = actor->x + xmove; desty = actor->y + ymove; - t = TMulScale16 (plane->a, destx, plane->b, desty, plane->c, actor->z) + plane->d; + t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->z) + plane->d; if (t < 0) { // Desired location is behind (below) the plane - // (i.e. Walking up the plane) + // (i.e. Walking up the plane) if (plane->c < STEEPSLOPE) { // Can't climb up slopes of ~45 degrees or more if (actor->flags & MF_NOCLIP) @@ -2674,14 +2674,14 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo const msecnode_t *node; bool dopush = true; - if (plane->c > STEEPSLOPE*2/3) + if (plane->c > STEEPSLOPE * 2 / 3) { for (node = actor->touching_sectorlist; node; node = node->m_tnext) { const sector_t *sec = node->m_sector; if (sec->floorplane.c >= STEEPSLOPE) { - if (sec->floorplane.ZatPoint (destx, desty) >= actor->z - actor->MaxStepHeight) + if (sec->floorplane.ZatPoint(destx, desty) >= actor->z - actor->MaxStepHeight) { dopush = false; break; @@ -2699,8 +2699,8 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo } // Slide the desired location along the plane's normal // so that it lies on the plane's surface - destx -= FixedMul (plane->a, t); - desty -= FixedMul (plane->b, t); + destx -= FixedMul(plane->a, t); + desty -= FixedMul(plane->b, t); xmove = destx - actor->x; ymove = desty - actor->y; return (actor->floorsector == actor->Sector) ? plane : NULL; @@ -2709,9 +2709,9 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo { // Desired location is in front of (above) the plane if (planezhere == actor->z) { // Actor's current spot is on/in the plane, so walk down it - // Same principle as walking up, except reversed - destx += FixedMul (plane->a, t); - desty += FixedMul (plane->b, t); + // Same principle as walking up, except reversed + destx += FixedMul(plane->a, t); + desty += FixedMul(plane->b, t); xmove = destx - actor->x; ymove = desty - actor->y; return (actor->floorsector == actor->Sector) ? plane : NULL; @@ -2727,7 +2727,7 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo // //============================================================================ -bool FSlide::BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) +bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) { FLineOpening open; FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES); @@ -2740,7 +2740,7 @@ bool FSlide::BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed if (!in->isaline) { - Printf ("PTR_BounceTraverse: not a line?"); + Printf("PTR_BounceTraverse: not a line?"); continue; } @@ -2752,14 +2752,14 @@ bool FSlide::BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed } if (!(li->flags&ML_TWOSIDED) || !li->backsector) { - if (P_PointOnLineSide (slidemo->x, slidemo->y, li)) + if (P_PointOnLineSide(slidemo->x, slidemo->y, li)) continue; // don't hit the back side goto bounceblocking; } - P_LineOpening (open, slidemo, li, it.Trace().x + FixedMul (it.Trace().dx, in->frac), - it.Trace().y + FixedMul (it.Trace().dy, in->frac)); // set openrange, opentop, openbottom + P_LineOpening(open, slidemo, li, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); // set openrange, opentop, openbottom if (open.range < slidemo->height) goto bounceblocking; // doesn't fit @@ -2771,7 +2771,7 @@ bool FSlide::BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed continue; // this line doesn't block movement - // the line does block movement, see if it is closer than best so far + // the line does block movement, see if it is closer than best so far bounceblocking: if (in->frac < bestslidefrac) { @@ -2791,7 +2791,7 @@ bool FSlide::BounceTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed // //============================================================================ -bool FSlide::BounceWall (AActor *mo) +bool FSlide::BounceWall(AActor *mo) { fixed_t leadx, leady; int side; @@ -2805,39 +2805,39 @@ bool FSlide::BounceWall (AActor *mo) } slidemo = mo; -// -// trace along the three leading corners -// + // + // trace along the three leading corners + // if (mo->velx > 0) { - leadx = mo->x+mo->radius; + leadx = mo->x + mo->radius; } else { - leadx = mo->x-mo->radius; + leadx = mo->x - mo->radius; } if (mo->vely > 0) { - leady = mo->y+mo->radius; + leady = mo->y + mo->radius; } else { - leady = mo->y-mo->radius; + leady = mo->y - mo->radius; } - bestslidefrac = FRACUNIT+1; + bestslidefrac = FRACUNIT + 1; bestslideline = mo->BlockingLine; - if (BounceTraverse(leadx, leady, leadx+mo->velx, leady+mo->vely) && mo->BlockingLine == NULL) + if (BounceTraverse(leadx, leady, leadx + mo->velx, leady + mo->vely) && mo->BlockingLine == NULL) { // Could not find a wall, so bounce off the floor/ceiling instead. fixed_t floordist = mo->z - mo->floorz; fixed_t ceildist = mo->ceilingz - mo->z; if (floordist <= ceildist) { - mo->FloorBounceMissile (mo->Sector->floorplane); + mo->FloorBounceMissile(mo->Sector->floorplane); return true; } else { - mo->FloorBounceMissile (mo->Sector->ceilingplane); + mo->FloorBounceMissile(mo->Sector->ceilingplane); return true; } } @@ -2851,7 +2851,7 @@ bool FSlide::BounceWall (AActor *mo) } // The amount of bounces is limited - if (mo->bouncecount>0 && --mo->bouncecount==0) + if (mo->bouncecount>0 && --mo->bouncecount == 0) { if (mo->flags & MF_MISSILE) P_ExplodeMissile(mo, line, NULL); @@ -2860,14 +2860,14 @@ bool FSlide::BounceWall (AActor *mo) return true; } - side = P_PointOnLineSide (mo->x, mo->y, line); - lineangle = R_PointToAngle2 (0, 0, line->dx, line->dy); + side = P_PointOnLineSide(mo->x, mo->y, line); + lineangle = R_PointToAngle2(0, 0, line->dx, line->dy); if (side == 1) { lineangle += ANG180; } - moveangle = R_PointToAngle2 (0, 0, mo->velx, mo->vely); - deltaangle = (2*lineangle)-moveangle; + moveangle = R_PointToAngle2(0, 0, mo->velx, mo->vely); + deltaangle = (2 * lineangle) - moveangle; mo->angle = deltaangle; lineangle >>= ANGLETOFINESHIFT; @@ -2877,14 +2877,14 @@ bool FSlide::BounceWall (AActor *mo) movelen = FixedMul(movelen, mo->wallbouncefactor); FBoundingBox box(mo->x, mo->y, mo->radius); - if (box.BoxOnLineSide (line) == -1) + if (box.BoxOnLineSide(line) == -1) { - mo->SetOrigin (mo->x + FixedMul(mo->radius, + mo->SetOrigin(mo->x + FixedMul(mo->radius, finecosine[deltaangle]), mo->y + FixedMul(mo->radius, finesine[deltaangle]), mo->z); } if (movelen < FRACUNIT) { - movelen = 2*FRACUNIT; + movelen = 2 * FRACUNIT; } mo->velx = FixedMul(movelen, finecosine[deltaangle]); mo->vely = FixedMul(movelen, finesine[deltaangle]); @@ -2899,7 +2899,7 @@ bool FSlide::BounceWall (AActor *mo) return true; } -bool P_BounceWall (AActor *mo) +bool P_BounceWall(AActor *mo) { FSlide slide; return slide.BounceWall(mo); @@ -2912,7 +2912,7 @@ bool P_BounceWall (AActor *mo) //========================================================================== extern FRandom pr_bounce; -bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) +bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) { if (mo && BlockingMobj && ((mo->BounceFlags & BOUNCE_AllActors) || ((mo->flags & MF_MISSILE) && (!(mo->flags2 & MF2_RIP) || (BlockingMobj->flags5 & MF5_DONTRIP) || ((mo->flags6 & MF6_NOBOSSRIP) && (BlockingMobj->flags2 & MF2_BOSS))) && (BlockingMobj->flags2 & MF2_REFLECTIVE)) @@ -2924,21 +2924,21 @@ bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) if (!ontop) { fixed_t speed; - angle_t angle = R_PointToAngle2 (BlockingMobj->x, - BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce()%16)-8); - speed = P_AproxDistance (mo->velx, mo->vely); - speed = FixedMul (speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent + angle_t angle = R_PointToAngle2(BlockingMobj->x, + BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce() % 16) - 8); + speed = P_AproxDistance(mo->velx, mo->vely); + speed = FixedMul(speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent mo->angle = angle; angle >>= ANGLETOFINESHIFT; - mo->velx = FixedMul (speed, finecosine[angle]); - mo->vely = FixedMul (speed, finesine[angle]); + mo->velx = FixedMul(speed, finecosine[angle]); + mo->vely = FixedMul(speed, finesine[angle]); mo->PlayBounceSound(true); if (mo->BounceFlags & BOUNCE_UseBounceState) { FName names[] = { NAME_Bounce, NAME_Actor, NAME_Creature }; FState *bouncestate; int count = 2; - + if ((BlockingMobj->flags & MF_SHOOTABLE) && !(BlockingMobj->flags & MF_NOBLOOD)) { count = 3; @@ -2956,7 +2956,7 @@ bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) if (mo->BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - mo->velz -= MulScale15 (FRACUNIT, dot); + mo->velz -= MulScale15(FRACUNIT, dot); if (!(mo->BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { mo->flags |= MF_INBOUNCE; @@ -2981,9 +2981,9 @@ bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) if (abs(mo->velz) < (fixed_t)(mo->Mass * mo->GetGravity() / 64)) mo->velz = 0; } - else if (mo->BounceFlags & (BOUNCE_AutoOff|BOUNCE_AutoOffFloorOnly)) + else if (mo->BounceFlags & (BOUNCE_AutoOff | BOUNCE_AutoOffFloorOnly)) { - if (!(mo->flags & MF_NOGRAVITY) && (mo->velz < 3*FRACUNIT)) + if (!(mo->flags & MF_NOGRAVITY) && (mo->velz < 3 * FRACUNIT)) mo->BounceFlags &= ~BOUNCE_TypeMask; } } @@ -3008,7 +3008,7 @@ struct aim_t fixed_t toppitch, bottompitch; AActor * linetarget; - AActor * thing_friend, * thing_other; + AActor * thing_friend, *thing_other; angle_t pitch_friend, pitch_other; int flags; #ifdef _3DFLOORS @@ -3021,7 +3021,7 @@ struct aim_t bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in); #endif - void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target=NULL); + void AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target = NULL); }; @@ -3034,100 +3034,100 @@ struct aim_t bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in) { sector_t * nextsector; - secplane_t * nexttopplane, * nextbottomplane; - line_t * li=in->d.line; + secplane_t * nexttopplane, *nextbottomplane; + line_t * li = in->d.line; - nextsector=NULL; - nexttopplane=nextbottomplane=NULL; + nextsector = NULL; + nexttopplane = nextbottomplane = NULL; if (li->backsector == NULL) return true; // shouldn't really happen but crashed once for me... - if (li->frontsector->e->XFloor.ffloors.Size() || li->backsector->e->XFloor.ffloors.Size()) - { + if (li->frontsector->e->XFloor.ffloors.Size() || li->backsector->e->XFloor.ffloors.Size()) + { int frontflag; F3DFloor* rover; int highpitch, lowpitch; - fixed_t trX = trace.x + FixedMul (trace.dx, in->frac); - fixed_t trY = trace.y + FixedMul (trace.dy, in->frac); - fixed_t dist = FixedMul (attackrange, in->frac); + fixed_t trX = trace.x + FixedMul(trace.dx, in->frac); + fixed_t trY = trace.y + FixedMul(trace.dy, in->frac); + fixed_t dist = FixedMul(attackrange, in->frac); + - int dir = aimpitch < 0 ? 1 : aimpitch > 0 ? -1 : 0; - + frontflag = P_PointOnLineSide(shootthing->x, shootthing->y, li); - + // 3D floor check. This is not 100% accurate but normally sufficient when // combined with a final sight check - for(int i=1;i<=2;i++) + for (int i = 1; i <= 2; i++) { - sector_t * s=i==1? li->frontsector:li->backsector; + sector_t * s = i == 1 ? li->frontsector : li->backsector; - for(unsigned k=0;ke->XFloor.ffloors.Size();k++) + for (unsigned k = 0; ke->XFloor.ffloors.Size(); k++) { - crossedffloors=true; - rover=s->e->XFloor.ffloors[k]; - - if((rover->flags & FF_SHOOTTHROUGH) || !(rover->flags & FF_EXISTS)) continue; - - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(trX, trY); - fixed_t ff_top=rover->top.plane->ZatPoint(trX, trY); - + crossedffloors = true; + rover = s->e->XFloor.ffloors[k]; - highpitch = -(int)R_PointToAngle2 (0, shootz, dist, ff_top); - lowpitch = -(int)R_PointToAngle2 (0, shootz, dist, ff_bottom); + if ((rover->flags & FF_SHOOTTHROUGH) || !(rover->flags & FF_EXISTS)) continue; - if (highpitch<=toppitch) + fixed_t ff_bottom = rover->bottom.plane->ZatPoint(trX, trY); + fixed_t ff_top = rover->top.plane->ZatPoint(trX, trY); + + + highpitch = -(int)R_PointToAngle2(0, shootz, dist, ff_top); + lowpitch = -(int)R_PointToAngle2(0, shootz, dist, ff_bottom); + + if (highpitch <= toppitch) { // blocks completely - if (lowpitch>=bottompitch) return false; + if (lowpitch >= bottompitch) return false; // blocks upper edge of view - if (lowpitch>toppitch) + if (lowpitch>toppitch) { - toppitch=lowpitch; - if (frontflag!=i-1) + toppitch = lowpitch; + if (frontflag != i - 1) { - nexttopplane=rover->bottom.plane; + nexttopplane = rover->bottom.plane; } } } - else if (lowpitch>=bottompitch) + else if (lowpitch >= bottompitch) { // blocks lower edge of view - if (highpitchtop.plane; + nextbottomplane = rover->top.plane; } } } // trace is leaving a sector with a 3d-floor - if (frontflag==i-1) + if (frontflag == i - 1) { - if (s==lastsector) + if (s == lastsector) { // upper slope intersects with this 3d-floor - if (rover->bottom.plane==lastceilingplane && lowpitch > toppitch) + if (rover->bottom.plane == lastceilingplane && lowpitch > toppitch) { - toppitch=lowpitch; + toppitch = lowpitch; } // lower slope intersects with this 3d-floor - if (rover->top.plane==lastfloorplane && highpitch < bottompitch) + if (rover->top.plane == lastfloorplane && highpitch < bottompitch) { - bottompitch=highpitch; + bottompitch = highpitch; } } } if (toppitch >= bottompitch) return false; // stop } } - } + } - lastsector=nextsector; - lastceilingplane=nexttopplane; - lastfloorplane=nextbottomplane; + lastsector = nextsector; + lastceilingplane = nexttopplane; + lastfloorplane = nextbottomplane; return true; } #endif @@ -3139,9 +3139,9 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in) // //============================================================================ -void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target) +void aim_t::AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target) { - FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS|PT_COMPATIBLE); + FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE); intercept_t *in; while ((in = it.Next())) @@ -3154,35 +3154,35 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e fixed_t dist; int thingpitch; - if (in->isaline) + if (in->isaline) { li = in->d.line; - if ( !(li->flags & ML_TWOSIDED) || (li->flags & ML_BLOCKEVERYTHING) ) + if (!(li->flags & ML_TWOSIDED) || (li->flags & ML_BLOCKEVERYTHING)) return; // stop // Crosses a two sided line. // A two sided line will restrict the possible target ranges. FLineOpening open; - P_LineOpening (open, NULL, li, it.Trace().x + FixedMul (it.Trace().dx, in->frac), - it.Trace().y + FixedMul (it.Trace().dy, in->frac)); + P_LineOpening(open, NULL, li, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); if (open.bottom >= open.top) return; // stop - dist = FixedMul (attackrange, in->frac); + dist = FixedMul(attackrange, in->frac); - pitch = -(int)R_PointToAngle2 (0, shootz, dist, open.bottom); + pitch = -(int)R_PointToAngle2(0, shootz, dist, open.bottom); if (pitch < bottompitch) bottompitch = pitch; - pitch = -(int)R_PointToAngle2 (0, shootz, dist, open.top); + pitch = -(int)R_PointToAngle2(0, shootz, dist, open.top); if (pitch > toppitch) toppitch = pitch; if (toppitch >= bottompitch) return; // stop - + #ifdef _3DFLOORS if (!AimTraverse3DFloors(it.Trace(), in)) return; #endif @@ -3203,11 +3203,11 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e { if (!(flags & ALF_CHECKNONSHOOTABLE)) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags { - if (!(th->flags&MF_SHOOTABLE)) + if (!(th->flags&MF_SHOOTABLE)) continue; // corpse or something // check for physical attacks on a ghost - if ((th->flags3 & MF3_GHOST) && + if ((th->flags3 & MF3_GHOST) && shootthing->player && // [RH] Be sure shootthing is a player shootthing->player->ReadyWeapon && (shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) @@ -3216,7 +3216,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e } } } - dist = FixedMul (attackrange, in->frac); + dist = FixedMul(attackrange, in->frac); // Don't autoaim certain special actors if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED) @@ -3226,26 +3226,26 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e #ifdef _3DFLOORS // we must do one last check whether the trace has crossed a 3D floor - if (lastsector==th->Sector && th->Sector->e->XFloor.ffloors.Size()) + if (lastsector == th->Sector && th->Sector->e->XFloor.ffloors.Size()) { if (lastceilingplane) { - fixed_t ff_top=lastceilingplane->ZatPoint(th->x, th->y); - fixed_t pitch = -(int)R_PointToAngle2 (0, shootz, dist, ff_top); + fixed_t ff_top = lastceilingplane->ZatPoint(th->x, th->y); + fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_top); // upper slope intersects with this 3d-floor if (pitch > toppitch) { - toppitch=pitch; + toppitch = pitch; } } if (lastfloorplane) { - fixed_t ff_bottom=lastfloorplane->ZatPoint(th->x, th->y); - fixed_t pitch = -(int)R_PointToAngle2 (0, shootz, dist, ff_bottom); + fixed_t ff_bottom = lastfloorplane->ZatPoint(th->x, th->y); + fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_bottom); // lower slope intersects with this 3d-floor if (pitch < bottompitch) { - bottompitch=pitch; + bottompitch = pitch; } } } @@ -3253,30 +3253,30 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e // check angles to see if the thing can be aimed at - thingtoppitch = -(int)R_PointToAngle2 (0, shootz, dist, th->z + th->height); + thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->z + th->height); if (thingtoppitch > bottompitch) continue; // shot over the thing - thingbottompitch = -(int)R_PointToAngle2 (0, shootz, dist, th->z); + thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->z); if (thingbottompitch < toppitch) continue; // shot under the thing - + #ifdef _3DFLOORS if (crossedffloors) { // if 3D floors were in the way do an extra visibility check for safety - if (!P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) + if (!P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // the thing can't be seen so we can safely exclude its range from our aiming field - if (thingtoppitchtoppitch) toppitch=thingbottompitch; + if (thingbottompitch>toppitch) toppitch = thingbottompitch; } else if (thingbottompitch>bottompitch) { - if (thingtoppitch bottompitch) thingbottompitch = bottompitch; - - thingpitch = thingtoppitch/2 + thingbottompitch/2; - + + thingpitch = thingtoppitch / 2 + thingbottompitch / 2; + if (flags & ALF_CHECK3D) { // We need to do a 3D distance check here because this is nearly always used in @@ -3302,7 +3302,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT]; if (cosine != 0) { - fixed_t d3 = FixedDiv( FixedMul( P_AproxDistance(it.Trace().dx, it.Trace().dy), in->frac), cosine); + fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it.Trace().dx, it.Trace().dy), in->frac), cosine); if (d3 > attackrange) { return; @@ -3358,8 +3358,8 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e // //============================================================================ -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, - int flags, AActor *target, AActor *friender) +fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, + int flags, AActor *target, AActor *friender) { fixed_t x2; fixed_t y2; @@ -3370,16 +3370,16 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p aim.shootthing = t1; aim.friender = (friender == NULL) ? t1 : friender; - x2 = t1->x + (distance>>FRACBITS)*finecosine[angle]; - y2 = t1->y + (distance>>FRACBITS)*finesine[angle]; - aim.shootz = t1->z + (t1->height>>1) - t1->floorclip; + x2 = t1->x + (distance >> FRACBITS)*finecosine[angle]; + y2 = t1->y + (distance >> FRACBITS)*finesine[angle]; + aim.shootz = t1->z + (t1->height >> 1) - t1->floorclip; if (t1->player != NULL) { - aim.shootz += FixedMul (t1->player->mo->AttackZOffset, t1->player->crouchfactor); + aim.shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); } else { - aim.shootz += 8*FRACUNIT; + aim.shootz += 8 * FRACUNIT; } // can't shoot outside view angles @@ -3387,15 +3387,15 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p { if (t1->player == NULL || !level.IsFreelookAllowed()) { - vrange = ANGLE_1*35; + vrange = ANGLE_1 * 35; } else { // [BB] Disable autoaim on weapons with WIF_NOAUTOAIM. AWeapon *weapon = t1->player->ReadyWeapon; - if ( weapon && (weapon->WeaponFlags & WIF_NOAUTOAIM) ) + if (weapon && (weapon->WeaponFlags & WIF_NOAUTOAIM)) { - vrange = ANGLE_1/2; + vrange = ANGLE_1 / 2; } else { @@ -3403,7 +3403,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p // vrange of 0 degrees, because then toppitch and bottompitch will // be equal, and PTR_AimTraverse will never find anything to shoot at // if it crosses a line. - vrange = clamp (t1->player->userinfo.GetAimDist(), ANGLE_1/2, ANGLE_1*35); + vrange = clamp(t1->player->userinfo.GetAimDist(), ANGLE_1 / 2, ANGLE_1 * 35); } } } @@ -3414,32 +3414,32 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p aim.linetarget = NULL; // for smart aiming - aim.thing_friend=aim.thing_other=NULL; + aim.thing_friend = aim.thing_other = NULL; // Information for tracking crossed 3D floors - aim.aimpitch=t1->pitch; + aim.aimpitch = t1->pitch; #ifdef _3DFLOORS - aim.crossedffloors=t1->Sector->e->XFloor.ffloors.Size()!=0; - aim.lastsector=t1->Sector; - aim.lastfloorplane=aim.lastceilingplane=NULL; + aim.crossedffloors = t1->Sector->e->XFloor.ffloors.Size() != 0; + aim.lastsector = t1->Sector; + aim.lastfloorplane = aim.lastceilingplane = NULL; // set initial 3d-floor info - for(unsigned i=0;iSector->e->XFloor.ffloors.Size();i++) + for (unsigned i = 0; iSector->e->XFloor.ffloors.Size(); i++) { - F3DFloor * rover=t1->Sector->e->XFloor.ffloors[i]; - fixed_t bottomz=rover->bottom.plane->ZatPoint(t1->x, t1->y); + F3DFloor * rover = t1->Sector->e->XFloor.ffloors[i]; + fixed_t bottomz = rover->bottom.plane->ZatPoint(t1->x, t1->y); - if (bottomz>=t1->z+t1->height) aim.lastceilingplane=rover->bottom.plane; + if (bottomz >= t1->z + t1->height) aim.lastceilingplane = rover->bottom.plane; - bottomz=rover->top.plane->ZatPoint(t1->x, t1->y); - if (bottomz<=t1->z) aim.lastfloorplane=rover->top.plane; + bottomz = rover->top.plane->ZatPoint(t1->x, t1->y); + if (bottomz <= t1->z) aim.lastfloorplane = rover->top.plane; } #endif - aim.AimTraverse (t1->x, t1->y, x2, y2, target); + aim.AimTraverse(t1->x, t1->y, x2, y2, target); - if (!aim.linetarget) + if (!aim.linetarget) { if (aim.thing_other) { @@ -3469,9 +3469,11 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p struct Origin { AActor *Caller; + bool hitGhosts; + bool hitSameSpecie; }; -static ETraceStatus CheckForSameSpecie(FTraceResults &res, void *userdata) +static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { @@ -3480,59 +3482,21 @@ static ETraceStatus CheckForSameSpecie(FTraceResults &res, void *userdata) Origin *data = (Origin *)userdata; - // check for physical attacks on the same specie - if (res.Actor->GetSpecies() == data->Caller->GetSpecies() || res.Actor->flags4 & MF4_SPECTRAL) - { - return TRACE_Skip; - } - - return TRACE_Stop; -} -static ETraceStatus CheckForGhost(FTraceResults &res, void *userdata) -{ - if (res.HitType != TRACE_HitActor) - { - return TRACE_Stop; - } - - // check for physical attacks on a ghost - if (res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL) - { - return TRACE_Skip; - } - - return TRACE_Stop; -} -static ETraceStatus CheckForSpecieAndGhost(FTraceResults &res, void *userdata) -{ - if (res.HitType != TRACE_HitActor) - { - return TRACE_Stop; - } - - Origin *data = (Origin *)userdata; - - // check for physical attacks - if (res.Actor->GetSpecies() == data->Caller->GetSpecies() || res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL) - { - return TRACE_Skip; - } - - return TRACE_Stop; -} -static ETraceStatus CheckForSpectral(FTraceResults &res, void *userdata) -{ - if (res.HitType != TRACE_HitActor) - { - return TRACE_Stop; - } - // check for physical attacks on spectrals if (res.Actor->flags4 & MF4_SPECTRAL) { return TRACE_Skip; } + if (data->hitSameSpecie && res.Actor->GetSpecies() == data->Caller->GetSpecies()) + { + return TRACE_Skip; + } + if (data->hitGhosts && res.Actor->flags3 & MF3_GHOST) + { + return TRACE_Skip; + } + return TRACE_Stop; } @@ -3544,8 +3508,8 @@ static ETraceStatus CheckForSpectral(FTraceResults &res, void *userdata) // //========================================================================== -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, const PClass *pufftype, int flags, AActor **victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, + int pitch, int damage, FName damageType, const PClass *pufftype, int flags, AActor **victim, int *actualdamage) { fixed_t vx, vy, vz, shootz; FTraceResults trace; @@ -3558,7 +3522,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, bool killPuff = false; AActor *puff = NULL; int pflag = 0; - int puffFlags = (flags & LAF_ISMELEEATTACK)? PF_MELEERANGE : 0; + int puffFlags = (flags & LAF_ISMELEEATTACK) ? PF_MELEERANGE : 0; if (flags & LAF_NORANDOMPUFFZ) puffFlags |= PF_NORANDOMZ; @@ -3574,14 +3538,14 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, angle >>= ANGLETOFINESHIFT; pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT; - vx = FixedMul (finecosine[pitch], finecosine[angle]); - vy = FixedMul (finecosine[pitch], finesine[angle]); + vx = FixedMul(finecosine[pitch], finecosine[angle]); + vy = FixedMul(finecosine[pitch], finesine[angle]); vz = -finesine[pitch]; - shootz = t1->z - t1->floorclip + (t1->height>>1); + shootz = t1->z - t1->floorclip + (t1->height >> 1); if (t1->player != NULL) { - shootz += FixedMul (t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); if (damageType == NAME_Melee || damageType == NAME_Hitscan) { // this is coming from a weapon attack function which needs to transfer information to the obituary code, @@ -3591,18 +3555,18 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, } else { - shootz += 8*FRACUNIT; + shootz += 8 * FRACUNIT; } // We need to check the defaults of the replacement here AActor *puffDefaults = GetDefaultByType(pufftype->GetReplacement()); - hitGhosts = (t1->player != NULL && + TData.hitGhosts = (t1->player != NULL && t1->player->ReadyWeapon != NULL && (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) || (puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST)); - hitSameSpecie = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES)); + TData.hitSameSpecie = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES)); // if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type. // All other explicitly passed damage types (currenty only MDK) will be preserved. @@ -3614,22 +3578,22 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int tflags; if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky; - else tflags = TRACE_NoSky|TRACE_Impact; + else tflags = TRACE_NoSky | TRACE_Impact; - if (!Trace (t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance, - MF_SHOOTABLE, ML_BLOCKEVERYTHING|ML_BLOCKHITSCAN, t1, trace, - tflags, hitGhosts ? (hitSameSpecie ? CheckForSpecieAndGhost : CheckForGhost) : hitSameSpecie ? CheckForSameSpecie : CheckForSpectral, &TData)) + if (!Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance, + MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, + tflags, CheckForActor, &TData)) { // hit nothing if (puffDefaults == NULL) { } else if (puffDefaults->ActiveSound) { // Play miss sound - S_Sound (t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM); + S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM); } if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) { // Spawn the puff anyway - puff = P_SpawnPuff (t1, pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2, puffFlags); + puff = P_SpawnPuff(t1, pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2, puffFlags); } else { @@ -3645,32 +3609,32 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, // position a bit closer for puffs if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon) { - fixed_t closer = trace.Distance - 4*FRACUNIT; - puff = P_SpawnPuff (t1, pufftype, t1->x + FixedMul (vx, closer), - t1->y + FixedMul (vy, closer), - shootz + FixedMul (vz, closer), angle - ANG90, 0, puffFlags); + fixed_t closer = trace.Distance - 4 * FRACUNIT; + puff = P_SpawnPuff(t1, pufftype, t1->x + FixedMul(vx, closer), + t1->y + FixedMul(vy, closer), + shootz + FixedMul(vz, closer), angle - ANG90, 0, puffFlags); } // [RH] Spawn a decal if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon) - { + { // [TN] If the actor or weapon has a decal defined, use that one. - if(t1->DecalGenerator != NULL || + if (t1->DecalGenerator != NULL || (t1->player != NULL && t1->player->ReadyWeapon != NULL && t1->player->ReadyWeapon->DecalGenerator != NULL)) { - SpawnShootDecal (t1, trace); + SpawnShootDecal(t1, trace); } // Else, look if the bulletpuff has a decal defined. - else if(puff != NULL && puff->DecalGenerator) + else if (puff != NULL && puff->DecalGenerator) { - SpawnShootDecal (puff, trace); - } - + SpawnShootDecal(puff, trace); + } + else { - SpawnShootDecal (t1, trace); - } + SpawnShootDecal(t1, trace); + } } else if (puff != NULL && trace.CrossedWater == NULL && @@ -3679,17 +3643,17 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, { // Using the puff's position is not accurate enough. // Instead make it splash at the actual hit position - hitx = t1->x + FixedMul (vx, trace.Distance); - hity = t1->y + FixedMul (vy, trace.Distance); - hitz = shootz + FixedMul (vz, trace.Distance); - P_HitWater (puff, P_PointInSector(hitx, hity), hitx, hity, hitz); + hitx = t1->x + FixedMul(vx, trace.Distance); + hity = t1->y + FixedMul(vy, trace.Distance); + hitz = shootz + FixedMul(vz, trace.Distance); + P_HitWater(puff, P_PointInSector(hitx, hity), hitx, hity, hitz); } } else { bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) || - (t1->player != NULL && t1->player->ReadyWeapon != NULL && - (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); + (t1->player != NULL && t1->player->ReadyWeapon != NULL && + (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); bool axeBlood = (t1->player != NULL && t1->player->ReadyWeapon != NULL && @@ -3698,21 +3662,21 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, // Hit a thing, so it could be either a puff or blood fixed_t dist = trace.Distance; // position a bit closer for puffs/blood if using compatibility mode. - if (i_compatflags & COMPATF_HITSCAN) dist -= 10*FRACUNIT; - hitx = t1->x + FixedMul (vx, dist); - hity = t1->y + FixedMul (vy, dist); - hitz = shootz + FixedMul (vz, dist); + if (i_compatflags & COMPATF_HITSCAN) dist -= 10 * FRACUNIT; + hitx = t1->x + FixedMul(vx, dist); + hity = t1->y + FixedMul(vy, dist); + hitz = shootz + FixedMul(vz, dist); // Spawn bullet puffs or blood spots, depending on target type. if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) || (trace.Actor->flags & MF_NOBLOOD) || - (trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT))) + (trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) { if (!(trace.Actor->flags & MF_NOBLOOD)) puffFlags |= PF_HITTHINGBLEED; // We must pass the unreplaced puff type here - puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags|PF_HITTHING); + puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING); } // Allow puffs to inflict poison damage, so that hitscans can poison, too. @@ -3733,15 +3697,15 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, { dmgflags |= DMG_NO_ARMOR; } - + if (puff == NULL) - { + { // Since the puff is the damage inflictor we need it here // regardless of whether it is displayed or not. - puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags|PF_HITTHING|PF_TEMPORARY); + puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } - newdam = P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); + newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); if (actualdamage != NULL) { *actualdamage = newdam; @@ -3751,30 +3715,30 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, { if (!bloodsplatter && !axeBlood && !(trace.Actor->flags & MF_NOBLOOD) && - !(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT))) + !(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) { - P_SpawnBlood (hitx, hity, hitz, angle - ANG180, newdam > 0 ? newdam : damage, trace.Actor); + P_SpawnBlood(hitx, hity, hitz, angle - ANG180, newdam > 0 ? newdam : damage, trace.Actor); } - + if (damage) { if (bloodsplatter || axeBlood) { if (!(trace.Actor->flags&MF_NOBLOOD) && - !(trace.Actor->flags2&(MF2_INVULNERABLE|MF2_DORMANT))) + !(trace.Actor->flags2&(MF2_INVULNERABLE | MF2_DORMANT))) { if (axeBlood) { - P_BloodSplatter2 (hitx, hity, hitz, trace.Actor); + P_BloodSplatter2(hitx, hity, hitz, trace.Actor); } if (pr_lineattack() < 192) { - P_BloodSplatter (hitx, hity, hitz, trace.Actor); + P_BloodSplatter(hitx, hity, hitz, trace.Actor); } } } // [RH] Stick blood to walls - P_TraceBleed (newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z, + P_TraceBleed(newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z, trace.Actor, srcangle, srcpitch); } } @@ -3788,10 +3752,10 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, if (puff == NULL) { // Spawn puff just to get a mass for the splash - puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags|PF_HITTHING|PF_TEMPORARY); + puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } - SpawnDeepSplash (t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); + SpawnDeepSplash(t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); } } if (killPuff && puff != NULL) @@ -3802,8 +3766,8 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, return puff; } -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, FName pufftype, int flags, AActor **victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, + int pitch, int damage, FName damageType, FName pufftype, int flags, AActor **victim, int *actualdamage) { const PClass * type = PClass::FindClass(pufftype); if (victim != NULL) @@ -3827,7 +3791,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, // //========================================================================== -void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, angle_t angle, int pitch) +void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, angle_t angle, int pitch) { if (!cl_bloodsplats) return; @@ -3839,7 +3803,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a if ((actor->flags & MF_NOBLOOD) || (actor->flags5 & MF5_NOBLOODDECALS) || - (actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)) || + (actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)) || (actor->player && actor->player->cheats & CF_GODMODE)) { return; @@ -3880,28 +3844,28 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a { FTraceResults bleedtrace; - angle_t bleedang = (angle + ((pr_tracebleed()-128) << noise)) >> ANGLETOFINESHIFT; - angle_t bleedpitch = (angle_t)(pitch + ((pr_tracebleed()-128) << noise)) >> ANGLETOFINESHIFT; - fixed_t vx = FixedMul (finecosine[bleedpitch], finecosine[bleedang]); - fixed_t vy = FixedMul (finecosine[bleedpitch], finesine[bleedang]); + angle_t bleedang = (angle + ((pr_tracebleed() - 128) << noise)) >> ANGLETOFINESHIFT; + angle_t bleedpitch = (angle_t)(pitch + ((pr_tracebleed() - 128) << noise)) >> ANGLETOFINESHIFT; + fixed_t vx = FixedMul(finecosine[bleedpitch], finecosine[bleedang]); + fixed_t vy = FixedMul(finecosine[bleedpitch], finesine[bleedang]); fixed_t vz = -finesine[bleedpitch]; - if (Trace (x, y, z, actor->Sector, - vx, vy, vz, 172*FRACUNIT, 0, ML_BLOCKEVERYTHING, actor, - bleedtrace, TRACE_NoSky)) + if (Trace(x, y, z, actor->Sector, + vx, vy, vz, 172 * FRACUNIT, 0, ML_BLOCKEVERYTHING, actor, + bleedtrace, TRACE_NoSky)) { if (bleedtrace.HitType == TRACE_HitWall) { PalEntry bloodcolor = actor->GetBloodColor(); if (bloodcolor != 0) { - bloodcolor.r>>=1; // the full color is too bright for blood decals - bloodcolor.g>>=1; - bloodcolor.b>>=1; - bloodcolor.a=1; + bloodcolor.r >>= 1; // the full color is too bright for blood decals + bloodcolor.g >>= 1; + bloodcolor.b >>= 1; + bloodcolor.a = 1; } - DImpactDecal::StaticCreate (bloodType, + DImpactDecal::StaticCreate(bloodType, bleedtrace.X, bleedtrace.Y, bleedtrace.Z, bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, @@ -3911,9 +3875,9 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a } } -void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch) +void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch) { - P_TraceBleed (damage, target->x, target->y, target->z + target->height/2, + P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2, target, angle, pitch); } @@ -3923,7 +3887,7 @@ void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch) // //========================================================================== -void P_TraceBleed (int damage, AActor *target, AActor *missile) +void P_TraceBleed(int damage, AActor *target, AActor *missile) { int pitch; @@ -3936,15 +3900,15 @@ void P_TraceBleed (int damage, AActor *target, AActor *missile) { double aim; - aim = atan ((double)missile->velz / (double)P_AproxDistance (missile->x - target->x, missile->y - target->y)); - pitch = -(int)(aim * ANGLE_180/PI); + aim = atan((double)missile->velz / (double)P_AproxDistance(missile->x - target->x, missile->y - target->y)); + pitch = -(int)(aim * ANGLE_180 / PI); } else { pitch = 0; } - P_TraceBleed (damage, target->x, target->y, target->z + target->height/2, - target, R_PointToAngle2 (missile->x, missile->y, target->x, target->y), + P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2, + target, R_PointToAngle2(missile->x, missile->y, target->x, target->y), pitch); } @@ -3954,14 +3918,14 @@ void P_TraceBleed (int damage, AActor *target, AActor *missile) // //========================================================================== -void P_TraceBleed (int damage, AActor *target) +void P_TraceBleed(int damage, AActor *target) { if (target != NULL) { fixed_t one = pr_tracebleed() << 24; - fixed_t two = (pr_tracebleed()-128) << 16; + fixed_t two = (pr_tracebleed() - 128) << 16; - P_TraceBleed (damage, target->x, target->y, target->z + target->height/2, + P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2, target, one, two); } } @@ -3984,7 +3948,7 @@ struct RailData bool StopAtInvul; }; -static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) +static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) { RailData *data = (RailData *)userdata; if (res.HitType != TRACE_HitActor) @@ -4001,8 +3965,8 @@ static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) // Save this thing for damaging later, and continue the trace SRailHit newhit; newhit.HitActor = res.Actor; - newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front - data->RailHits.Push (newhit); + newhit.Distance = res.Distance - 10 * FRACUNIT; // put blood in front + data->RailHits.Push(newhit); return data->StopAtOne ? TRACE_Stop : TRACE_Continue; } @@ -4012,7 +3976,7 @@ static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) // // //========================================================================== -void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, int color1, int color2, float maxdiff, int railflags, const PClass *puffclass, angle_t angleoffset, angle_t pitchoffset, fixed_t distance, int duration, float sparsity, float drift, const PClass *spawnclass) +void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, int color1, int color2, float maxdiff, int railflags, const PClass *puffclass, angle_t angleoffset, angle_t pitchoffset, fixed_t distance, int duration, float sparsity, float drift, const PClass *spawnclass) { fixed_t vx, vy, vz; angle_t angle, pitch; @@ -4026,8 +3990,8 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, pitch = ((angle_t)(-source->pitch) + pitchoffset) >> ANGLETOFINESHIFT; angle = (source->angle + angleoffset) >> ANGLETOFINESHIFT; - vx = FixedMul (finecosine[pitch], finecosine[angle]); - vy = FixedMul (finecosine[pitch], finesine[angle]); + vx = FixedMul(finecosine[pitch], finecosine[angle]); + vy = FixedMul(finecosine[pitch], finesine[angle]); vz = finesine[pitch]; x1 = source->x; @@ -4039,11 +4003,11 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, { if (source->player != NULL) { - shootz += FixedMul (source->player->mo->AttackZOffset, source->player->crouchfactor); + shootz += FixedMul(source->player->mo->AttackZOffset, source->player->crouchfactor); } else { - shootz += 8*FRACUNIT; + shootz += 8 * FRACUNIT; } } @@ -4061,12 +4025,12 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, int flags; assert(puffclass != NULL); // Because we set it to a default above - AActor *puffDefaults = GetDefaultByType (puffclass->GetReplacement()); + AActor *puffDefaults = GetDefaultByType(puffclass->GetReplacement()); - flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross|TRACE_Impact; + flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross | TRACE_Impact; rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true; - Trace (x1, y1, shootz, source->Sector, vx, vy, vz, + Trace(x1, y1, shootz, source->Sector, vx, vy, vz, distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace, flags, ProcessRailHit, &rail_data); @@ -4076,10 +4040,10 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, // used as damage inflictor AActor *thepuff = NULL; - - if (puffclass != NULL) thepuff = Spawn (puffclass, source->x, source->y, source->z, ALLOW_REPLACE); - for (i = 0; i < rail_data.RailHits.Size (); i++) + if (puffclass != NULL) thepuff = Spawn(puffclass, source->x, source->y, source->z, ALLOW_REPLACE); + + for (i = 0; i < rail_data.RailHits.Size(); i++) { fixed_t x, y, z; bool spawnpuff; @@ -4094,7 +4058,7 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, z = shootz + FixedMul(hitdist, vz); if ((hitactor->flags & MF_NOBLOOD) || - (hitactor->flags2 & (MF2_DORMANT|MF2_INVULNERABLE))) + (hitactor->flags2 & (MF2_DORMANT | MF2_INVULNERABLE))) { spawnpuff = (puffclass != NULL); } @@ -4102,7 +4066,7 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, { spawnpuff = (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF); puffflags |= PF_HITTHINGBLEED; // [XA] Allow for puffs to jump to XDeath state. - if (!(puffDefaults->flags3 & MF3_BLOODLESSIMPACT)) + if (!(puffDefaults->flags3 & MF3_BLOODLESSIMPACT)) { bleed = true; } @@ -4115,7 +4079,7 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, { P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType); } - int newdam = P_DamageMobj(hitactor, thepuff? thepuff:source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF); + int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF); if (bleed) { P_SpawnBlood(x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, hitactor); @@ -4126,34 +4090,34 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, // Spawn a decal or puff at the point where the trace ended. if (trace.HitType == TRACE_HitWall) { - SpawnShootDecal (source, trace); - if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) + SpawnShootDecal(source, trace); + if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) { - P_SpawnPuff (source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0); + P_SpawnPuff(source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0); } } - if(thepuff != NULL) + if (thepuff != NULL) { if (trace.HitType == TRACE_HitFloor && trace.CrossedWater == NULL && trace.Sector->heightsec == NULL) { thepuff->SetOrigin(trace.X, trace.Y, trace.Z); - P_HitWater (thepuff, trace.Sector); + P_HitWater(thepuff, trace.Sector); } if (trace.Crossed3DWater || trace.CrossedWater) { - SpawnDeepSplash (source, trace, thepuff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); + SpawnDeepSplash(source, trace, thepuff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); } - thepuff->Destroy (); + thepuff->Destroy(); } // Draw the slug's trail. end.X = FIXED2FLOAT(trace.X); end.Y = FIXED2FLOAT(trace.Y); end.Z = FIXED2FLOAT(trace.Z); - P_DrawRailTrail (source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift); + P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift); } //========================================================================== @@ -4162,10 +4126,10 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, // //========================================================================== -CVAR (Float, chase_height, -8.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Float, chase_dist, 90.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(Float, chase_height, -8.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -void P_AimCamera (AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &CameraZ, sector_t *&CameraSector) +void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &CameraZ, sector_t *&CameraSector) { fixed_t distance = (fixed_t)(chase_dist * FRACUNIT); angle_t angle = (t1->angle - ANG180) >> ANGLETOFINESHIFT; @@ -4173,21 +4137,21 @@ void P_AimCamera (AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camer FTraceResults trace; fixed_t vx, vy, vz, sz; - vx = FixedMul (finecosine[pitch], finecosine[angle]); - vy = FixedMul (finecosine[pitch], finesine[angle]); + vx = FixedMul(finecosine[pitch], finecosine[angle]); + vy = FixedMul(finecosine[pitch], finesine[angle]); vz = finesine[pitch]; sz = t1->z - t1->floorclip + t1->height + (fixed_t)(chase_height * FRACUNIT); - if (Trace (t1->x, t1->y, sz, t1->Sector, + if (Trace(t1->x, t1->y, sz, t1->Sector, vx, vy, vz, distance, 0, 0, NULL, trace) && - trace.Distance > 10*FRACUNIT) + trace.Distance > 10 * FRACUNIT) { // Position camera slightly in front of hit thing - fixed_t dist = trace.Distance - 5*FRACUNIT; - CameraX = t1->x + FixedMul (vx, dist); - CameraY = t1->y + FixedMul (vy, dist); - CameraZ = sz + FixedMul (vz, dist); + fixed_t dist = trace.Distance - 5 * FRACUNIT; + CameraX = t1->x + FixedMul(vx, dist); + CameraY = t1->y + FixedMul(vy, dist); + CameraZ = sz + FixedMul(vz, dist); } else { @@ -4212,13 +4176,13 @@ bool P_TalkFacing(AActor *player) { AActor *linetarget; - P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); + P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); if (linetarget == NULL) { - P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); + P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); if (linetarget == NULL) { - P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); + P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); if (linetarget == NULL) { return false; @@ -4238,8 +4202,8 @@ bool P_TalkFacing(AActor *player) if (linetarget->Conversation != NULL) { // Give the NPC a chance to play a brief animation - linetarget->ConversationAnimation (0); - P_StartConversation (linetarget, player, true, true); + linetarget->ConversationAnimation(0); + P_StartConversation(linetarget, player, true, true); return true; } return false; @@ -4253,7 +4217,7 @@ bool P_TalkFacing(AActor *player) bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline) { - FPathTraverse it(usething->x, usething->y, endx, endy, PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(usething->x, usething->y, endx, endy, PT_ADDLINES | PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) @@ -4276,17 +4240,17 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline } FLineOpening open; - if (in->d.line->special == 0 || !(in->d.line->activation & (SPAC_Use|SPAC_UseThrough|SPAC_UseBack))) + if (in->d.line->special == 0 || !(in->d.line->activation & (SPAC_Use | SPAC_UseThrough | SPAC_UseBack))) { - blocked: - if (in->d.line->flags & (ML_BLOCKEVERYTHING|ML_BLOCKUSE)) + blocked: + if (in->d.line->flags & (ML_BLOCKEVERYTHING | ML_BLOCKUSE)) { open.range = 0; } else { - P_LineOpening (open, NULL, in->d.line, it.Trace().x + FixedMul (it.Trace().dx, in->frac), - it.Trace().y + FixedMul (it.Trace().dy, in->frac)); + P_LineOpening(open, NULL, in->d.line, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); } if (open.range <= 0 || (in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING))) @@ -4297,31 +4261,31 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline sec = usething->Sector; - if (sec->SecActTarget && sec->SecActTarget->TriggerAction (usething, SECSPAC_Use)) + if (sec->SecActTarget && sec->SecActTarget->TriggerAction(usething, SECSPAC_Use)) { return true; } - sec = P_PointOnLineSide(usething->x, usething->y, in->d.line) == 0? + sec = P_PointOnLineSide(usething->x, usething->y, in->d.line) == 0 ? in->d.line->frontsector : in->d.line->backsector; if (sec != NULL && sec->SecActTarget && - sec->SecActTarget->TriggerAction (usething, SECSPAC_UseWall)) + sec->SecActTarget->TriggerAction(usething, SECSPAC_UseWall)) { return true; } if (usething->player) { - S_Sound (usething, CHAN_VOICE, "*usefail", 1, ATTN_IDLE); + S_Sound(usething, CHAN_VOICE, "*usefail", 1, ATTN_IDLE); } return true; // can't use through a wall } foundline = true; continue; // not a special line, but keep checking } - - if (P_PointOnLineSide (usething->x, usething->y, in->d.line) == 1) + + if (P_PointOnLineSide(usething->x, usething->y, in->d.line) == 1) { if (!(in->d.line->activation & SPAC_UseBack)) { @@ -4331,18 +4295,18 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline } else { - P_ActivateLine (in->d.line, usething, 1, SPAC_UseBack); + P_ActivateLine(in->d.line, usething, 1, SPAC_UseBack); return true; } } - else + else { - if ((in->d.line->activation & (SPAC_Use|SPAC_UseThrough|SPAC_UseBack)) == SPAC_UseBack) + if ((in->d.line->activation & (SPAC_Use | SPAC_UseThrough | SPAC_UseBack)) == SPAC_UseBack) { goto blocked; // Line cannot be used from front side so treat it as a non-trigger line } - P_ActivateLine (in->d.line, usething, 0, SPAC_Use); + P_ActivateLine(in->d.line, usething, 0, SPAC_Use); //WAS can't use more than one special line in a row //jff 3/21/98 NOW multiple use allowed with enabling line flag @@ -4379,7 +4343,7 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline // //========================================================================== -bool P_NoWayTraverse (AActor *usething, fixed_t endx, fixed_t endy) +bool P_NoWayTraverse(AActor *usething, fixed_t endx, fixed_t endy) { FPathTraverse it(usething->x, usething->y, endx, endy, PT_ADDLINES); intercept_t *in; @@ -4392,9 +4356,9 @@ bool P_NoWayTraverse (AActor *usething, fixed_t endx, fixed_t endy) // [GrafZahl] de-obfuscated. Was I the only one who was unable to make sense out of // this convoluted mess? if (ld->special) continue; - if (ld->flags&(ML_BLOCKING|ML_BLOCKEVERYTHING|ML_BLOCK_PLAYERS)) return true; - P_LineOpening(open, NULL, ld, it.Trace().x+FixedMul(it.Trace().dx, in->frac), - it.Trace().y+FixedMul(it.Trace().dy, in->frac)); + if (ld->flags&(ML_BLOCKING | ML_BLOCKEVERYTHING | ML_BLOCK_PLAYERS)) return true; + P_LineOpening(open, NULL, ld, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); if (open.range <= 0 || open.bottom > usething->z + usething->MaxStepHeight || open.top < usething->z + usething->height) return true; @@ -4410,7 +4374,7 @@ bool P_NoWayTraverse (AActor *usething, fixed_t endx, fixed_t endy) // //========================================================================== -void P_UseLines (player_t *player) +void P_UseLines(player_t *player) { angle_t angle; fixed_t x1, y1, usedist; @@ -4431,15 +4395,15 @@ void P_UseLines (player_t *player) // // This added test makes the "oof" sound work on 2s lines -- killough: - if (!P_UseTraverse (player->mo, x1, y1, foundline)) + if (!P_UseTraverse(player->mo, x1, y1, foundline)) { // [RH] Give sector a chance to eat the use sector_t *sec = player->mo->Sector; int spac = SECSPAC_Use; if (foundline) spac |= SECSPAC_UseWall; - if ((!sec->SecActTarget || !sec->SecActTarget->TriggerAction (player->mo, spac)) && - P_NoWayTraverse (player->mo, x1, y1)) + if ((!sec->SecActTarget || !sec->SecActTarget->TriggerAction(player->mo, spac)) && + P_NoWayTraverse(player->mo, x1, y1)) { - S_Sound (player->mo, CHAN_VOICE, "*usefail", 1, ATTN_IDLE); + S_Sound(player->mo, CHAN_VOICE, "*usefail", 1, ATTN_IDLE); } } } @@ -4452,12 +4416,12 @@ void P_UseLines (player_t *player) // //========================================================================== -bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) +bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) { int angle; fixed_t x1, y1, x2, y2, usedist; - angle = PuzzleItemUser->angle>>ANGLETOFINESHIFT; + angle = PuzzleItemUser->angle >> ANGLETOFINESHIFT; x1 = PuzzleItemUser->x; y1 = PuzzleItemUser->y; @@ -4470,7 +4434,7 @@ bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) x2 = x1 + FixedMul(usedist, finecosine[angle]); y2 = y1 + FixedMul(usedist, finesine[angle]); - FPathTraverse it(x1, y1, x2, y2, PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(x1, y1, x2, y2, PT_ADDLINES | PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) @@ -4482,15 +4446,15 @@ bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) { // Check line if (in->d.line->special != UsePuzzleItem) { - P_LineOpening (open, NULL, in->d.line, it.Trace().x + FixedMul (it.Trace().dx, in->frac), - it.Trace().y + FixedMul (it.Trace().dy, in->frac)); + P_LineOpening(open, NULL, in->d.line, it.Trace().x + FixedMul(it.Trace().dx, in->frac), + it.Trace().y + FixedMul(it.Trace().dy, in->frac)); if (open.range <= 0) { return false; // can't use through a wall } continue; } - if (P_PointOnLineSide (PuzzleItemUser->x, PuzzleItemUser->y, in->d.line) == 1) + if (P_PointOnLineSide(PuzzleItemUser->x, PuzzleItemUser->y, in->d.line) == 1) { // Don't use back sides return false; } @@ -4499,7 +4463,7 @@ bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) return false; } int args[3] = { in->d.line->args[2], in->d.line->args[3], in->d.line->args[4] }; - P_StartScript (PuzzleItemUser, in->d.line, in->d.line->args[1], NULL, args, 3, ACS_ALWAYS); + P_StartScript(PuzzleItemUser, in->d.line, in->d.line->args[1], NULL, args, 3, ACS_ALWAYS); in->d.line->special = 0; return true; } @@ -4514,7 +4478,7 @@ bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) continue; } int args[3] = { mobj->args[2], mobj->args[3], mobj->args[4] }; - P_StartScript (PuzzleItemUser, NULL, mobj->args[1], NULL, args, 3, ACS_ALWAYS); + P_StartScript(PuzzleItemUser, NULL, mobj->args[1], NULL, args, 3, ACS_ALWAYS); mobj->special = 0; return true; } @@ -4532,7 +4496,7 @@ bool P_UsePuzzleItem (AActor *PuzzleItemUser, int PuzzleItemType) // [RH] Damage scale to apply to thing that shot the missile. static float selfthrustscale; -CUSTOM_CVAR (Float, splashfactor, 1.f, CVAR_SERVERINFO) +CUSTOM_CVAR(Float, splashfactor, 1.f, CVAR_SERVERINFO) { if (self <= 0.f) self = 1.f; @@ -4547,19 +4511,19 @@ CUSTOM_CVAR (Float, splashfactor, 1.f, CVAR_SERVERINFO) // //========================================================================== -void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int bombdistance, FName bombmod, +void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bombdistance, FName bombmod, int flags, int fulldamagedistance) { if (bombdistance <= 0) return; - fulldamagedistance = clamp(fulldamagedistance, 0, bombdistance-1); + fulldamagedistance = clamp(fulldamagedistance, 0, bombdistance - 1); double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance); double bombdamagefloat = (double)bombdamage; FVector3 bombvec(FIXED2FLOAT(bombspot->x), FIXED2FLOAT(bombspot->y), FIXED2FLOAT(bombspot->z)); - FBlockThingsIterator it(FBoundingBox(bombspot->x, bombspot->y, bombdistance<x, bombspot->y, bombdistance << FRACBITS)); AActor *thing; if (flags & RADF_SOURCEISSPOT) @@ -4588,12 +4552,12 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b // be hurt by projectiles fired by a monster of the same type. // Controlled by the DONTHARMCLASS and DONTHARMSPECIES flags. if ((bombsource && !thing->player) // code common to both checks - && ( // Class check first + && ( // Class check first ((bombsource->flags4 & MF4_DONTHARMCLASS) && (thing->GetClass() == bombsource->GetClass())) || // Nigh-identical species check second ((bombsource->flags6 & MF6_DONTHARMSPECIES) && (thing->GetSpecies() == bombsource->GetSpecies())) ) - ) continue; + ) continue; // Barrels always use the original code, since this makes // them far too "active." BossBrains also use the old code @@ -4608,12 +4572,12 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b fixed_t dx, dy; double boxradius; - dx = abs (thing->x - bombspot->x); - dy = abs (thing->y - bombspot->y); - boxradius = double (thing->radius); + dx = abs(thing->x - bombspot->x); + dy = abs(thing->y - bombspot->y); + boxradius = double(thing->radius); // The damage pattern is square, not circular. - len = double (dx > dy ? dx : dy); + len = double(dx > dy ? dx : dy); if (bombspot->z < thing->z || bombspot->z >= thing->z + thing->height) { @@ -4621,11 +4585,11 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b if (bombspot->z > thing->z) { - dz = double (bombspot->z - thing->z - thing->height); + dz = double(bombspot->z - thing->z - thing->height); } else { - dz = double (thing->z - bombspot->z); + dz = double(thing->z - bombspot->z); } if (len <= boxradius) { @@ -4634,7 +4598,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b else { len -= boxradius; - len = sqrt (len*len + dz*dz); + len = sqrt(len*len + dz*dz); } } else @@ -4650,10 +4614,10 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { points = points * splashfactor; } - points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(double)FRACUNIT; + points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT) / (double)FRACUNIT; // points and bombdamage should be the same sign - if ((points * bombdamage) > 0 && P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) + if ((points * bombdamage) > 0 && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path double velz; double thrust; @@ -4661,14 +4625,14 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b int newdam = damage; if (!(flags & RADF_NODAMAGE)) - newdam = P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); + newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); else if (thing->player == NULL && !(flags & RADF_NOIMPACTDAMAGE)) thing->flags2 |= MF2_BLASTED; if (!(thing->flags & MF_ICECORPSE)) { if (!(flags & RADF_NODAMAGE) && !(bombspot->flags3 & MF3_BLOODLESSIMPACT)) - P_TraceBleed (newdam > 0 ? newdam : damage, thing, bombspot); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot); if ((flags & RADF_NODAMAGE) || !(bombspot->flags2 & MF2_NODMGTHRUST)) { @@ -4679,7 +4643,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { thrust *= selfthrustscale; } - velz = (double)(thing->z + (thing->height>>1) - bombspot->z) * thrust; + velz = (double)(thing->z + (thing->height >> 1) - bombspot->z) * thrust; if (bombsource != thing) { velz *= 0.5f; @@ -4688,9 +4652,9 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { velz *= 0.8f; } - angle_t ang = R_PointToAngle2 (bombspot->x, bombspot->y, thing->x, thing->y) >> ANGLETOFINESHIFT; - thing->velx += fixed_t (finecosine[ang] * thrust); - thing->vely += fixed_t (finesine[ang] * thrust); + angle_t ang = R_PointToAngle2(bombspot->x, bombspot->y, thing->x, thing->y) >> ANGLETOFINESHIFT; + thing->velx += fixed_t(finecosine[ang] * thrust); + thing->vely += fixed_t(finesine[ang] * thrust); if (!(flags & RADF_NODAMAGE)) thing->velz += (fixed_t)velz; // this really doesn't work well } @@ -4703,8 +4667,8 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b // [RH] Old code just for barrels fixed_t dx, dy, dist; - dx = abs (thing->x - bombspot->x); - dy = abs (thing->y - bombspot->y); + dx = abs(thing->x - bombspot->x); + dy = abs(thing->y - bombspot->y); dist = dx>dy ? dx : dy; dist = (dist - thing->radius) >> FRACBITS; @@ -4715,17 +4679,17 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b if (dist >= bombdistance) continue; // out of range - if (P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) + if (P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path dist = clamp(dist - fulldamagedistance, 0, dist); - int damage = Scale (bombdamage, bombdistance-dist, bombdistance); + int damage = Scale(bombdamage, bombdistance - dist, bombdistance); damage = (int)((double)damage * splashfactor); damage = Scale(damage, thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT), FRACUNIT); if (damage > 0) { - int newdam = P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); - P_TraceBleed (newdam > 0 ? newdam : damage, thing, bombspot); + int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); + P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot); } } } @@ -4765,7 +4729,7 @@ struct FChangePosition TArray intersectors; -EXTERN_CVAR (Int, cl_bloodtype) +EXTERN_CVAR(Int, cl_bloodtype) //============================================================================= // @@ -4773,7 +4737,7 @@ EXTERN_CVAR (Int, cl_bloodtype) // //============================================================================= -bool P_AdjustFloorCeil (AActor *thing, FChangePosition *cpos) +bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos) { int flags2 = thing->flags2 & MF2_PASSMOBJ; FCheckPosition tm; @@ -4791,7 +4755,7 @@ bool P_AdjustFloorCeil (AActor *thing, FChangePosition *cpos) thing->flags2 |= MF2_PASSMOBJ; } - bool isgood = P_CheckPosition (thing, thing->x, thing->y, tm); + bool isgood = P_CheckPosition(thing, thing->x, thing->y, tm); thing->floorz = tm.floorz; thing->ceilingz = tm.ceilingz; thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs @@ -4812,7 +4776,7 @@ bool P_AdjustFloorCeil (AActor *thing, FChangePosition *cpos) // //============================================================================= -void P_FindAboveIntersectors (AActor *actor) +void P_FindAboveIntersectors(AActor *actor) { if (actor->flags & MF_NOCLIP) return; @@ -4855,7 +4819,7 @@ void P_FindAboveIntersectors (AActor *actor) if (thing->z >= actor->z && thing->z <= actor->z + actor->height) { // Thing intersects above the base - intersectors.Push (thing); + intersectors.Push(thing); } } } @@ -4866,7 +4830,7 @@ void P_FindAboveIntersectors (AActor *actor) // //============================================================================= -void P_FindBelowIntersectors (AActor *actor) +void P_FindBelowIntersectors(AActor *actor) { if (actor->flags & MF_NOCLIP) return; @@ -4909,7 +4873,7 @@ void P_FindBelowIntersectors (AActor *actor) if (thing->z + thing->height <= actor->z + actor->height && thing->z + thing->height > actor->z) { // Thing intersects below the base - intersectors.Push (thing); + intersectors.Push(thing); } } } @@ -4920,34 +4884,34 @@ void P_FindBelowIntersectors (AActor *actor) // //============================================================================= -void P_DoCrunch (AActor *thing, FChangePosition *cpos) +void P_DoCrunch(AActor *thing, FChangePosition *cpos) { if (!(thing && thing->Grind(true) && cpos)) return; cpos->nofit = true; if ((cpos->crushchange > 0) && !(level.maptime & 3)) { - int newdam = P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush); + int newdam = P_DamageMobj(thing, NULL, NULL, cpos->crushchange, NAME_Crush); // spray blood in a random direction - if (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT))) + if (!(thing->flags2&(MF2_INVULNERABLE | MF2_DORMANT))) { if (!(thing->flags&MF_NOBLOOD)) { PalEntry bloodcolor = thing->GetBloodColor(); const PClass *bloodcls = thing->GetBloodType(); - - P_TraceBleed (newdam > 0 ? newdam : cpos->crushchange, thing); + + P_TraceBleed(newdam > 0 ? newdam : cpos->crushchange, thing); if (bloodcls != NULL) { AActor *mo; - mo = Spawn (bloodcls, thing->x, thing->y, - thing->z + thing->height/2, ALLOW_REPLACE); + mo = Spawn(bloodcls, thing->x, thing->y, + thing->z + thing->height / 2, ALLOW_REPLACE); - mo->velx = pr_crunch.Random2 () << 12; - mo->vely = pr_crunch.Random2 () << 12; + mo->velx = pr_crunch.Random2() << 12; + mo->vely = pr_crunch.Random2() << 12; if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); @@ -4957,7 +4921,7 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) } angle_t an; - an = (M_Random () - 128) << 24; + an = (M_Random() - 128) << 24; if (cl_bloodtype >= 1) { P_DrawSplash2(32, thing->x, thing->y, thing->z + thing->height / 2, an, 2, bloodcolor); @@ -4982,9 +4946,9 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) // above it didn't fit. //============================================================================= -int P_PushUp (AActor *thing, FChangePosition *cpos) +int P_PushUp(AActor *thing, FChangePosition *cpos) { - unsigned int firstintersect = intersectors.Size (); + unsigned int firstintersect = intersectors.Size(); unsigned int lastintersect; int mymass = thing->Mass; @@ -4995,8 +4959,8 @@ int P_PushUp (AActor *thing, FChangePosition *cpos) // [GZ] Skip thing intersect test for THRUACTORS things. if (thing->flags2 & MF2_THRUACTORS) return 0; - P_FindAboveIntersectors (thing); - lastintersect = intersectors.Size (); + P_FindAboveIntersectors(thing); + lastintersect = intersectors.Size(); for (; firstintersect < lastintersect; firstintersect++) { AActor *intersect = intersectors[firstintersect]; @@ -5009,17 +4973,17 @@ int P_PushUp (AActor *thing, FChangePosition *cpos) if (!(intersect->flags2 & MF2_PASSMOBJ) || (!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) || (intersect->flags4 & MF4_ACTLIKEBRIDGE) - ) - { + ) + { // Can't push bridges or things more massive than ourself return 2; } fixed_t oldz = intersect->z; - P_AdjustFloorCeil (intersect, cpos); + P_AdjustFloorCeil(intersect, cpos); intersect->z = thing->z + thing->height + 1; - if (P_PushUp (intersect, cpos)) + if (P_PushUp(intersect, cpos)) { // Move blocked - P_DoCrunch (intersect, cpos); + P_DoCrunch(intersect, cpos); intersect->z = oldz; return 2; } @@ -5035,9 +4999,9 @@ int P_PushUp (AActor *thing, FChangePosition *cpos) // below it didn't fit. //============================================================================= -int P_PushDown (AActor *thing, FChangePosition *cpos) +int P_PushDown(AActor *thing, FChangePosition *cpos) { - unsigned int firstintersect = intersectors.Size (); + unsigned int firstintersect = intersectors.Size(); unsigned int lastintersect; int mymass = thing->Mass; @@ -5045,27 +5009,27 @@ int P_PushDown (AActor *thing, FChangePosition *cpos) { return 1; } - P_FindBelowIntersectors (thing); - lastintersect = intersectors.Size (); + P_FindBelowIntersectors(thing); + lastintersect = intersectors.Size(); for (; firstintersect < lastintersect; firstintersect++) { AActor *intersect = intersectors[firstintersect]; if (!(intersect->flags2 & MF2_PASSMOBJ) || (!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) || (intersect->flags4 & MF4_ACTLIKEBRIDGE) - ) - { + ) + { // Can't push bridges or things more massive than ourself return 2; } fixed_t oldz = intersect->z; - P_AdjustFloorCeil (intersect, cpos); + P_AdjustFloorCeil(intersect, cpos); if (oldz > thing->z - intersect->height) { // Only push things down, not up. intersect->z = thing->z - intersect->height; - if (P_PushDown (intersect, cpos)) + if (P_PushDown(intersect, cpos)) { // Move blocked - P_DoCrunch (intersect, cpos); + P_DoCrunch(intersect, cpos); intersect->z = oldz; return 2; } @@ -5080,27 +5044,27 @@ int P_PushDown (AActor *thing, FChangePosition *cpos) // //============================================================================= -void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) +void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { fixed_t oldfloorz = thing->floorz; - P_AdjustFloorCeil (thing, cpos); + P_AdjustFloorCeil(thing, cpos); if (oldfloorz == thing->floorz) return; if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things if (thing->velz == 0 && (!(thing->flags & MF_NOGRAVITY) || - (thing->z == oldfloorz && !(thing->flags & MF_NOLIFTDROP)))) + (thing->z == oldfloorz && !(thing->flags & MF_NOLIFTDROP)))) { fixed_t oldz = thing->z; if ((thing->flags & MF_NOGRAVITY) || (thing->flags5 & MF5_MOVEWITHSECTOR) || - (((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9*FRACUNIT) - && thing->z - thing->floorz <= cpos->moveamt)) + (((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9 * FRACUNIT) + && thing->z - thing->floorz <= cpos->moveamt)) { thing->z = thing->floorz; - P_CheckFakeFloorTriggers (thing, oldz); + P_CheckFakeFloorTriggers(thing, oldz); } } else if ((thing->z != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) @@ -5109,7 +5073,7 @@ void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { thing->z = thing->z - oldfloorz + thing->floorz; - P_CheckFakeFloorTriggers (thing, oldz); + P_CheckFakeFloorTriggers(thing, oldz); } } } @@ -5120,46 +5084,46 @@ void PIT_FloorDrop (AActor *thing, FChangePosition *cpos) // //============================================================================= -void PIT_FloorRaise (AActor *thing, FChangePosition *cpos) +void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) { fixed_t oldfloorz = thing->floorz; fixed_t oldz = thing->z; - P_AdjustFloorCeil (thing, cpos); + P_AdjustFloorCeil(thing, cpos); if (oldfloorz == thing->floorz) return; // Move things intersecting the floor up if (thing->z <= thing->floorz) { - if (thing->flags4 & MF4_ACTLIKEBRIDGE) + if (thing->flags4 & MF4_ACTLIKEBRIDGE) { cpos->nofit = true; return; // do not move bridge things } - intersectors.Clear (); + intersectors.Clear(); thing->z = thing->floorz; } else { - if((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) + if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { - intersectors.Clear (); + intersectors.Clear(); thing->z = thing->z - oldfloorz + thing->floorz; } else return; } - switch (P_PushUp (thing, cpos)) + switch (P_PushUp(thing, cpos)) { default: - P_CheckFakeFloorTriggers (thing, oldz); + P_CheckFakeFloorTriggers(thing, oldz); break; case 1: - P_DoCrunch (thing, cpos); - P_CheckFakeFloorTriggers (thing, oldz); + P_DoCrunch(thing, cpos); + P_CheckFakeFloorTriggers(thing, oldz); break; case 2: - P_DoCrunch (thing, cpos); + P_DoCrunch(thing, cpos); thing->z = oldz; break; } @@ -5171,21 +5135,21 @@ void PIT_FloorRaise (AActor *thing, FChangePosition *cpos) // //============================================================================= -void PIT_CeilingLower (AActor *thing, FChangePosition *cpos) +void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) { bool onfloor; onfloor = thing->z <= thing->floorz; - P_AdjustFloorCeil (thing, cpos); + P_AdjustFloorCeil(thing, cpos); if (thing->z + thing->height > thing->ceilingz) { - if (thing->flags4 & MF4_ACTLIKEBRIDGE) + if (thing->flags4 & MF4_ACTLIKEBRIDGE) { cpos->nofit = true; return; // do not move bridge things } - intersectors.Clear (); + intersectors.Clear(); fixed_t oldz = thing->z; if (thing->ceilingz - thing->height >= thing->floorz) { @@ -5195,18 +5159,18 @@ void PIT_CeilingLower (AActor *thing, FChangePosition *cpos) { thing->z = thing->floorz; } - switch (P_PushDown (thing, cpos)) + switch (P_PushDown(thing, cpos)) { case 2: // intentional fall-through case 1: if (onfloor) thing->z = thing->floorz; - P_DoCrunch (thing, cpos); - P_CheckFakeFloorTriggers (thing, oldz); + P_DoCrunch(thing, cpos); + P_CheckFakeFloorTriggers(thing, oldz); break; default: - P_CheckFakeFloorTriggers (thing, oldz); + P_CheckFakeFloorTriggers(thing, oldz); break; } } @@ -5218,9 +5182,9 @@ void PIT_CeilingLower (AActor *thing, FChangePosition *cpos) // //============================================================================= -void PIT_CeilingRaise (AActor *thing, FChangePosition *cpos) +void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) { - bool isgood = P_AdjustFloorCeil (thing, cpos); + bool isgood = P_AdjustFloorCeil(thing, cpos); if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things @@ -5237,15 +5201,15 @@ void PIT_CeilingRaise (AActor *thing, FChangePosition *cpos) { thing->z = thing->ceilingz - thing->height; } - P_CheckFakeFloorTriggers (thing, oldz); + P_CheckFakeFloorTriggers(thing, oldz); } else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->z + thing->height < thing->ceilingz) { AActor *onmobj; - if (!P_TestMobjZ (thing, true, &onmobj) && onmobj->z <= thing->z) + if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->z <= thing->z) { - thing->z = MIN (thing->ceilingz - thing->height, - onmobj->z + onmobj->height); + thing->z = MIN(thing->ceilingz - thing->height, + onmobj->z + onmobj->height); } } } @@ -5260,23 +5224,23 @@ void PIT_CeilingRaise (AActor *thing, FChangePosition *cpos) // //============================================================================= -bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, bool isreset) +bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool isreset) { FChangePosition cpos; - void (*iterator)(AActor *, FChangePosition *); - void (*iterator2)(AActor *, FChangePosition *) = NULL; + void(*iterator)(AActor *, FChangePosition *); + void(*iterator2)(AActor *, FChangePosition *) = NULL; msecnode_t *n; cpos.nofit = false; cpos.crushchange = crunch; - cpos.moveamt = abs (amt); + cpos.moveamt = abs(amt); cpos.movemidtex = false; cpos.sector = sector; #ifdef _3DFLOORS // Also process all sectors that have 3D floors transferred from the // changed sector. - if(sector->e->XFloor.attached.Size()) + if (sector->e->XFloor.attached.Size()) { unsigned i; sector_t* sec; @@ -5285,30 +5249,30 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, boo // Use different functions for the four different types of sector movement. // for 3D-floors the meaning of floor and ceiling is inverted!!! if (floorOrCeil == 1) - { + { iterator = (amt >= 0) ? PIT_FloorRaise : PIT_FloorDrop; } else - { - iterator = (amt >=0) ? PIT_CeilingRaise : PIT_CeilingLower; + { + iterator = (amt >= 0) ? PIT_CeilingRaise : PIT_CeilingLower; } - for(i = 0; i < sector->e->XFloor.attached.Size(); i ++) + for (i = 0; i < sector->e->XFloor.attached.Size(); i++) { sec = sector->e->XFloor.attached[i]; P_Recalculate3DFloors(sec); // Must recalculate the 3d floor and light lists // no thing checks for attached sectors because of heightsec - if (sec->heightsec==sector) continue; + if (sec->heightsec == sector) continue; - for (n=sec->touching_thinglist; n; n=n->m_snext) n->visited = false; - do + for (n = sec->touching_thinglist; n; n = n->m_snext) n->visited = false; + do { - for (n=sec->touching_thinglist; n; n=n->m_snext) + for (n = sec->touching_thinglist; n; n = n->m_snext) { if (!n->visited) { - n->visited = true; + n->visited = true; if (!(n->m_thing->flags & MF_NOBLOCKMAP) || //jff 4/7/98 don't do these (n->m_thing->flags5 & MF5_MOVEWITHSECTOR)) { @@ -5317,8 +5281,7 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, boo break; } } - } - while (n); + } while (n); } } P_Recalculate3DFloors(sector); // Must recalculate the 3d floor and light lists @@ -5376,8 +5339,8 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, boo if (!(n->m_thing->flags & MF_NOBLOCKMAP) || //jff 4/7/98 don't do these (n->m_thing->flags5 & MF5_MOVEWITHSECTOR)) { - iterator (n->m_thing, &cpos); // process it - if (iterator2 != NULL) iterator2 (n->m_thing, &cpos); + iterator(n->m_thing, &cpos); // process it + if (iterator2 != NULL) iterator2(n->m_thing, &cpos); } break; // exit and start over } @@ -5391,7 +5354,7 @@ bool P_ChangeSector (sector_t *sector, int crunch, int amt, int floorOrCeil, boo // execute appropriate sector actions. // Only check if the sector move was successful. TArray & secs = sector->e->FakeFloor.Sectors; - for(unsigned i = 0; i < secs.Size(); i++) + for (unsigned i = 0; i < secs.Size(); i++) { sector_t * s = secs[i]; @@ -5446,7 +5409,7 @@ msecnode_t *P_GetSecnode() } else { - node = (msecnode_t *)M_Malloc (sizeof(*node)); + node = (msecnode_t *)M_Malloc(sizeof(*node)); } return node; } @@ -5459,7 +5422,7 @@ msecnode_t *P_GetSecnode() // //============================================================================= -void P_PutSecnode (msecnode_t *node) +void P_PutSecnode(msecnode_t *node) { node->m_snext = headsecnode; headsecnode = node; @@ -5477,13 +5440,13 @@ void P_PutSecnode (msecnode_t *node) // //============================================================================= -msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode) +msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode) { msecnode_t *node; if (s == 0) { - I_FatalError ("AddSecnode of 0 for %s\n", thing->_StaticType.TypeName.GetChars()); + I_FatalError("AddSecnode of 0 for %s\n", thing->_StaticType.TypeName.GetChars()); } node = nextnode; @@ -5506,16 +5469,16 @@ msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode) node->visited = 0; node->m_sector = s; // sector - node->m_thing = thing; // mobj - node->m_tprev = NULL; // prev node on Thing thread - node->m_tnext = nextnode; // next node on Thing thread + node->m_thing = thing; // mobj + node->m_tprev = NULL; // prev node on Thing thread + node->m_tnext = nextnode; // next node on Thing thread if (nextnode) nextnode->m_tprev = node; // set back link on Thing // Add new node at head of sector thread starting at s->touching_thinglist - node->m_sprev = NULL; // prev node on sector thread - node->m_snext = s->touching_thinglist; // next node on sector thread + node->m_sprev = NULL; // prev node on sector thread + node->m_snext = s->touching_thinglist; // next node on sector thread if (s->touching_thinglist) node->m_snext->m_sprev = node; s->touching_thinglist = node; @@ -5532,7 +5495,7 @@ msecnode_t *P_AddSecnode (sector_t *s, AActor *thing, msecnode_t *nextnode) // //============================================================================= -msecnode_t *P_DelSecnode (msecnode_t *node) +msecnode_t *P_DelSecnode(msecnode_t *node) { msecnode_t* tp; // prev node on thing thread msecnode_t* tn; // next node on thing thread @@ -5579,11 +5542,11 @@ msecnode_t *P_DelSecnode (msecnode_t *node) // //============================================================================= -void P_DelSector_List () +void P_DelSector_List() { if (sector_list != NULL) { - P_DelSeclist (sector_list); + P_DelSeclist(sector_list); sector_list = NULL; } } @@ -5596,10 +5559,10 @@ void P_DelSector_List () // //============================================================================= -void P_DelSeclist (msecnode_t *node) +void P_DelSeclist(msecnode_t *node) { while (node) - node = P_DelSecnode (node); + node = P_DelSecnode(node); } //============================================================================= @@ -5611,7 +5574,7 @@ void P_DelSeclist (msecnode_t *node) // //============================================================================= -void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) +void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y) { msecnode_t *node; @@ -5633,13 +5596,13 @@ void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) while ((ld = it.Next())) { - if (box.Right() <= ld->bbox[BOXLEFT] || - box.Left() >= ld->bbox[BOXRIGHT] || - box.Top() <= ld->bbox[BOXBOTTOM] || + if (box.Right() <= ld->bbox[BOXLEFT] || + box.Left() >= ld->bbox[BOXRIGHT] || + box.Top() <= ld->bbox[BOXBOTTOM] || box.Bottom() >= ld->bbox[BOXTOP]) continue; - if (box.BoxOnLineSide (ld) != -1) + if (box.BoxOnLineSide(ld) != -1) continue; // This line crosses through the object. @@ -5649,7 +5612,7 @@ void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) // allowed to move to this position, then the sector_list // will be attached to the Thing's AActor at touching_sectorlist. - sector_list = P_AddSecnode (ld->frontsector,thing,sector_list); + sector_list = P_AddSecnode(ld->frontsector, thing, sector_list); // Don't assume all lines are 2-sided, since some Things // like MT_TFOG are allowed regardless of whether their radius takes @@ -5664,7 +5627,7 @@ void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) // Add the sector of the (x,y) point to sector_list. - sector_list = P_AddSecnode (thing->Sector, thing, sector_list); + sector_list = P_AddSecnode(thing->Sector, thing, sector_list); // Now delete any nodes that won't be used. These are the ones where // m_thing is still NULL. @@ -5676,7 +5639,7 @@ void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) { if (node == sector_list) sector_list = node->m_tnext; - node = P_DelSecnode (node); + node = P_DelSecnode(node); } else { @@ -5691,7 +5654,7 @@ void P_CreateSecNodeList (AActor *thing, fixed_t x, fixed_t y) // //========================================================================== -void SpawnShootDecal (AActor *t1, const FTraceResults &trace) +void SpawnShootDecal(AActor *t1, const FTraceResults &trace) { FDecalBase *decalbase = NULL; @@ -5705,7 +5668,7 @@ void SpawnShootDecal (AActor *t1, const FTraceResults &trace) } if (decalbase != NULL) { - DImpactDecal::StaticCreate (decalbase->GetDecal (), + DImpactDecal::StaticCreate(decalbase->GetDecal(), trace.X, trace.Y, trace.Z, trace.Line->sidedef[trace.Side], trace.ffloor); } } @@ -5716,10 +5679,10 @@ void SpawnShootDecal (AActor *t1, const FTraceResults &trace) // //========================================================================== -static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff, +static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor) { - const secplane_t *plane; + const secplane_t *plane; if (ffloor && trace.Crossed3DWater) plane = trace.Crossed3DWater->top.plane; else if (trace.CrossedWater && trace.CrossedWater->heightsec) @@ -5727,19 +5690,19 @@ static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puf else return; fixed_t num, den, hitdist; - den = TMulScale16 (plane->a, vx, plane->b, vy, plane->c, vz); + den = TMulScale16(plane->a, vx, plane->b, vy, plane->c, vz); if (den != 0) { - num = TMulScale16 (plane->a, t1->x, plane->b, t1->y, plane->c, shootz) + plane->d; - hitdist = FixedDiv (-num, den); + num = TMulScale16(plane->a, t1->x, plane->b, t1->y, plane->c, shootz) + plane->d; + hitdist = FixedDiv(-num, den); if (hitdist >= 0 && hitdist <= trace.Distance) { - fixed_t hitx = t1->x+FixedMul (vx, hitdist); - fixed_t hity = t1->y+FixedMul (vy, hitdist); - fixed_t hitz = shootz+FixedMul (vz, hitdist); + fixed_t hitx = t1->x + FixedMul(vx, hitdist); + fixed_t hity = t1->y + FixedMul(vy, hitdist); + fixed_t hitz = shootz + FixedMul(vz, hitdist); - P_HitWater (puff != NULL? puff:t1, P_PointInSector(hitx, hity), hitx, hity, hitz); + P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitx, hity), hitx, hity, hitz); } } } @@ -5761,12 +5724,12 @@ bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death) if (thing->activationtype & THINGSPEC_TriggerTargets) trigger->target = thing; // State change mechanism. The thing needs to be not dead and to have at least one of the relevant flags - if (!death && (thing->activationtype & (THINGSPEC_Activate|THINGSPEC_Deactivate|THINGSPEC_Switch))) + if (!death && (thing->activationtype & (THINGSPEC_Activate | THINGSPEC_Deactivate | THINGSPEC_Switch))) { // If a switchable thing does not know whether it should be activated // or deactivated, the default is to activate it. - if ((thing->activationtype & THINGSPEC_Switch) - && !(thing->activationtype & (THINGSPEC_Activate|THINGSPEC_Deactivate))) + if ((thing->activationtype & THINGSPEC_Switch) + && !(thing->activationtype & (THINGSPEC_Activate | THINGSPEC_Deactivate))) { thing->activationtype |= THINGSPEC_Activate; } @@ -5793,11 +5756,11 @@ bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death) // Run the special, if any if (thing->special) { - res = !! P_ExecuteSpecial(thing->special, NULL, + res = !!P_ExecuteSpecial(thing->special, NULL, // TriggerActs overrides the level flag, which only concerns thing activated by death (((death && level.flags & LEVEL_ACTOWNSPECIAL && !(thing->activationtype & THINGSPEC_TriggerActs)) || (thing->activationtype & THINGSPEC_ThingActs)) // Who triggers? - ? thing : trigger), + ? thing : trigger), false, thing->args[0], thing->args[1], thing->args[2], thing->args[3], thing->args[4]); // Clears the special if it was run on thing's death or if flag is set. From e1ee80661e285f2be6d3ef58e5ec0e1fe8d554fe Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 17:12:04 -0500 Subject: [PATCH 301/311] Make FWallCoords' members lowercase because they're kind of a pain to type when all uppercase. - Also, make its sx1 and sx2 members shorts, so it takes less space, since it's getting crammed into a vissprite now. --- src/r_bsp.cpp | 90 ++++++++++++------------ src/r_bsp.h | 12 ++-- src/r_segs.cpp | 180 +++++++++++++++++++++++------------------------ src/r_things.cpp | 12 ++-- 4 files changed, 147 insertions(+), 147 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 02a89f371..c56255888 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -408,7 +408,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y)) { // Check that the window is actually visible - for (int z = WallC.SX1; z < WallC.SX2; ++z) + for (int z = WallC.sx1; z < WallC.sx2; ++z) { if (floorclip[z] > ceilingclip[z]) { @@ -541,12 +541,12 @@ void R_AddLine (seg_t *line) if (WallC.Init(tx1, ty1, tx2, ty2, 32)) return; - if (WallC.SX1 > WindowRight || WallC.SX2 < WindowLeft) + if (WallC.sx1 > WindowRight || WallC.sx2 < WindowLeft) return; if (line->linedef == NULL) { - if (R_CheckClipWallSegment (WallC.SX1, WallC.SX2)) + if (R_CheckClipWallSegment (WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -695,7 +695,7 @@ void R_AddLine (seg_t *line) // mark their subsectors as visible for automap texturing. if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) { - if (R_CheckClipWallSegment(WallC.SX1, WallC.SX2)) + if (R_CheckClipWallSegment(WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -709,8 +709,8 @@ void R_AddLine (seg_t *line) if (line->linedef->special == Line_Horizon) { // Be aware: Line_Horizon does not work properly with sloped planes - clearbufshort (walltop+WallC.SX1, WallC.SX2 - WallC.SX1, centery); - clearbufshort (wallbottom+WallC.SX1, WallC.SX2 - WallC.SX1, centery); + clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery); + clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery); } else { @@ -735,7 +735,7 @@ void R_AddLine (seg_t *line) #endif } - if (R_ClipWallSegment (WallC.SX1, WallC.SX2, solid)) + if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid)) { InSubsector->flags |= SSECF_DRAWN; } @@ -748,58 +748,58 @@ void R_AddLine (seg_t *line) // bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close) { - TX1 = DMulScale20(x1, viewsin, -y1, viewcos); - TX2 = DMulScale20(x2, viewsin, -y2, viewcos); + tx1 = DMulScale20(x1, viewsin, -y1, viewcos); + tx2 = DMulScale20(x2, viewsin, -y2, viewcos); - TY1 = DMulScale20(x1, viewtancos, y1, viewtansin); - TY2 = DMulScale20(x2, viewtancos, y2, viewtansin); + ty1 = DMulScale20(x1, viewtancos, y1, viewtansin); + ty2 = DMulScale20(x2, viewtancos, y2, viewtansin); if (MirrorFlags & RF_XFLIP) { - int t = 256 - TX1; - TX1 = 256 - TX2; - TX2 = t; - swapvalues(TY1, TY2); + int t = 256 - tx1; + tx1 = 256 - tx2; + tx2 = t; + swapvalues(ty1, ty2); } - if (TX1 >= -TY1) + if (tx1 >= -ty1) { - if (TX1 > TY1) return true; // left edge is off the right side - if (TY1 == 0) return true; - SX1 = (centerxfrac + Scale(TX1, centerxfrac, TY1)) >> FRACBITS; - if (TX1 >= 0) SX1 = MIN(viewwidth, SX1+1); // fix for signed divide - SZ1 = TY1; + if (tx1 > ty1) return true; // left edge is off the right side + if (ty1 == 0) return true; + sx1 = (centerxfrac + Scale(tx1, centerxfrac, ty1)) >> FRACBITS; + if (tx1 >= 0) sx1 = MIN(viewwidth, sx1+1); // fix for signed divide + sz1 = ty1; } else { - if (TX2 < -TY2) return true; // wall is off the left side - fixed_t den = TX1 - TX2 - TY2 + TY1; + if (tx2 < -ty2) return true; // wall is off the left side + fixed_t den = tx1 - tx2 - ty2 + ty1; if (den == 0) return true; - SX1 = 0; - SZ1 = TY1 + Scale(TY2 - TY1, TX1 + TY1, den); + sx1 = 0; + sz1 = ty1 + Scale(ty2 - ty1, tx1 + ty1, den); } - if (SZ1 < too_close) + if (sz1 < too_close) return true; - if (TX2 <= TY2) + if (tx2 <= ty2) { - if (TX2 < -TY2) return true; // right edge is off the left side - if (TY2 == 0) return true; - SX2 = (centerxfrac + Scale(TX2, centerxfrac, TY2)) >> FRACBITS; - if (TX2 >= 0) SX2 = MIN(viewwidth, SX2+1); // fix for signed divide - SZ2 = TY2; + if (tx2 < -ty2) return true; // right edge is off the left side + if (ty2 == 0) return true; + sx2 = (centerxfrac + Scale(tx2, centerxfrac, ty2)) >> FRACBITS; + if (tx2 >= 0) sx2 = MIN(viewwidth, sx2+1); // fix for signed divide + sz2 = ty2; } else { - if (TX1 > TY1) return true; // wall is off the right side - fixed_t den = TY2 - TY1 - TX2 + TX1; + if (tx1 > ty1) return true; // wall is off the right side + fixed_t den = ty2 - ty1 - tx2 + tx1; if (den == 0) return true; - SX2 = viewwidth; - SZ2 = TY1 + Scale(TY2 - TY1, TX1 - TY1, den); + sx2 = viewwidth; + sz2 = ty1 + Scale(ty2 - ty1, tx1 - ty1, den); } - if (SZ2 < too_close || SX2 <= SX1) + if (sz2 < too_close || sx2 <= sx1) return true; return false; @@ -809,17 +809,17 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) { if (MirrorFlags & RF_XFLIP) { - UoverZorg = (float)wallc->TX2 * WallTMapScale; - UoverZstep = (float)(-wallc->TY2) * 32.f; - InvZorg = (float)(wallc->TX2 - wallc->TX1) * WallTMapScale; - InvZstep = (float)(wallc->TY1 - wallc->TY2) * 32.f; + UoverZorg = (float)wallc->tx2 * WallTMapScale; + UoverZstep = (float)(-wallc->ty2) * 32.f; + InvZorg = (float)(wallc->tx2 - wallc->tx1) * WallTMapScale; + InvZstep = (float)(wallc->ty1 - wallc->ty2) * 32.f; } else { - UoverZorg = (float)wallc->TX1 * WallTMapScale; - UoverZstep = (float)(-wallc->TY1) * 32.f; - InvZorg = (float)(wallc->TX1 - wallc->TX2) * WallTMapScale; - InvZstep = (float)(wallc->TY2 - wallc->TY1) * 32.f; + UoverZorg = (float)wallc->tx1 * WallTMapScale; + UoverZstep = (float)(-wallc->ty1) * 32.f; + InvZorg = (float)(wallc->tx1 - wallc->tx2) * WallTMapScale; + InvZstep = (float)(wallc->ty2 - wallc->ty1) * 32.f; } InitDepth(); } diff --git a/src/r_bsp.h b/src/r_bsp.h index d15beca0c..79dac6c88 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -33,14 +33,14 @@ struct FWallCoords { - fixed_t TX1, TX2; // x coords at left, right of wall in view space - fixed_t TY1, TY2; // y coords at left, right of wall in view space + fixed_t tx1, tx2; // x coords at left, right of wall in view space + fixed_t ty1, ty2; // y coords at left, right of wall in view space - fixed_t CX1, CX2; // x coords at left, right of wall in camera space - fixed_t CY1, CY2; // y coords at left, right of wall in camera space + fixed_t cx1, cx2; // x coords at left, right of wall in camera space + fixed_t cy1, cy2; // y coords at left, right of wall in camera space - int SX1, SX2; // x coords at left, right of wall in screen space - fixed_t SZ1, SZ2; // depth at left, right of wall in screen space + short sx1, sx2; // x coords at left, right of wall in screen space + fixed_t sz1, sz2; // depth at left, right of wall in screen space bool Init(int x1, int y1, int x2, int y2, int too_close); }; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 25395a596..15f736c93 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -376,10 +376,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) goto clearfog; } - WallC.SZ1 = ds->sz1; - WallC.SZ2 = ds->sz2; - WallC.SX1 = ds->sx1; - WallC.SX2 = ds->sx2; + WallC.sz1 = ds->sz1; + WallC.sz2 = ds->sz2; + WallC.sx1 = ds->sx1; + WallC.sx2 = ds->sx2; if (fake3D & FAKE3D_CLIPTOP) { @@ -467,10 +467,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } else { // Texture does wrap vertically. - WallC.SZ1 = ds->sz1; - WallC.SZ2 = ds->sz2; - WallC.SX1 = ds->sx1; - WallC.SX2 = ds->sx2; + WallC.sz1 = ds->sz1; + WallC.sz2 = ds->sz2; + WallC.sx1 = ds->sx1; + WallC.sx2 = ds->sx2; if (CurrentSkybox) { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor @@ -587,14 +587,14 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; - WallC.SZ1 = ds->sz1; - WallC.SZ2 = ds->sz2; - WallC.SX1 = ds->sx1; - WallC.SX2 = ds->sx2; - WallC.TX1 = ds->cx; - WallC.TY1 = ds->cy; - WallC.TX2 = ds->cx + ds->cdx; - WallC.TY2 = ds->cy + ds->cdy; + WallC.sz1 = ds->sz1; + WallC.sz2 = ds->sz2; + WallC.sx1 = ds->sx1; + WallC.sx2 = ds->sx2; + WallC.tx1 = ds->cx; + WallC.ty1 = ds->cy; + WallC.tx2 = ds->cx + ds->cdx; + WallC.ty2 = ds->cy + ds->cdy; WallT = ds->tmapvals; OWallMost(wallupper, sclipTop - viewz, &WallC); @@ -1209,8 +1209,8 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, up = uwal; down = most1; - assert(WallC.SX1 <= x1); - assert(WallC.SX2 > x2); + assert(WallC.sx1 <= x1); + assert(WallC.sx2 > x2); // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) @@ -1821,7 +1821,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); lwallscale = xscale; } if (midtexture->bWorldPanning) @@ -1864,7 +1864,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); lwallscale = xscale; } if (toptexture->bWorldPanning) @@ -1910,7 +1910,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); lwallscale = xscale; } if (bottomtexture->bWorldPanning) @@ -2030,7 +2030,7 @@ void R_NewWall (bool needlights) { if (rw_havehigh) { // front ceiling is above back ceiling - memcpy (&walltop[WallC.SX1], &wallupper[WallC.SX1], (WallC.SX2 - WallC.SX1)*sizeof(walltop[0])); + memcpy (&walltop[WallC.sx1], &wallupper[WallC.sx1], (WallC.sx2 - WallC.sx1)*sizeof(walltop[0])); rw_havehigh = false; } else if (rw_havelow && frontsector->ceilingplane != backsector->ceilingplane) @@ -2255,15 +2255,15 @@ void R_NewWall (bool needlights) bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) : FRACUNIT; - PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.SX1, WallC.SX2); + PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2); if (fixedcolormap == NULL && fixedlightlev < 0) { wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) + r_actualextralight); GlobVis = r_WallVisibility; - rw_lightleft = SafeDivScale12 (GlobVis, WallC.SZ1); - rw_lightstep = (SafeDivScale12 (GlobVis, WallC.SZ2) - rw_lightleft) / (WallC.SX2 - WallC.SX1); + rw_lightleft = SafeDivScale12 (GlobVis, WallC.sz1); + rw_lightstep = (SafeDivScale12 (GlobVis, WallC.sz2) - rw_lightleft) / (WallC.sx2 - WallC.sx1); } else { @@ -2337,19 +2337,19 @@ void R_StoreWallRange (int start, int stop) } rw_offset = sidedef->GetTextureXOffset(side_t::mid); - rw_light = rw_lightleft + rw_lightstep * (start - WallC.SX1); + rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1); - ds_p->sx1 = WallC.SX1; - ds_p->sx2 = WallC.SX2; - ds_p->sz1 = WallC.SZ1; - ds_p->sz2 = WallC.SZ2; - ds_p->cx = WallC.TX1; - ds_p->cy = WallC.TY1; - ds_p->cdx = WallC.TX2 - WallC.TX1; - ds_p->cdy = WallC.TY2 - WallC.TY1; + ds_p->sx1 = WallC.sx1; + ds_p->sx2 = WallC.sx2; + ds_p->sz1 = WallC.sz1; + ds_p->sz2 = WallC.sz2; + ds_p->cx = WallC.tx1; + ds_p->cy = WallC.ty1; + ds_p->cdx = WallC.tx2 - WallC.tx1; + ds_p->cdy = WallC.ty2 - WallC.ty1; ds_p->tmapvals = WallT; - ds_p->siz1 = (DWORD)DivScale32 (1, WallC.SZ1) >> 1; - ds_p->siz2 = (DWORD)DivScale32 (1, WallC.SZ2) >> 1; + ds_p->siz1 = (DWORD)DivScale32 (1, WallC.sz1) >> 1; + ds_p->siz2 = (DWORD)DivScale32 (1, WallC.sz2) >> 1; ds_p->x1 = rw_x = start; ds_p->x2 = stop-1; ds_p->curline = curline; @@ -2442,7 +2442,7 @@ void R_StoreWallRange (int start, int stop) if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && - (WallC.SZ1 >= TOO_CLOSE_Z && WallC.SZ2 >= TOO_CLOSE_Z)) + (WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z)) { fixed_t *swal; fixed_t *lwal; @@ -2590,59 +2590,59 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) fixed_t s1, s2, s3, s4; z = -(z >> 4); - s1 = MulScale16 (globaluclip, wallc->SZ1); s2 = MulScale16 (globaluclip, wallc->SZ2); - s3 = MulScale16 (globaldclip, wallc->SZ1); s4 = MulScale16 (globaldclip, wallc->SZ2); + s1 = MulScale16 (globaluclip, wallc->sz1); s2 = MulScale16 (globaluclip, wallc->sz2); + s3 = MulScale16 (globaldclip, wallc->sz1); s4 = MulScale16 (globaldclip, wallc->sz2); bad = (zs3)<<2)+((z>s4)<<3); #if 1 if ((bad&3) == 3) { - memset (&mostbuf[wallc->SX1], 0, (wallc->SX2 - wallc->SX1)*sizeof(mostbuf[0])); + memset (&mostbuf[wallc->sx1], 0, (wallc->sx2 - wallc->sx1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) { - clearbufshort (&mostbuf[wallc->SX1], wallc->SX2 - wallc->SX1, viewheight); + clearbufshort (&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight); return bad; } #endif - ix1 = wallc->SX1; iy1 = wallc->SZ1; - ix2 = wallc->SX2; iy2 = wallc->SZ2; + ix1 = wallc->sx1; iy1 = wallc->sz1; + ix2 = wallc->sx2; iy2 = wallc->sz2; #if 1 if (bad & 3) { int t = DivScale30 (z-s1, s2-s1); - int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); - int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); + int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t); + int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty); if ((bad & 3) == 2) { - if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (wallc->SX2 > xcross) memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->sx2 > xcross) memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > wallc->SX1) memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->sx1) memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0])); } } if (bad & 12) { int t = DivScale30 (z-s3, s4-s3); - int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); - int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); + int inty = wallc->sz1 + MulScale30 (wallc->sz2 - wallc->sz1, t); + int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2 - wallc->sx1, inty); if ((bad & 12) == 8) { - if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2 - xcross, viewheight); + if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2 - xcross, viewheight); } else { - if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross - wallc->SX1, viewheight); + if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross - wallc->sx1, viewheight); } } @@ -2660,12 +2660,12 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) double max = viewheight; double zz = z / 65536.0; #if 0 - double z1 = zz * InvZtoScale / wallc->SZ1; - double z2 = zz * InvZtoScale / wallc->SZ2 - z1; - z2 /= (wallc->SX2 - wallc->SX1); + double z1 = zz * InvZtoScale / wallc->sz1; + double z2 = zz * InvZtoScale / wallc->sz2 - z1; + z2 /= (wallc->sx2 - wallc->sx1); z1 += centeryfrac / 65536.0; - for (int x = wallc->SX1; x < wallc->SX2; ++x) + for (int x = wallc->sx1; x < wallc->sx2; ++x) { mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); z1 += z2; @@ -2673,12 +2673,12 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) #else double top, bot, i; - i = wallc->SX1 - centerx; + i = wallc->sx1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; double cy = centeryfrac / 65536.0; - for (int x = wallc->SX1; x < wallc->SX2; x++) + for (int x = wallc->sx1; x < wallc->sx2; x++) { double frac = top / bot; double scale = frac * WallT.DepthScale + WallT.DepthOrg; @@ -2711,21 +2711,21 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { x = curline->v2->x; y = curline->v2->y; - if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) + if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2)) { - int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); + int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } z1 = viewz - plane.ZatPoint (x, y); - if (wallc->SX2 > wallc->SX1 + 1) + if (wallc->sx2 > wallc->sx1 + 1) { x = curline->v1->x; y = curline->v1->y; - if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) + if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2)) { - int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); + int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } @@ -2740,21 +2740,21 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { x = curline->v1->x; y = curline->v1->y; - if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) + if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2)) { - int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); + int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } z1 = viewz - plane.ZatPoint (x, y); - if (wallc->SX2 > wallc->SX1 + 1) + if (wallc->sx2 > wallc->sx1 + 1) { x = curline->v2->x; y = curline->v2->y; - if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) + if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2)) { - int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); + int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } @@ -2766,12 +2766,12 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) } } - s1 = MulScale12 (globaluclip, wallc->SZ1); s2 = MulScale12 (globaluclip, wallc->SZ2); - s3 = MulScale12 (globaldclip, wallc->SZ1); s4 = MulScale12 (globaldclip, wallc->SZ2); + s1 = MulScale12 (globaluclip, wallc->sz1); s2 = MulScale12 (globaluclip, wallc->sz2); + s3 = MulScale12 (globaldclip, wallc->sz1); s4 = MulScale12 (globaldclip, wallc->sz2); bad = (z1s3)<<2)+((z2>s4)<<3); - ix1 = wallc->SX1; ix2 = wallc->SX2; - iy1 = wallc->SZ1; iy2 = wallc->SZ2; + ix1 = wallc->sx1; ix2 = wallc->sx2; + iy1 = wallc->sz1; iy2 = wallc->sz2; oz1 = z1; oz2 = z2; if ((bad&3) == 3) @@ -2791,9 +2791,9 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { //inty = intz / (globaluclip>>16) int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); - int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); + int inty = wallc->sz1 + MulScale30 (wallc->sz2-wallc->sz1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1, inty); + int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2-wallc->sx1, inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2801,13 +2801,13 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) if ((bad&3) == 2) { - if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; } + memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0])); } } @@ -2815,9 +2815,9 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { //inty = intz / (globaldclip>>16) int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); - int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); + int inty = wallc->sz1 + MulScale30 (wallc->sz2-wallc->sz1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1,inty); + int xcross = wallc->sx1 + Scale (MulScale30 (wallc->sz2, t), wallc->sx2-wallc->sx1,inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2825,13 +2825,13 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) if ((bad&12) == 8) { - if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2-xcross, viewheight); + if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2-xcross, viewheight); } else { - if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross-wallc->SX1, viewheight); + if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; } + if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross-wallc->sx1, viewheight); } } @@ -3041,8 +3041,8 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z)) goto done; - x1 = WallC.SX1; - x2 = WallC.SX2; + x1 = WallC.sx1; + x2 = WallC.sx2; if (x1 > clipper->x2 || x2 <= clipper->x1) goto done; @@ -3145,7 +3145,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - WallC.SX1) * rw_lightstep; + rw_light = rw_lightleft + (x1 - WallC.sx1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = usecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) diff --git a/src/r_things.cpp b/src/r_things.cpp index 1d2c07a2a..72ebcf8c4 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -411,8 +411,8 @@ void R_DrawWallSprite(vissprite_t *spr) fixed_t yscale; int shade = LIGHT2SHADE(140); - x1 = MAX(spr->x1, spr->wallc.SX1); - x2 = MIN(spr->x2, spr->wallc.SX2 + 1); + x1 = MAX(spr->x1, spr->wallc.sx1); + x2 = MIN(spr->x2, spr->wallc.sx2 + 1); if (x1 >= x2) return; WallT.InitFromWallCoords(&spr->wallc); @@ -440,7 +440,7 @@ void R_DrawWallSprite(vissprite_t *spr) rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - spr->wallc.SX1) * rw_lightstep; + rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = usecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) @@ -1057,7 +1057,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z)) return; - if (wallc.SX1 > WindowRight || wallc.SX2 <= WindowLeft) + if (wallc.sx1 > WindowRight || wallc.sx2 <= WindowLeft) return; // Sprite sorting should probably treat these as walls, not sprites, @@ -1070,8 +1070,8 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f gzb = fz + yscale * scaled_bo; vis = R_NewVisSprite(); - vis->x1 = wallc.SX1 < WindowLeft ? WindowLeft : wallc.SX1; - vis->x2 = wallc.SX2 >= WindowRight ? WindowRight-1 : wallc.SX2-1; + vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; + vis->x2 = wallc.sx2 >= WindowRight ? WindowRight-1 : wallc.sx2-1; vis->idepth = (unsigned)DivScale32(1, tz) >> 1; vis->depth = tz; vis->sector = thing->Sector; From 0aa67c68ab44ee79dbbad27765ae41e18d41256d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 17:23:06 -0500 Subject: [PATCH 302/311] Redo lighting for each wall sprite - Because previously it just reused whatever the most recently drawn wall used. --- src/r_things.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 72ebcf8c4..84ce18b64 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -409,7 +409,6 @@ void R_DrawWallSprite(vissprite_t *spr) { int x1, x2; fixed_t yscale; - int shade = LIGHT2SHADE(140); x1 = MAX(spr->x1, spr->wallc.sx1); x2 = MIN(spr->x2, spr->wallc.sx2 + 1); @@ -440,6 +439,10 @@ void R_DrawWallSprite(vissprite_t *spr) rereadcolormap = false; } + int shade = LIGHT2SHADE(spr->sector->lightlevel + r_actualextralight); + GlobVis = r_WallVisibility; + rw_lightleft = SafeDivScale12(GlobVis, spr->wallc.sz1); + rw_lightstep = (SafeDivScale12(GlobVis, spr->wallc.sz2) - rw_lightleft) / (spr->wallc.sx2 - spr->wallc.sx1); rw_light = rw_lightleft + (x1 - spr->wallc.sx1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = usecolormap->Maps + fixedlightlev; From 6303935ad61bc360dae646ac052a784b1d68e782 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 19:57:55 -0500 Subject: [PATCH 303/311] Use wall sprite Y scale --- src/r_things.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 84ce18b64..9a6bfee6f 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -416,8 +416,8 @@ void R_DrawWallSprite(vissprite_t *spr) return; WallT.InitFromWallCoords(&spr->wallc); PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); - dc_texturemid = spr->gzt - viewz; - yscale = FRACUNIT; + yscale = spr->yscale; + dc_texturemid = FixedDiv(spr->gzt - viewz, yscale); if (spr->renderflags & RF_XFLIP) { int right = (spr->pic->GetWidth() << FRACBITS) - 1; @@ -1075,6 +1075,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f vis = R_NewVisSprite(); vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; vis->x2 = wallc.sx2 >= WindowRight ? WindowRight-1 : wallc.sx2-1; + vis->yscale = yscale; vis->idepth = (unsigned)DivScale32(1, tz) >> 1; vis->depth = tz; vis->sector = thing->Sector; From 7b02027ba72879a95261d353f1155c0e8d33a823 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 20:00:49 -0500 Subject: [PATCH 304/311] Fixed: Wall sprites cut off one pixel short of the window's right border --- src/r_things.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 9a6bfee6f..801d25bfb 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -411,7 +411,7 @@ void R_DrawWallSprite(vissprite_t *spr) fixed_t yscale; x1 = MAX(spr->x1, spr->wallc.sx1); - x2 = MIN(spr->x2, spr->wallc.sx2 + 1); + x2 = MIN(spr->x2 + 1, spr->wallc.sx2 + 1); if (x1 >= x2) return; WallT.InitFromWallCoords(&spr->wallc); @@ -1074,7 +1074,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f vis = R_NewVisSprite(); vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; - vis->x2 = wallc.sx2 >= WindowRight ? WindowRight-1 : wallc.sx2-1; + vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2-1; vis->yscale = yscale; vis->idepth = (unsigned)DivScale32(1, tz) >> 1; vis->depth = tz; From 9659b894a3663aceb640d61e6950e1ac7ef256b5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 20:43:09 -0500 Subject: [PATCH 305/311] Skip neardepth/fardepth checking in R_DrawSprite - Wall sprites now clip much, much better than before. --- src/r_things.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 801d25bfb..092e799dc 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2076,19 +2076,9 @@ void R_DrawSprite (vissprite_t *spr) r1 = MAX (ds->x1, x1); r2 = MIN (ds->x2, x2); - fixed_t neardepth, fardepth; - if (ds->sz1 < ds->sz2) - { - neardepth = ds->sz1, fardepth = ds->sz2; - } - else - { - neardepth = ds->sz2, fardepth = ds->sz1; - } - if (neardepth > spr->depth || (fardepth > spr->depth && - // Check if sprite is in front of draw seg: - DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, - ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0)) + // Check if sprite is in front of draw seg: + if (DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, + ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0) { // seg is behind sprite, so draw the mid texture if it has one if (ds->maskedtexturecol != -1 || ds->bFogBoundary) From e6a1d6b516eb45206e8a688de26dd70c357799ef Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:00:02 -0500 Subject: [PATCH 306/311] Parse more info from Blood's map header --- src/p_buildmap.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 32651b5bb..7e2f0b472 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -249,7 +249,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * BYTE infoBlock[37]; int mapver = data[5]; DWORD matt; - int numRevisions, numWalls, numsprites, skyLen; + int numRevisions, numWalls, numsprites, skyLen, visibility, parallaxType; int i; int k; @@ -269,11 +269,14 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * { memcpy (infoBlock, data + 6, 37); } + skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16)); + visibility = LittleLong(*(DWORD *)(infoBlock + 18)); + parallaxType = infoBlock[26]; numRevisions = LittleLong(*(DWORD *)(infoBlock + 27)); numsectors = LittleShort(*(WORD *)(infoBlock + 31)); numWalls = LittleShort(*(WORD *)(infoBlock + 33)); numsprites = LittleShort(*(WORD *)(infoBlock + 35)); - skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16)); + Printf("Visibility: %d\n", visibility); if (mapver == 7) { From fbb5689f298348003c5fbf90956656e1f946e30f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:26:24 -0500 Subject: [PATCH 307/311] Eliminate extra vars from FWallCoords - cx1, cx2, cy1, and cy2 are not used anywhere, so get rid of them. - Also annotated the comments to indicate the corresponding arrays in the Build engine. --- src/r_bsp.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/r_bsp.h b/src/r_bsp.h index 79dac6c88..1b5af9805 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -33,14 +33,11 @@ struct FWallCoords { - fixed_t tx1, tx2; // x coords at left, right of wall in view space - fixed_t ty1, ty2; // y coords at left, right of wall in view space + fixed_t tx1, tx2; // x coords at left, right of wall in view space rx1,rx2 + fixed_t ty1, ty2; // y coords at left, right of wall in view space ry1,ry2 - fixed_t cx1, cx2; // x coords at left, right of wall in camera space - fixed_t cy1, cy2; // y coords at left, right of wall in camera space - - short sx1, sx2; // x coords at left, right of wall in screen space - fixed_t sz1, sz2; // depth at left, right of wall in screen space + short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2 + fixed_t sz1, sz2; // depth at left, right of wall in screen space yb1,yb2 bool Init(int x1, int y1, int x2, int y2, int too_close); }; From 46592f5f6d3c72938911df920a9afb4391964a33 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:27:48 -0500 Subject: [PATCH 308/311] Don't clamp SHADE2LIGHT - Light levels aren't stored in bytes anymore, so there's no reason to clamp it anymore when loading Build maps. --- src/p_buildmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 7e2f0b472..2ee2ae83a 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -20,8 +20,8 @@ // MACROS ------------------------------------------------------------------ -//#define SHADE2LIGHT(s) (clamp (160-2*(s), 0, 255)) -#define SHADE2LIGHT(s) (clamp (255-2*s, 0, 255)) +//#define SHADE2LIGHT(s) (160-2*(s)) +#define SHADE2LIGHT(s) (255-2*s) // TYPES ------------------------------------------------------------------- From fefe6aa2c105e38056cf35668bd51f5f5b4073be Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:40:12 -0500 Subject: [PATCH 309/311] Specie -> Species - specie: money in the form of coins rather than notes - species: a group of living organisms consisting of similar individuals capable of exchanging genes or interbreeding --- src/p_map.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 68c2c1530..4ea8762ec 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3470,7 +3470,7 @@ struct Origin { AActor *Caller; bool hitGhosts; - bool hitSameSpecie; + bool hitSameSpecies; }; static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) @@ -3488,7 +3488,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) return TRACE_Skip; } - if (data->hitSameSpecie && res.Actor->GetSpecies() == data->Caller->GetSpecies()) + if (data->hitSameSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies()) { return TRACE_Skip; } @@ -3517,8 +3517,6 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, TData.Caller = t1; angle_t srcangle = angle; int srcpitch = pitch; - bool hitGhosts; - bool hitSameSpecie; bool killPuff = false; AActor *puff = NULL; int pflag = 0; @@ -3566,7 +3564,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, (t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) || (puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST)); - TData.hitSameSpecie = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES)); + TData.hitSameSpecies = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES)); // if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type. // All other explicitly passed damage types (currenty only MDK) will be preserved. From 891b3da1038a0a3cb759e39678881d480c2bed82 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:43:23 -0500 Subject: [PATCH 310/311] Remove extra magnitude from magic texture mapping values - These used to be fixed point, but now they're floating point, so the excess magnitude is unneeded. --- src/r_bsp.cpp | 24 ++++++++++++------------ src/r_main.cpp | 4 +--- src/r_main.h | 1 - 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index c56255888..146ea5673 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -809,17 +809,17 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) { if (MirrorFlags & RF_XFLIP) { - UoverZorg = (float)wallc->tx2 * WallTMapScale; - UoverZstep = (float)(-wallc->ty2) * 32.f; - InvZorg = (float)(wallc->tx2 - wallc->tx1) * WallTMapScale; - InvZstep = (float)(wallc->ty1 - wallc->ty2) * 32.f; + UoverZorg = (float)wallc->tx2 * centerx; + UoverZstep = (float)(-wallc->ty2); + InvZorg = (float)(wallc->tx2 - wallc->tx1) * centerx; + InvZstep = (float)(wallc->ty1 - wallc->ty2); } else { - UoverZorg = (float)wallc->tx1 * WallTMapScale; - UoverZstep = (float)(-wallc->ty1) * 32.f; - InvZorg = (float)(wallc->tx1 - wallc->tx2) * WallTMapScale; - InvZstep = (float)(wallc->ty2 - wallc->ty1) * 32.f; + UoverZorg = (float)wallc->tx1 * centerx; + UoverZstep = (float)(-wallc->ty1); + InvZorg = (float)(wallc->tx1 - wallc->tx2) * centerx; + InvZstep = (float)(wallc->ty2 - wallc->ty1); } InitDepth(); } @@ -837,10 +837,10 @@ void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) fullx2 = -fullx2; } - UoverZorg = (float)fullx1 * WallTMapScale; - UoverZstep = (float)(-fully1) * 32.f; - InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - InvZstep = (float)(fully2 - fully1) * 32.f; + UoverZorg = (float)fullx1 * centerx; + UoverZstep = (float)(-fully1); + InvZorg = (float)(fullx1 - fullx2) * centerx; + InvZstep = (float)(fully2 - fully1); InitDepth(); } diff --git a/src/r_main.cpp b/src/r_main.cpp index bc3c4c7c0..dbf4cbeb5 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -117,7 +117,6 @@ FDynamicColormap*basecolormap; // [RH] colormap currently drawing with int fixedlightlev; lighttable_t *fixedcolormap; FSpecialColormap *realfixedcolormap; -float WallTMapScale; float WallTMapScale2; @@ -386,8 +385,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, iyaspectmulfloat = (float)virtwidth * r_Yaspect / 320.f / (float)virtheight; InvZtoScale = yaspectmul * centerx; - WallTMapScale = (float)centerx * 32.f; - WallTMapScale2 = iyaspectmulfloat * 2.f / (float)centerx; + WallTMapScale2 = iyaspectmulfloat * 64.f / (float)centerx; // psprite scales pspritexscale = (centerxwide << FRACBITS) / 160; diff --git a/src/r_main.h b/src/r_main.h index 0126d3906..715a60610 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -42,7 +42,6 @@ extern fixed_t FocalLengthX, FocalLengthY; extern float FocalLengthXfloat; extern fixed_t InvZtoScale; -extern float WallTMapScale; extern float WallTMapScale2; extern int viewwindowx; From bf0856aef5e55c7b10eac2cb7ac4e9d0489a163b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:58:11 -0500 Subject: [PATCH 311/311] Remove DepthScale and DepthOrg from FWallTmapVals --- src/r_bsp.cpp | 8 -------- src/r_bsp.h | 2 -- src/r_segs.cpp | 4 +++- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 146ea5673..bf0ac910f 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -821,7 +821,6 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) InvZorg = (float)(wallc->tx1 - wallc->tx2) * centerx; InvZstep = (float)(wallc->ty2 - wallc->ty1); } - InitDepth(); } void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) @@ -841,13 +840,6 @@ void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) UoverZstep = (float)(-fully1); InvZorg = (float)(fullx1 - fullx2) * centerx; InvZstep = (float)(fully2 - fully1); - InitDepth(); -} - -void FWallTmapVals::InitDepth() -{ - DepthScale = InvZstep * WallTMapScale2; - DepthOrg = -UoverZstep * WallTMapScale2; } // diff --git a/src/r_bsp.h b/src/r_bsp.h index 1b5af9805..acd519c62 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -44,13 +44,11 @@ struct FWallCoords struct FWallTmapVals { - float DepthOrg, DepthScale; float UoverZorg, UoverZstep; float InvZorg, InvZstep; void InitFromWallCoords(const FWallCoords *wallc); void InitFromLine(int x1, int y1, int x2, int y2); - void InitDepth(); }; extern FWallCoords WallC; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 15f736c93..cf00abc45 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2893,6 +2893,8 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x { // swall = scale, lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); + double depth_scale = WallT.InvZstep * WallTMapScale2; + double depth_org = -WallT.UoverZstep * WallTMapScale2; i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; @@ -2909,7 +2911,7 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x { lwall[x] = xs_RoundToInt(frac * xrepeat); } - swall[x] = xs_RoundToInt(frac * WallT.DepthScale + WallT.DepthOrg); + swall[x] = xs_RoundToInt(frac * depth_scale + depth_org); top += WallT.UoverZstep; bot += WallT.InvZstep; }