From 193b491b63c5b2f1c6fcca100f747b8fd936be7e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 4 Apr 2015 17:36:55 +0300 Subject: [PATCH 01/58] Added control of automatic graphics switching on OS X Automatic graphics switching is enabled by default Set vid_autoswitch CVAR to false to disable it --- src/posix/cocoa/i_video.mm | 10 ++++++++++ src/posix/osx/zdoom-info.plist | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 350202a13..29e6bf4d4 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -72,6 +72,11 @@ CUSTOM_CVAR(Bool, fullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) setmodeneeded = true; } +CUSTOM_CVAR(Bool, vid_autoswitch, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + Printf("You must restart " GAMENAME " to apply graphics switching mode\n"); +} + RenderBufferOptions rbOpts; @@ -399,6 +404,11 @@ CocoaVideo::CocoaVideo(const int multisample) attributes[i++] = NSOpenGLPFAStencilSize; attributes[i++] = NSOpenGLPixelFormatAttribute(8); + if (!vid_autoswitch) + { + attributes[i++] = NSOpenGLPFAAllowOfflineRenderers; + } + if (multisample) { attributes[i++] = NSOpenGLPFAMultisample; diff --git a/src/posix/osx/zdoom-info.plist b/src/posix/osx/zdoom-info.plist index 2a1911cdf..73be09aa8 100644 --- a/src/posix/osx/zdoom-info.plist +++ b/src/posix/osx/zdoom-info.plist @@ -43,5 +43,7 @@ NSPrincipalClass NSApplication + NSSupportsAutomaticGraphicsSwitching + YES From 1fddd1859e6b6aca3e7e8cb603f798a8329385f1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Apr 2015 00:38:29 +0200 Subject: [PATCH 02/58] - fixed: FResourceFile::FilterLumps must use a proper copy of the filename to pass to LumpNameSetup instead of a pointer to the file name's stringbuffer, because that function will overwrite the variable it is taken from. --- src/resourcefiles/resourcefile.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index ebeb40d96..b4280adf6 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -98,8 +98,7 @@ void FResourceLump::LumpNameSetup(const char *iname) base = base.Left(base.LastIndexOf('.')); uppercopy(Name, base); Name[8] = 0; - FString temp = iname; // Note: iname can point to inside FullName's string buffer so we cannot do the assignment directly. - FullName = temp; + FullName = iname; // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. @@ -382,7 +381,7 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, { FResourceLump *lump = (FResourceLump *)lump_p; assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0); - lump->LumpNameSetup(&lump->FullName[filter.Len()]); + lump->LumpNameSetup(lump->FullName.Mid(filter.Len())); } // Move filtered lumps to the end of the lump list. From bbbbb7ac9d513c11c44ca5aa78303fa8bd1cfdd7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 17:05:38 -0500 Subject: [PATCH 03/58] Reorder FMapThing to remove padding --- src/doomdata.h | 4 ++-- src/p_buildmap.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index b51dd5d20..71e581e26 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -347,10 +347,10 @@ struct FMapThing fixed_t y; fixed_t z; short angle; - FDoomEdEntry *info; - short EdNum; WORD SkillFilter; WORD ClassFilter; + short EdNum; + FDoomEdEntry *info; DWORD flags; int special; int args[5]; diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index c6fffd87c..ddfa0e2ec 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -781,14 +781,14 @@ vertex_t *FindVertex (fixed_t x, fixed_t y) static void CreateStartSpot (fixed_t *pos, FMapThing *start) { short angle = LittleShort(*(WORD *)(&pos[3])); - FMapThing mt = - { - 0, (LittleLong(pos[0])<<12), ((-LittleLong(pos[1]))<<12), 0,// tid, x, y, z - short(Scale ((2048-angle)&2047, 360, 2048)), DoomEdMap.CheckKey(1), 1, // angle, type - 0, 0, // Skillfilter, Classfilter - 7|MTF_SINGLE|224, // flags - 0, {0}, 0 // special is 0, args and Conversation are 0 - }; + FMapThing mt = { 0, }; + + mt.x = LittleLong(pos[0])<<12; + mt.y = (-LittleLong(pos[1]))<<12; + mt.angle = short(Scale((2048-angle)&2047, 360, 2048)); + mt.info = DoomEdMap.CheckKey(1); + mt.EdNum = 1; + mt.flags = 7|MTF_SINGLE|224; *start = mt; } From 2103fe2a14aed2a1fd61cc3fd936f19229e7652b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 17:14:17 -0500 Subject: [PATCH 04/58] Make FResourceLump::LumpNameSetup's argument an FString --- src/resourcefiles/resourcefile.cpp | 7 +++---- src/resourcefiles/resourcefile.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index b4280adf6..6b4c8c29b 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -90,11 +90,10 @@ FResourceLump::~FResourceLump() // //========================================================================== -void FResourceLump::LumpNameSetup(const char *iname) +void FResourceLump::LumpNameSetup(FString iname) { - const char *lname = strrchr(iname,'/'); - lname = (lname == NULL) ? iname : lname + 1; - FString base = lname; + long slash = iname.LastIndexOf('/'); + FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname; base = base.Left(base.LastIndexOf('.')); uppercopy(Name, base); Name[8] = 0; diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index 9927b1eae..c62981ca7 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -44,7 +44,7 @@ struct FResourceLump virtual FileReader *NewReader(); virtual int GetFileOffset() { return -1; } virtual int GetIndexNum() const { return 0; } - void LumpNameSetup(const char *iname); + void LumpNameSetup(FString iname); void CheckEmbedded(); void *CacheLump(); From 4315423200af3ba414b9057e1755048af6a85a14 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 17:38:45 -0500 Subject: [PATCH 05/58] Rename ns_invalid to ns_hidden - Also use ns_hidden by name in LumpNameSetup(). --- src/resourcefiles/resourcefile.cpp | 6 +++--- src/w_wad.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index 6b4c8c29b..bb3776e83 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -115,12 +115,12 @@ void FResourceLump::LumpNameSetup(FString iname) !strncmp(iname, "sounds/", 7) ? ns_sounds : !strncmp(iname, "music/", 6) ? ns_music : !strchr(iname, '/') ? ns_global : - -1; + ns_hidden; // Anything that is not in one of these subdirectories or the main directory // should not be accessible through the standard WAD functions but only through // the ones which look for the full name. - if (Namespace == -1) + if (Namespace == ns_hidden) { memset(Name, 0, 8); } @@ -428,7 +428,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, DWORD max) FResourceLump *lump = (FResourceLump *)p; lump->FullName = 0; lump->Name[0] = '\0'; - lump->Namespace = ns_invalid; + lump->Namespace = ns_hidden; } } } diff --git a/src/w_wad.h b/src/w_wad.h index 262a332c6..63912373e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -52,7 +52,7 @@ struct wadlump_t // [RH] Namespaces from BOOM. typedef enum { - ns_invalid = -1, + ns_hidden = -1, ns_global = 0, ns_sprites, From 6da887c34fcbc55cfd0115cfe3ebcc3001bf0c4a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 17:47:36 -0500 Subject: [PATCH 06/58] Use Truncate to chop off extension in LumpNameSetup. - Left() always creates a new string. Truncate() can reuse the old one if it only has one reference. --- src/resourcefiles/resourcefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index bb3776e83..caeb1090f 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -94,7 +94,7 @@ void FResourceLump::LumpNameSetup(FString iname) { long slash = iname.LastIndexOf('/'); FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname; - base = base.Left(base.LastIndexOf('.')); + base.Truncate(base.LastIndexOf('.')); uppercopy(Name, base); Name[8] = 0; FullName = iname; From e451faa1ccaa66feb05c2425cc3c5b2a12ca9d3d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 18:02:49 -0500 Subject: [PATCH 07/58] Fixed: FString::ReallocBuffer could write to unallocated memory - Previously, calling ReallocBuffer with a smaller buffer size than the current one could overwrite unallocated memory. This required that the string it was called on had more than one reference and therefore required creating a new copy. The entire original string would be copied, whether it fit in the new buffer or not. --- src/zstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zstring.cpp b/src/zstring.cpp index 14d19f46f..510ff19d7 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -1096,7 +1096,7 @@ void FString::ReallocBuffer (size_t newlen) { // If more than one reference, we must use a new copy FStringData *old = Data(); AllocBuffer (newlen); - StrCopy (Chars, old->Chars(), old->Len); + StrCopy (Chars, old->Chars(), newlen < old->Len ? newlen : old->Len); old->Release(); } else From 89054f5d60908440b9e5592cf00dbb2ef9304a34 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Apr 2015 18:39:22 -0500 Subject: [PATCH 08/58] Use filtering and LOADACS to autoload strfhelp.o - No more special case for STRFHELP in the executable! --- src/p_acs.cpp | 6 ------ wadsrc/static/{ => filter/strife}/acs/strfhelp.o | Bin wadsrc/static/filter/strife/loadacs.txt | 1 + 3 files changed, 1 insertion(+), 6 deletions(-) rename wadsrc/static/{ => filter/strife}/acs/strfhelp.o (100%) create mode 100644 wadsrc/static/filter/strife/loadacs.txt diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 8894bc936..5556507b7 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1409,12 +1409,6 @@ void DPlaneWatcher::Tick () // own behavior is loaded (if it has one). void FBehavior::StaticLoadDefaultModules () { - // When playing Strife, STRFHELP is always loaded. - if (gameinfo.gametype == GAME_Strife) - { - StaticLoadModule (Wads.CheckNumForName ("STRFHELP", ns_acslibrary)); - } - // Scan each LOADACS lump and load the specified modules in order int lump, lastlump = 0; diff --git a/wadsrc/static/acs/strfhelp.o b/wadsrc/static/filter/strife/acs/strfhelp.o similarity index 100% rename from wadsrc/static/acs/strfhelp.o rename to wadsrc/static/filter/strife/acs/strfhelp.o diff --git a/wadsrc/static/filter/strife/loadacs.txt b/wadsrc/static/filter/strife/loadacs.txt new file mode 100644 index 000000000..eb41c01ae --- /dev/null +++ b/wadsrc/static/filter/strife/loadacs.txt @@ -0,0 +1 @@ +strfhelp From 82f7b439c889500ad2e8bececb8cebe595886381 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Apr 2015 10:59:07 +0300 Subject: [PATCH 09/58] Improved text pasting on OS X Support for UTF-8 and UTF-16 encodings should cover all cases of text pasting from clipboard --- src/posix/i_system.cpp | 44 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index b3de61419..f87cf76ae 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -603,6 +603,15 @@ int I_FindAttr (findstate_t *fileinfo) #ifdef __APPLE__ static PasteboardRef s_clipboard; + +static CFDataRef GetPasteboardData(const PasteboardItemID itemID, const CFStringRef flavorType) +{ + CFDataRef data = NULL; + + const OSStatus result = PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &data); + + return noErr == result ? data : NULL; +} #endif // __APPLE__ // Clipboard support requires GTK+ @@ -688,35 +697,36 @@ FString I_GetFromClipboard (bool use_primary_selection) return FString(); } - CFArrayRef flavorTypeArray; - - if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray)) + if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText)) { - return FString(); + result = reinterpret_cast(CFDataGetBytePtr(data)); } - - const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray); - - for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex) + else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText)) { - const CFStringRef flavorType = static_cast( - CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex)); +#ifdef __LITTLE_ENDIAN__ + static const CFStringEncoding ENCODING = kCFStringEncodingUTF16LE; +#else // __BIG_ENDIAN__ + static const CFStringEncoding ENCODING = kCFStringEncodingUTF16BE; +#endif // __LITTLE_ENDIAN__ - if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text"))) + if (const CFStringRef utf16 = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, ENCODING)) { - CFDataRef flavorData; + const CFRange range = { 0, CFStringGetLength(utf16) }; + CFIndex bufferLength = 0; - if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData)) + if (CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, NULL, 0, &bufferLength) > 0) { - result += reinterpret_cast(CFDataGetBytePtr(flavorData)); + UInt8* const buffer = reinterpret_cast(result.LockNewBuffer(bufferLength)); + + CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, buffer, bufferLength, NULL); + + result.UnlockBuffer(); } - CFRelease(flavorData); + CFRelease(utf16); } } - CFRelease(flavorTypeArray); - return result; #endif return ""; From ebd8f2410347477e774515a53ca402c64e765daa Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Apr 2015 11:39:49 +0300 Subject: [PATCH 10/58] Fixed compilation with OS X SDK 10.4 --- src/posix/cocoa/i_common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/posix/cocoa/i_common.h b/src/posix/cocoa/i_common.h index 081466e87..545540b2f 100644 --- a/src/posix/cocoa/i_common.h +++ b/src/posix/cocoa/i_common.h @@ -128,6 +128,8 @@ enum kVK_UpArrow = 0x7E }; +static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSOpenGLPixelFormatAttribute(96); + #endif // prior to 10.5 From 7b8931292318c145ce34ec53d4ee8f6a3291274e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 5 Apr 2015 11:52:57 +0300 Subject: [PATCH 11/58] Fixed potential issue with read beyond buffer boundaries --- src/posix/i_system.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index f87cf76ae..0a1b2f69a 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -699,7 +699,12 @@ FString I_GetFromClipboard (bool use_primary_selection) if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText)) { - result = reinterpret_cast(CFDataGetBytePtr(data)); + const CFIndex bufferLength = CFDataGetLength(data); + char* const buffer = result.LockNewBuffer(bufferLength); + + memcpy(buffer, CFDataGetBytePtr(data), bufferLength); + + result.UnlockBuffer(); } else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText)) { From a91997d12c41805421dd446fdd6a045b898857d9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 5 Apr 2015 22:07:24 +0200 Subject: [PATCH 12/58] - fixed: Don't try to load autoload sections for empty section names. --- 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 ab2459788..930b0f629 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2031,7 +2031,7 @@ static void AddAutoloadFiles(const char *group, const char *autoname) D_AddConfigWads (allwads, file); // Add group-specific wads - if (group != NULL) + if (group != NULL && group[0] != 0) { file = group; file += ".Autoload"; @@ -2039,7 +2039,7 @@ static void AddAutoloadFiles(const char *group, const char *autoname) } // Add IWAD-specific wads - if (autoname != NULL) + if (autoname != NULL && autoname[0] != 0) { file = autoname; file += ".Autoload"; From 62d036a63e12cdafb74ff617a5bd58444892284e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 5 Apr 2015 20:24:49 -0500 Subject: [PATCH 13/58] Added gametype-based filter - For when IWADs are too specific, filter by the base gametype too. - Minor small edits to the sndinfo.txt files so that zipdir will notice the changes, since it doesn't check path names when checking for file differences. --- src/resourcefiles/resourcefile.cpp | 35 ++++++++++++++++++ src/resourcefiles/resourcefile.h | 1 + .../{doom => game-doomchex}/sndinfo.txt | 1 + .../{heretic => game-heretic}/sndinfo.txt | 1 + .../filter/{hexen => game-hexen}/sndinfo.txt | 1 + .../{strife => game-strife}/acs/strfhelp.o | Bin .../{strife => game-strife}/loadacs.txt | 0 .../{strife => game-strife}/sndinfo.txt | 1 + 8 files changed, 40 insertions(+) rename wadsrc/static/filter/{doom => game-doomchex}/sndinfo.txt (99%) rename wadsrc/static/filter/{heretic => game-heretic}/sndinfo.txt (99%) rename wadsrc/static/filter/{hexen => game-hexen}/sndinfo.txt (99%) rename wadsrc/static/filter/{strife => game-strife}/acs/strfhelp.o (100%) rename wadsrc/static/filter/{strife => game-strife}/loadacs.txt (100%) rename wadsrc/static/filter/{strife => game-strife}/sndinfo.txt (99%) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index caeb1090f..d5ad659af 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -344,6 +344,7 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize) // in the ini file use. We reduce the maximum lump concidered after // each one so that we don't risk refiltering already filtered lumps. DWORD max = NumLumps; + max -= FilterLumpsByGameType(gameinfo.gametype, lumps, lumpsize, max); max -= FilterLumps(gameinfo.ConfigName, lumps, lumpsize, max); max -= FilterLumps(LumpFilterGroup, lumps, lumpsize, max); max -= FilterLumps(LumpFilterIWAD, lumps, lumpsize, max); @@ -406,6 +407,40 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, return end - start; } +//========================================================================== +// +// FResourceFile :: FilterLumpsByGameType +// +// Matches any lumps that match "filter/game-/*". Includes +// inclusive gametypes like Raven. +// +//========================================================================== + +int FResourceFile::FilterLumpsByGameType(int type, void *lumps, size_t lumpsize, DWORD max) +{ + static const struct { int match; const char *name; } blanket[] = + { + { GAME_Raven, "game-Raven" }, + { GAME_DoomStrifeChex, "game-DoomStrifeChex" }, + { GAME_DoomChex, "game-DoomChex" }, + }; + if (type == 0) + { + return 0; + } + int count = 0; + for (int i = 0; i < countof(blanket); ++i) + { + if (type & blanket[i].match) + { + count += FilterLumps(blanket[i].name, lumps, lumpsize, max); + } + } + FString filter = "game-"; + filter += GameNames[type]; + return count + FilterLumps(filter, lumps, lumpsize, max); +} + //========================================================================== // // FResourceFile :: JunkLeftoverFilters diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index c62981ca7..e84967a24 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -72,6 +72,7 @@ private: DWORD FirstLump; int FilterLumps(FString filtername, void *lumps, size_t lumpsize, DWORD max); + int FilterLumpsByGameType(int gametype, void *lumps, size_t lumpsize, DWORD max); bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, DWORD max, DWORD &start, DWORD &end); void JunkLeftoverFilters(void *lumps, size_t lumpsize, DWORD max); diff --git a/wadsrc/static/filter/doom/sndinfo.txt b/wadsrc/static/filter/game-doomchex/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/doom/sndinfo.txt rename to wadsrc/static/filter/game-doomchex/sndinfo.txt index 6028b11f0..c103f493c 100644 --- a/wadsrc/static/filter/doom/sndinfo.txt +++ b/wadsrc/static/filter/game-doomchex/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* DOOM SOUNDS */ diff --git a/wadsrc/static/filter/heretic/sndinfo.txt b/wadsrc/static/filter/game-heretic/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/heretic/sndinfo.txt rename to wadsrc/static/filter/game-heretic/sndinfo.txt index cb3fe1e73..b9f1fd7c3 100644 --- a/wadsrc/static/filter/heretic/sndinfo.txt +++ b/wadsrc/static/filter/game-heretic/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* HERETIC SOUNDS */ diff --git a/wadsrc/static/filter/hexen/sndinfo.txt b/wadsrc/static/filter/game-hexen/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/hexen/sndinfo.txt rename to wadsrc/static/filter/game-hexen/sndinfo.txt index 85d7a75dd..a1169dcb9 100644 --- a/wadsrc/static/filter/hexen/sndinfo.txt +++ b/wadsrc/static/filter/game-hexen/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* HEXEN SOUNDS */ diff --git a/wadsrc/static/filter/strife/acs/strfhelp.o b/wadsrc/static/filter/game-strife/acs/strfhelp.o similarity index 100% rename from wadsrc/static/filter/strife/acs/strfhelp.o rename to wadsrc/static/filter/game-strife/acs/strfhelp.o diff --git a/wadsrc/static/filter/strife/loadacs.txt b/wadsrc/static/filter/game-strife/loadacs.txt similarity index 100% rename from wadsrc/static/filter/strife/loadacs.txt rename to wadsrc/static/filter/game-strife/loadacs.txt diff --git a/wadsrc/static/filter/strife/sndinfo.txt b/wadsrc/static/filter/game-strife/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/strife/sndinfo.txt rename to wadsrc/static/filter/game-strife/sndinfo.txt index 877bba50a..22f9b8356 100644 --- a/wadsrc/static/filter/strife/sndinfo.txt +++ b/wadsrc/static/filter/game-strife/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* STRIFE SOUNDS */ From c36222d2ef6c61e5d1693130d6311ff90df41ac6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 5 Apr 2015 21:40:53 -0500 Subject: [PATCH 14/58] Externalized default key bindings --- src/c_bind.cpp | 208 +++--------------- src/c_bind.h | 7 - src/d_main.cpp | 2 + src/gameconfigfile.cpp | 70 +++--- src/gameconfigfile.h | 1 + wadsrc/static/defbinds.txt | 103 +++++++++ .../static/filter/game-heretic/defbinds.txt | 3 + wadsrc/static/filter/game-hexen/defbinds.txt | 12 + wadsrc/static/filter/game-strife/defbinds.txt | 11 + 9 files changed, 191 insertions(+), 226 deletions(-) create mode 100644 wadsrc/static/defbinds.txt create mode 100644 wadsrc/static/filter/game-heretic/defbinds.txt create mode 100644 wadsrc/static/filter/game-hexen/defbinds.txt create mode 100644 wadsrc/static/filter/game-strife/defbinds.txt diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 1a62469bc..0231820dc 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -43,158 +43,11 @@ #include "configfile.h" #include "i_system.h" #include "d_event.h" +#include "w_wad.h" #include #include -/* Default keybindings for Doom (and all other games) - */ -static const FBinding DefBindings[] = -{ - { "`", "toggleconsole" }, - { "1", "slot 1" }, - { "2", "slot 2" }, - { "3", "slot 3" }, - { "4", "slot 4" }, - { "5", "slot 5" }, - { "6", "slot 6" }, - { "7", "slot 7" }, - { "8", "slot 8" }, - { "9", "slot 9" }, - { "0", "slot 0" }, - { "[", "invprev" }, - { "]", "invnext" }, - { "mwheelleft", "invprev" }, - { "mwheelright", "invnext" }, - { "enter", "invuse" }, - { "-", "sizedown" }, - { "=", "sizeup" }, - { "ctrl", "+attack" }, - { "alt", "+strafe" }, - { "shift", "+speed" }, - { "space", "+use" }, - { "rightarrow", "+right" }, - { "leftarrow", "+left" }, - { "uparrow", "+forward" }, - { "downarrow", "+back" }, - { ",", "+moveleft" }, - { ".", "+moveright" }, - { "mouse1", "+attack" }, - { "mouse2", "+strafe" }, - { "mouse3", "+forward" }, - { "mouse4", "+speed" }, - { "capslock", "toggle cl_run" }, - { "f1", "menu_help" }, - { "f2", "menu_save" }, - { "f3", "menu_load" }, - { "f4", "menu_options" }, - { "f5", "menu_display" }, - { "f6", "quicksave" }, - { "f7", "menu_endgame" }, - { "f8", "togglemessages" }, - { "f9", "quickload" }, - { "f11", "bumpgamma" }, - { "f10", "menu_quit" }, - { "tab", "togglemap" }, - { "pause", "pause" }, - { "sysrq", "screenshot" }, - { "t", "messagemode" }, - { "\\", "+showscores" }, - { "f12", "spynext" }, - { "mwheeldown", "weapnext" }, - { "mwheelup", "weapprev" }, - - // Generic joystick buttons - { "joy1", "+attack" }, - { "joy2", "+strafe" }, - { "joy3", "+speed" }, - { "joy4", "+use" }, - - // Xbox 360 / PS2 controllers - { "pad_a", "+use" }, - { "pad_y", "+jump" }, - { "rtrigger", "+attack" }, - { "ltrigger", "+altattack" }, - { "lshoulder", "weapprev" }, - { "rshoulder", "weapnext" }, - { "dpadleft", "invprev" }, - { "dpadright", "invnext" }, - { "dpaddown", "invuse" }, - { "dpadup", "togglemap" }, - { "pad_start", "pause" }, - { "pad_back", "menu_main" }, - { "lthumb", "crouch" }, - { NULL, NULL } -}; - -static const FBinding DefRavenBindings[] = -{ - { "pgup", "+moveup" }, - { "ins", "+movedown" }, - { "home", "land" }, - { "pgdn", "+lookup" }, - { "del", "+lookdown" }, - { "end", "centerview" }, - { NULL, NULL } -}; - -static const FBinding DefHereticBindings[] = -{ - { "backspace", "use ArtiTomeOfPower" }, - { NULL, NULL } -}; - -static const FBinding DefHexenBindings[] = -{ - { "/", "+jump" }, - { "backspace", "invuseall" }, - { "\\", "use ArtiHealth" }, - { "0", "useflechette" }, - { "9", "use ArtiBlastRadius" }, - { "8", "use ArtiTeleport" }, - { "7", "use ArtiTeleportOther" }, - { "6", "use ArtiPork" }, - { "5", "use ArtiInvulnerability2" }, - { "scroll", "+showscores" }, - { NULL, NULL } -}; - -static const FBinding DefStrifeBindings[] = -{ - { "a", "+jump" }, - { "w", "showpop 1" }, - { "backspace", "invdrop" }, - { "z", "showpop 3" }, - { "k", "showpop 2" }, - { "q", "invquery" }, - { NULL, NULL } - // not done - // h - use health -}; - -static const FBinding DefAutomapBindings[] = -{ - { "f", "am_togglefollow" }, - { "g", "am_togglegrid" }, - { "p", "am_toggletexture" }, - { "m", "am_setmark" }, - { "c", "am_clearmarks" }, - { "0", "am_gobig" }, - { "rightarrow", "+am_panright" }, - { "leftarrow", "+am_panleft" }, - { "uparrow", "+am_panup" }, - { "downarrow", "+am_pandown" }, - { "-", "+am_zoomout" }, - { "=", "+am_zoomin" }, - { "kp-", "+am_zoomout" }, - { "kp+", "+am_zoomin" }, - { "mwheelup", "am_zoom 1.2" }, - { "mwheeldown", "am_zoom -1.2" }, - { NULL, NULL } -}; - - - const char *KeyNames[NUM_KEYS] = { // This array is dependant on the particular keyboard input @@ -452,21 +305,6 @@ void FKeyBindings::DoBind (const char *key, const char *bind) // //============================================================================= -void FKeyBindings::SetBinds(const FBinding *binds) -{ - while (binds->Key) - { - DoBind (binds->Key, binds->Bind); - binds++; - } -} - -//============================================================================= -// -// -// -//============================================================================= - void FKeyBindings::UnbindAll () { for (int i = 0; i < NUM_KEYS; ++i) @@ -785,29 +623,37 @@ CCMD (rebind) void C_BindDefaults () { - Bindings.SetBinds (DefBindings); + int lump, lastlump = 0; - if (gameinfo.gametype & (GAME_Raven|GAME_Strife)) + while ((lump = Wads.FindLump("DEFBINDS", &lastlump)) != -1) { - Bindings.SetBinds (DefRavenBindings); - } + FScanner sc(lump); - if (gameinfo.gametype == GAME_Heretic) - { - Bindings.SetBinds (DefHereticBindings); - } + while (sc.GetString()) + { + FKeyBindings *dest = &Bindings; + int key; - if (gameinfo.gametype == GAME_Hexen) - { - Bindings.SetBinds (DefHexenBindings); + // bind destination is optional and is the same as the console command + if (sc.Compare("bind")) + { + sc.MustGetString(); + } + else if (sc.Compare("doublebind")) + { + dest = &DoubleBindings; + sc.MustGetString(); + } + else if (sc.Compare("mapbind")) + { + dest = &AutomapBindings; + sc.MustGetString(); + } + key = GetConfigKeyFromName(sc.String); + sc.MustGetString(); + dest->SetBind(key, sc.String); + } } - - if (gameinfo.gametype == GAME_Strife) - { - Bindings.SetBinds (DefStrifeBindings); - } - - AutomapBindings.SetBinds(DefAutomapBindings); } CCMD(binddefaults) diff --git a/src/c_bind.h b/src/c_bind.h index 4c9edb2bb..394d313c9 100644 --- a/src/c_bind.h +++ b/src/c_bind.h @@ -42,19 +42,12 @@ class FCommandLine; void C_NameKeys (char *str, int first, int second); -struct FBinding -{ - const char *Key; - const char *Bind; -}; - class FKeyBindings { FString Binds[NUM_KEYS]; public: void PerformBind(FCommandLine &argv, const char *msg); - void SetBinds(const FBinding *binds); bool DoKey(event_t *ev); void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL); int GetKeysForCommand (const char *cmd, int *first, int *second); diff --git a/src/d_main.cpp b/src/d_main.cpp index 930b0f629..5dc5c7a78 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2324,6 +2324,8 @@ void D_DoomMain (void) allwads.ShrinkToFit(); SetMapxxFlag(); + GameConfig->DoKeySetup(gameinfo.ConfigName); + // Now that wads are loaded, define mod-specific cvars. ParseCVarInfo(); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index deb870774..6cfd6456b 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -244,9 +244,6 @@ void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, vo void FGameConfigFile::MigrateOldConfig () { - // Set default key bindings. These will be overridden - // by the bindings in the config file if it exists. - C_SetDefaultBindings (); } void FGameConfigFile::DoGlobalSetup () @@ -400,41 +397,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename) ReadCVars (0); } - if (!bMigrating) - { - C_SetDefaultBindings (); - } - - strncpy (subsection, "Bindings", sublen); - if (SetSection (section)) - { - Bindings.UnbindAll(); - while (NextInSection (key, value)) - { - Bindings.DoBind (key, value); - } - } - - strncpy (subsection, "DoubleBindings", sublen); - if (SetSection (section)) - { - DoubleBindings.UnbindAll(); - while (NextInSection (key, value)) - { - DoubleBindings.DoBind (key, value); - } - } - - strncpy (subsection, "AutomapBindings", sublen); - if (SetSection (section)) - { - AutomapBindings.UnbindAll(); - while (NextInSection (key, value)) - { - AutomapBindings.DoBind (key, value); - } - } - strncpy (subsection, "ConsoleAliases", sublen); if (SetSection (section)) { @@ -455,6 +417,38 @@ void FGameConfigFile::DoGameSetup (const char *gamename) OkayToWrite = true; } +// Moved from DoGameSetup so that it can happen after wads are loaded +void FGameConfigFile::DoKeySetup(const char *gamename) +{ + static const struct { const char *label; FKeyBindings *bindings; } binders[] = + { + { "Bindings", &Bindings }, + { "DoubleBindings", &DoubleBindings }, + { "AutomapBindings", &AutomapBindings }, + }; + const char *key, *value; + + sublen = countof(section) - 1 - mysnprintf(section, countof(section), "%s.", gamename); + subsection = section + countof(section) - sublen - 1; + section[countof(section) - 1] = '\0'; + + C_SetDefaultBindings (); + + for (int i = 0; i < countof(binders); ++i) + { + strncpy(subsection, binders[i].label, sublen); + if (SetSection(section)) + { + FKeyBindings *bindings = binders[i].bindings; + bindings->UnbindAll(); + while (NextInSection(key, value)) + { + bindings->DoBind(key, value); + } + } + } +} + // Like DoGameSetup(), but for mod-specific cvars. // Called after CVARINFO has been parsed. void FGameConfigFile::DoModSetup(const char *gamename) diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 74376b583..55867eaf8 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -47,6 +47,7 @@ public: void DoGlobalSetup (); void DoGameSetup (const char *gamename); + void DoKeySetup (const char *gamename); void DoModSetup (const char *gamename); void ArchiveGlobalData (); void ArchiveGameData (const char *gamename); diff --git a/wadsrc/static/defbinds.txt b/wadsrc/static/defbinds.txt new file mode 100644 index 000000000..420d22432 --- /dev/null +++ b/wadsrc/static/defbinds.txt @@ -0,0 +1,103 @@ +/* Default keybindings for all games */ + +` toggleconsole +1 "slot 1" +2 "slot 2" +3 "slot 3" +4 "slot 4" +5 "slot 5" +6 "slot 6" +7 "slot 7" +8 "slot 8" +9 "slot 9" +0 "slot 0" +[ invprev +] invnext +mwheelleft invprev +mwheelright invnext +enter invuse +- sizedown += sizeup +ctrl +attack +alt +strafe +shift +speed +space +use +rightarrow +right +leftarrow +left +uparrow +forward +downarrow +back +, +moveleft +. +moveright +mouse1 +attack +mouse2 +strafe +mouse3 +forward +mouse4 +speed +capslock "toggle cl_run" +f1 menu_help +f2 menu_save +f3 menu_load +f4 menu_options +f5 menu_display +f6 quicksave +f7 menu_endgame +f8 togglemessages +f9 quickload +f11 bumpgamma +f10 menu_quit +tab togglemap +pause pause +sysrq screenshot +t messagemode +\ +showscores +f12 spynext +mwheeldown weapnext +mwheelup weapprev + +// Originally just for Heretic, Hexen, and Strife. +// I can't see why they shouldn't be for Doom or Chex either. +pgup +moveup +ins +movedown +home land +pgdn +lookup +del +lookdown +end centerview + +// Generic joystick buttons +joy1 +attack +joy2 +strafe +joy3 +speed +joy4 +use + +// Xbox 360 / PS2 controllers +pad_a +use +pad_y +jump +rtrigger +attack +ltrigger +altattack +lshoulder weapprev +rshoulder weapnext +dpadleft invprev +dpadright invnext +dpaddown invuse +dpadup togglemap +pad_start pause +pad_back menu_main +lthumb crouch + + +/* Default automap bindings */ +mapbind f am_togglefollow +mapbind g am_togglegrid +mapbind p am_toggletexture +mapbind m am_setmark +mapbind c am_clearmarks +mapbind 0 am_gobig +mapbind rightarrow +am_panright +mapbind leftarrow +am_panleft +mapbind uparrow +am_panup +mapbind downarrow +am_pandown +mapbind - +am_zoomout +mapbind = +am_zoomin +mapbind kp- +am_zoomout +mapbind kp+ +am_zoomin +mapbind mwheelup "am_zoom 1.2" +mapbind mwheeldown "am_zoom -1.2" diff --git a/wadsrc/static/filter/game-heretic/defbinds.txt b/wadsrc/static/filter/game-heretic/defbinds.txt new file mode 100644 index 000000000..ed820a378 --- /dev/null +++ b/wadsrc/static/filter/game-heretic/defbinds.txt @@ -0,0 +1,3 @@ +/* Default keybindings for Heretic */ + +backspace "use ArtiTomeOfPower" \ No newline at end of file diff --git a/wadsrc/static/filter/game-hexen/defbinds.txt b/wadsrc/static/filter/game-hexen/defbinds.txt new file mode 100644 index 000000000..58167f57e --- /dev/null +++ b/wadsrc/static/filter/game-hexen/defbinds.txt @@ -0,0 +1,12 @@ +/* Default keybindings for Hexen */ + +/ +jump +backspace invuseall +\ "use ArtiHealth" +0 useflechette +9 "use ArtiBlastRadius" +8 "use ArtiTeleport" +7 "use ArtiTeleportOther" +6 "use ArtiPork" +5 "use ArtiInvulnerability2" +scroll +showscores \ No newline at end of file diff --git a/wadsrc/static/filter/game-strife/defbinds.txt b/wadsrc/static/filter/game-strife/defbinds.txt new file mode 100644 index 000000000..9370896a0 --- /dev/null +++ b/wadsrc/static/filter/game-strife/defbinds.txt @@ -0,0 +1,11 @@ +/* Default keybindings for Strife */ + +a +jump +w "showpop 1" +backspace invdrop +z "showpop 3" +k "showpop 2" +q invquery + +; not done +; h - use health From b300cfaf62e60aef1b48548c406f46bbb4edaecd Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 5 Apr 2015 21:56:00 -0500 Subject: [PATCH 15/58] Remove old pre-INI config migration code - As if any of this matters now. It's not the 90s anymore. --- src/configfile.cpp | 16 ++-------- src/configfile.h | 5 ++- src/gameconfigfile.cpp | 69 +++++++----------------------------------- src/gameconfigfile.h | 4 --- 4 files changed, 16 insertions(+), 78 deletions(-) diff --git a/src/configfile.cpp b/src/configfile.cpp index 177c019fb..8792175f4 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -66,15 +66,13 @@ FConfigFile::FConfigFile () // //==================================================================== -FConfigFile::FConfigFile (const char *pathname, - void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), - void *userdata) +FConfigFile::FConfigFile (const char *pathname) { Sections = CurrentSection = NULL; LastSectionPtr = &Sections; CurrentEntry = NULL; ChangePathName (pathname); - LoadConfigFile (nosechandler, userdata); + LoadConfigFile (); OkayToWrite = true; FileExisted = true; } @@ -591,7 +589,7 @@ FConfigFile::FConfigEntry *FConfigFile::NewConfigEntry ( // //==================================================================== -void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata) +void FConfigFile::LoadConfigFile () { FILE *file = fopen (PathName, "r"); bool succ; @@ -605,14 +603,6 @@ void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FCo succ = ReadConfig (file); fclose (file); FileExisted = succ; - - if (!succ) - { // First valid line did not define a section - if (nosechandler != NULL) - { - nosechandler (PathName, this, userdata); - } - } } //==================================================================== diff --git a/src/configfile.h b/src/configfile.h index 25c366f01..34ab9d56b 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -41,8 +41,7 @@ class FConfigFile { public: FConfigFile (); - FConfigFile (const char *pathname, - void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata)=0, void *userdata=NULL); + FConfigFile (const char *pathname); FConfigFile (const FConfigFile &other); virtual ~FConfigFile (); @@ -70,7 +69,7 @@ public: const char *GetPathName () const { return PathName.GetChars(); } void ChangePathName (const char *path); - void LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata); + void LoadConfigFile (); bool WriteConfigFile () const; protected: diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 6cfd6456b..7e0ddc6a1 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -83,16 +83,10 @@ FGameConfigFile::FGameConfigFile () FString pathname; OkayToWrite = false; // Do not allow saving of the config before DoGameSetup() - bMigrating = false; bModSetup = false; pathname = GetConfigPath (true); ChangePathName (pathname); - LoadConfigFile (MigrateStub, NULL); - - if (!HaveSections ()) - { // Config file not found; try the old one - MigrateOldConfig (); - } + LoadConfigFile (); // If zdoom.ini was read from the program directory, switch // to the user directory now. If it was read from the user @@ -237,15 +231,6 @@ void FGameConfigFile::WriteCommentHeader (FILE *file) const fprintf (file, "# This file was generated by " GAMENAME " %s on %s\n", GetVersionString(), myasctime()); } -void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, void *userdata) -{ - static_cast(config)->bMigrating = true; -} - -void FGameConfigFile::MigrateOldConfig () -{ -} - void FGameConfigFile::DoGlobalSetup () { if (SetSection ("GlobalSettings.Unknown")) @@ -358,10 +343,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename) const char *key; const char *value; - if (bMigrating) - { - MigrateOldConfig (); - } sublen = countof(section) - 1 - mysnprintf (section, countof(section), "%s.", gamename); subsection = section + countof(section) - sublen - 1; section[countof(section) - 1] = '\0'; @@ -622,41 +603,20 @@ void FGameConfigFile::AddAutoexec (DArgs *list, const char *game) mysnprintf (section, countof(section), "%s.AutoExec", game); - if (bMigrating) + // If .AutoExec section does not exist, create it + // with a default autoexec.cfg file present. + CreateStandardAutoExec(section, false); + // Run any files listed in the .AutoExec section + if (!SectionIsEmpty()) { - FBaseCVar *autoexec = FindCVar ("autoexec", NULL); - - if (autoexec != NULL) + while (NextInSection (key, value)) { - UCVarValue val; - char *path; - - val = autoexec->GetGenericRep (CVAR_String); - path = copystring (val.String); - delete autoexec; - SetSection (section, true); - SetValueForKey ("Path", path); - list->AppendArg (path); - delete[] path; - } - } - else - { - // If .AutoExec section does not exist, create it - // with a default autoexec.cfg file present. - CreateStandardAutoExec(section, false); - // Run any files listed in the .AutoExec section - if (!SectionIsEmpty()) - { - while (NextInSection (key, value)) + if (stricmp (key, "Path") == 0 && *value != '\0') { - if (stricmp (key, "Path") == 0 && *value != '\0') + FString expanded_path = ExpandEnvVars(value); + if (FileExists(expanded_path)) { - FString expanded_path = ExpandEnvVars(value); - if (FileExists(expanded_path)) - { - list->AppendArg (ExpandEnvVars(value)); - } + list->AppendArg (ExpandEnvVars(value)); } } } @@ -667,13 +627,6 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen) { UCVarValue val; - if (bMigrating) - { - con_centernotify.ResetToDefault (); - msg0color.ResetToDefault (); - color.ResetToDefault (); - } - val.Bool = false; wi_percents.SetGenericRepDefault (val, CVAR_Bool); val.Bool = true; diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 55867eaf8..57956f7cd 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -60,13 +60,9 @@ protected: void CreateStandardAutoExec (const char *section, bool start); private: - static void MigrateStub (const char *pathname, FConfigFile *config, void *userdata); - - void MigrateOldConfig (); void SetRavenDefaults (bool isHexen); void ReadCVars (DWORD flags); - bool bMigrating; bool bModSetup; char section[64]; From cac634567bb368d3b19e797175443574ece1dbb4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 10:51:28 +0200 Subject: [PATCH 16/58] - use a proper FString to hold the name of config sections instead of a buffer tacked onto the actual structure. This is necessary if we want to be able to rename a section. --- src/configfile.cpp | 16 ++++++---------- src/configfile.h | 3 ++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/configfile.cpp b/src/configfile.cpp index 8792175f4..9a1f7bd4d 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -138,7 +138,7 @@ FConfigFile &FConfigFile::operator = (const FConfigFile &other) while (fromsection != NULL) { fromentry = fromsection->RootEntry; - tosection = NewConfigSection (fromsection->Name); + tosection = NewConfigSection (fromsection->SectionName); while (fromentry != NULL) { NewConfigEntry (tosection, fromentry->Key, fromentry->Value); @@ -309,7 +309,7 @@ const char *FConfigFile::GetCurrentSection () const { if (CurrentSection != NULL) { - return CurrentSection->Name; + return CurrentSection->SectionName.GetChars(); } return NULL; } @@ -506,7 +506,7 @@ FConfigFile::FConfigSection *FConfigFile::FindSection (const char *name) const { FConfigSection *section = Sections; - while (section != NULL && stricmp (section->Name, name) != 0) + while (section != NULL && section->SectionName.CompareNoCase(name) != 0) { section = section->Next; } @@ -540,19 +540,15 @@ FConfigFile::FConfigEntry *FConfigFile::FindEntry ( FConfigFile::FConfigSection *FConfigFile::NewConfigSection (const char *name) { FConfigSection *section; - char *memblock; section = FindSection (name); if (section == NULL) { - size_t namelen = strlen (name); - memblock = new char[sizeof(*section)+namelen]; - section = ::new(memblock) FConfigSection; + section = new FConfigSection; section->RootEntry = NULL; section->LastEntryPtr = §ion->RootEntry; section->Next = NULL; - memcpy (section->Name, name, namelen); - section->Name[namelen] = 0; + section->SectionName = name; *LastSectionPtr = section; LastSectionPtr = §ion->Next; } @@ -777,7 +773,7 @@ bool FConfigFile::WriteConfigFile () const { fputs (section->Note.GetChars(), file); } - fprintf (file, "[%s]\n", section->Name); + fprintf (file, "[%s]\n", section->SectionName.GetChars()); while (entry != NULL) { if (strpbrk(entry->Value, "\r\n") == NULL) diff --git a/src/configfile.h b/src/configfile.h index 34ab9d56b..31943ccb6 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -93,11 +93,12 @@ private: }; struct FConfigSection { + FString SectionName; FConfigEntry *RootEntry; FConfigEntry **LastEntryPtr; FConfigSection *Next; FString Note; - char Name[1]; // + length of name + //char Name[1]; // + length of name }; FConfigSection *Sections; From 3114a26bc8aa7984b92db3da9ac311cd8e7b0567 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 11:21:28 +0200 Subject: [PATCH 17/58] - allow renaming of config sections and added migration code to rename the old autoload sections to the more flexible naming system that's planned. --- src/configfile.cpp | 16 ++++++++++++++++ src/configfile.h | 1 + src/gameconfigfile.cpp | 20 ++++++++++++++++++++ src/version.h | 2 +- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/configfile.cpp b/src/configfile.cpp index 9a1f7bd4d..e64005fc4 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -513,6 +513,22 @@ FConfigFile::FConfigSection *FConfigFile::FindSection (const char *name) const return section; } +//==================================================================== +// +// FConfigFile :: RenameSection +// +//==================================================================== + +void FConfigFile::RenameSection (const char *oldname, const char *newname) const +{ + FConfigSection *section = FindSection(oldname); + + if (section != NULL) + { + section->SectionName = newname; + } +} + //==================================================================== // // FConfigFile :: FindEntry diff --git a/src/configfile.h b/src/configfile.h index 31943ccb6..e125351dc 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -78,6 +78,7 @@ protected: virtual char *ReadLine (char *string, int n, void *file) const; bool ReadConfig (void *file); static const char *GenerateEndTag(const char *value); + void RenameSection(const char *oldname, const char *newname) const; bool OkayToWrite; bool FileExisted; diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 7e0ddc6a1..9121e79d6 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -334,6 +334,26 @@ void FGameConfigFile::DoGlobalSetup () SetValueForKey ("5", "use ArtiInvulnerability2"); } } + if (last < 211) + { + //RenameSection("Hacx2.Autoload", "hacx.2_0.Autoload"); + //RenameSection("Hacx12.Autoload", "hacx.1_2.Autoload"); + //RenameSection("Hexen1.Autoload", "hexen.hexen.Autoload"); + RenameSection("Chex3.Autoload", "chex.3.Autoload"); + RenameSection("Chex1.Autoload", "chex.1.Autoload"); + RenameSection("HexenDK.Autoload", "hexen.deathkings.Autoload"); + RenameSection("HereticSR.Autoload", "heretic.shadow.Autoload"); + RenameSection("FreeDM.Autoload", "doom.freedoom.freedm.Autoload"); + RenameSection("Freedoom2.Autoload", "doom.freedoom.phase2.Autoload"); + RenameSection("Freedoom1.Autoload", "doom.freedoom.phase1.Autoload"); + RenameSection("DoomBFG.Autoload", "doom.doom1.bfg.Autoload"); + RenameSection("DoomU.Autoload", "doom.doom1.ultimate.Autoload"); + RenameSection("Doom1.Autoload", "doom.doom1.registered.Autoload"); + RenameSection("TNT.Autoload", "doom.doom2.tnt.Autoload"); + RenameSection("Plutonia.Autoload", "doom.doom2.plutonia.Autoload"); + RenameSection("Doom2BFG.Autoload", "doom.doom2.bfg.Autoload"); + RenameSection("Doom2.Autoload", "doom.doom2.commercial.Autoload"); + } } } } diff --git a/src/version.h b/src/version.h index cbbb8bd21..f45f58b2f 100644 --- a/src/version.h +++ b/src/version.h @@ -56,7 +56,7 @@ const char *GetVersionString(); // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to // be able to migrate in FGameConfigFile::DoGlobalSetup(). -#define LASTRUNVERSION "210" +#define LASTRUNVERSION "211" // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. From 3241b1d3db2d9ce75f303bbf15af3eb3cb79b12b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 11:31:08 +0200 Subject: [PATCH 18/58] - add new config section names to iwadinfo.txt --- wadsrc/static/iwadinfo.txt | 53 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 0fcdd9b87..ceceafd2b 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -3,6 +3,7 @@ IWad { Name = "The Adventures of Square" + Autoname = "square.square" Game = "Doom" Config = "Square" MustContain = "SQU-IWAD", "E1A1" @@ -12,6 +13,7 @@ IWad IWad { Name = "The Adventures of Square (Square-ware)" + Autoname = "square.squareware" Game = "Doom" Config = "Square" MustContain = "SQU-SWE1", "E1A1" @@ -21,6 +23,7 @@ IWad IWad { Name = "Harmony" + Autoname = "harmony" Game = "Doom" Config = "Harmony" Mapinfo = "mapinfo/hacxharm.txt" @@ -33,7 +36,7 @@ IWad Name = "Hacx 2.0" Game = "Doom" Config = "Hacx" - Autoname = "Hacx2" + Autoname = "hacx.2_0" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-E" BannerColors = "ff ff ff", "00 88 22" @@ -44,7 +47,7 @@ IWad Name = "Hacx: Twitch'n Kill" Game = "Doom" Config = "Hacx" - Autoname = "Hacx12" + Autoname = "hacx.1_2" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-R" BannerColors = "00 00 a8", "a8 a8 a8" @@ -53,6 +56,7 @@ IWad IWad { Name = "Action Doom 2: Urban Brawl" + Autoname = "urbanbrawl" Game = "Doom" Config = "UrbanBrawl" Mapinfo = "mapinfo/urbanbrawl.txt" @@ -63,7 +67,7 @@ IWad IWad { Name = "Chex(R) Quest 3" - Autoname = "Chex3" + Autoname = "chex.3" Game = "Chex" Config = "Chex" Mapinfo = "mapinfo/chex.txt" @@ -75,7 +79,7 @@ IWad IWad { Name = "Chex(R) Quest" - Autoname = "Chex1" + Autoname = "chex.1" Game = "Chex" Config = "Chex" Mapinfo = "mapinfo/chex.txt" @@ -86,6 +90,7 @@ IWad IWad { Name = "Strife: Quest for the Sigil" + Autoname = "strife" Game = "Strife" Config = "Strife" Mapinfo = "mapinfo/strife.txt" @@ -99,7 +104,7 @@ IWad Name = "Strife: Teaser (New Version)" Game = "Strife" Config = "Strife" - Autoname = "Strifeteaser2" + Autoname = "strifeteaser2" Mapinfo = "mapinfo/strife.txt" Compatibility = "Shareware", "Teaser2" MustContain = "MAP33", "ENDSTRF", "INVCURS" @@ -111,7 +116,7 @@ IWad Name = "Strife: Teaser (Old Version)" Game = "Strife" Config = "Strife" - Autoname = "Strifeteaser1" + Autoname = "strifeteaser1" Mapinfo = "mapinfo/strife.txt" Compatibility = "Shareware" MustContain = "MAP33", "ENDSTRF" @@ -123,7 +128,7 @@ IWad Name = "Hexen: Beyond Heretic" Game = "Hexen" Config = "Hexen" - Autoname = "Hexen1" + Autoname = "hexen.hexen" Mapinfo = "mapinfo/hexen.txt" Compatibility = "Poly1" MustContain = "TITLE", "MAP01", "MAP40", "WINNOWR" @@ -133,7 +138,7 @@ IWad IWad { Name = "Hexen: Deathkings of the Dark Citadel" - Autoname = "HexenDK" + Autoname = "hexen.deathkings" Game = "Hexen" Config = "Hexen" Mapinfo = "mapinfo/hexen.txt" @@ -157,7 +162,7 @@ IWad IWad { Name = "Blasphemer" - Autoname = "Blasphemer" + Autoname = "blasphemer" Game = "Heretic" Config = "Heretic" Mapinfo = "mapinfo/heretic.txt" @@ -168,7 +173,7 @@ IWad IWad { Name = "Heretic: Shadow of the Serpent Riders" - Autoname = "HereticSR" + Autoname = "heretic.shadow" Game = "Heretic" Config = "Heretic" Mapinfo = "mapinfo/heretic.txt" @@ -182,7 +187,7 @@ IWad Name = "Heretic" Game = "Heretic" Config = "Heretic" - Autoname = "Heretic1" + Autoname = "heretic.heretic" Mapinfo = "mapinfo/heretic.txt" MustContain = "E1M1", "E2M1", "TITLE", "MUS_E1M1" BannerColors = "fc fc 00", "a8 00 00" @@ -202,8 +207,7 @@ IWad IWad { Name = "FreeDM" - Autoname = "FreeDM" - Group = "Freedoom" + Autoname = "doom.freedoom.freedm" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom2.txt" @@ -214,8 +218,7 @@ IWad IWad { Name = "Freedoom: Phase 2" - Autoname = "Freedoom2" - Group = "Freedoom" + Autoname = "doom.freedoom.phase2" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom2.txt" @@ -226,8 +229,7 @@ IWad IWad { Name = "Freedoom: Phase 1" - Autoname = "Freedoom1" - Group = "Freedoom" + Autoname = "doom.freedoom.phase1" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom1.txt" @@ -238,8 +240,7 @@ IWad IWad { Name = "Freedoom: Demo Version" - Autoname = "Freedoom1" - Group = "Freedoom" + Autoname = "doom.freedoom.demo" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom1.txt" @@ -250,7 +251,7 @@ IWad IWad { Name = "DOOM: BFG Edition" - Autoname = "DoomBFG" + Autoname = "doom.doom1.bfg" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/ultdoom.txt" @@ -265,7 +266,7 @@ IWad IWad { Name = "The Ultimate DOOM" - Autoname = "DoomU" + Autoname = "doom.doom1.ultimate" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/ultdoom.txt" @@ -279,7 +280,7 @@ IWad IWad { Name = "DOOM Registered" - Autoname = "Doom1" + Autoname = "doom.doom1.registered" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom1.txt" @@ -304,7 +305,7 @@ IWad IWad { Name = "Final Doom: TNT - Evilution" - Autoname = "TNT" + Autoname = "doom.doom2.tnt" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/tnt.txt" @@ -316,7 +317,7 @@ IWad IWad { Name = "Final Doom: Plutonia Experiment" - Autoname = "Plutonia" + Autoname = "doom.doom2.plutonia" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/plutonia.txt" @@ -328,7 +329,7 @@ IWad IWad { Name = "DOOM 2: BFG Edition" - Autoname = "Doom2BFG" + Autoname = "doom.doom2.bfg" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom2bfg.txt" @@ -342,7 +343,7 @@ IWad IWad { Name = "DOOM 2: Hell on Earth" - Autoname = "Doom2" + Autoname = "doom.doom2.commercial" Game = "Doom" Config = "Doom" Mapinfo = "mapinfo/doom2.txt" From 258822ef3bab753113eec96c6196f0fd2dc69a7b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 11:57:12 +0200 Subject: [PATCH 19/58] - redid autoload handler and resource file filtering to use the newly defined method with multi-part names. As a result the old 'Group' property could be removed and all other means to get a section name were disabled. As an example, if the code gets 'doom.doom2.commercial' it will use the following sections in this order: global.autoload doom.autoload doom.doom2.autoload doom.doom2.commercial.autoload. --- src/d_iwad.cpp | 6 ------ src/d_main.cpp | 28 ++++++++-------------------- src/d_main.h | 1 - src/doomstat.cpp | 2 +- src/doomstat.h | 2 +- src/gameconfigfile.cpp | 5 ++--- src/resourcefiles/resourcefile.cpp | 13 ++++++++++--- 7 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 4a46a93cd..e09baa26d 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -138,12 +138,6 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) sc.MustGetString(); iwad->Autoname = sc.String; } - else if (sc.Compare("Group")) - { - sc.MustGetStringName("="); - sc.MustGetString(); - iwad->Group = sc.String; - } else if (sc.Compare("Config")) { sc.MustGetStringName("="); diff --git a/src/d_main.cpp b/src/d_main.cpp index 5dc5c7a78..78d12e651 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1990,10 +1990,9 @@ static void D_DoomInit() // //========================================================================== -static void AddAutoloadFiles(const char *group, const char *autoname) +static void AddAutoloadFiles(const char *autoname) { - LumpFilterGroup = group; - LumpFilterIWAD = autoname; + LumpFilterIWAD.Format("%s.", autoname); // The '.' is appened to simplify parsing the string if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload")) { @@ -2025,25 +2024,14 @@ static void AddAutoloadFiles(const char *group, const char *autoname) // Add common (global) wads D_AddConfigWads (allwads, "Global.Autoload"); - // Add game-specific wads - file = gameinfo.ConfigName; - file += ".Autoload"; - D_AddConfigWads (allwads, file); + long len; + int lastpos = -1; - // Add group-specific wads - if (group != NULL && group[0] != 0) - { - file = group; - file += ".Autoload"; - D_AddConfigWads(allwads, file); - } - - // Add IWAD-specific wads - if (autoname != NULL && autoname[0] != 0) + while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0) { - file = autoname; - file += ".Autoload"; + file = LumpFilterIWAD.Left(len) + ".Autoload"; D_AddConfigWads(allwads, file); + lastpos = len; } } } @@ -2294,7 +2282,7 @@ void D_DoomMain (void) FBaseCVar::DisableCallbacks(); GameConfig->DoGameSetup (gameinfo.ConfigName); - AddAutoloadFiles(iwad_info->Group, iwad_info->Autoname); + AddAutoloadFiles(iwad_info->Autoname); // Run automatically executed files execFiles = new DArgs; diff --git a/src/d_main.h b/src/d_main.h index dd2ffc409..e4641c41d 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -75,7 +75,6 @@ struct FIWADInfo { FString Name; // Title banner text for this IWAD FString Autoname; // Name of autoload ini section for this IWAD - FString Group; // Groupname for this IWAD FString Configname; // Name of config section for this IWAD FString Required; // Requires another IWAD DWORD FgColor; // Foreground color for title banner diff --git a/src/doomstat.cpp b/src/doomstat.cpp index 697ef3afe..2ec72db9d 100644 --- a/src/doomstat.cpp +++ b/src/doomstat.cpp @@ -69,4 +69,4 @@ int SinglePlayerClass[MAXPLAYERS]; bool ToggleFullscreen; int BorderTopRefresh; -FString LumpFilterGroup, LumpFilterIWAD; +FString LumpFilterIWAD; diff --git a/src/doomstat.h b/src/doomstat.h index d7f3796ac..835ef73fb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -251,6 +251,6 @@ EXTERN_CVAR (Int, compatflags2); extern int i_compatflags, i_compatflags2, ii_compatflags, ii_compatflags2, ib_compatflags; // Filters from AddAutoloadFiles(). Used to filter files from archives. -extern FString LumpFilterGroup, LumpFilterIWAD; +extern FString LumpFilterIWAD; #endif diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 9121e79d6..e17a3e127 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -163,6 +163,7 @@ FGameConfigFile::FGameConfigFile () // Create auto-load sections, so users know what's available. // Note that this totem pole is the reverse of the order that // they will appear in the file. +#if 0 CreateSectionAtStart("Harmony.Autoload"); CreateSectionAtStart("UrbanBrawl.Autoload"); CreateSectionAtStart("Chex3.Autoload"); @@ -185,6 +186,7 @@ FGameConfigFile::FGameConfigFile () CreateSectionAtStart("DoomU.Autoload"); CreateSectionAtStart("Doom1.Autoload"); CreateSectionAtStart("Doom.Autoload"); +#endif CreateSectionAtStart("Global.Autoload"); // The same goes for auto-exec files. @@ -336,9 +338,6 @@ void FGameConfigFile::DoGlobalSetup () } if (last < 211) { - //RenameSection("Hacx2.Autoload", "hacx.2_0.Autoload"); - //RenameSection("Hacx12.Autoload", "hacx.1_2.Autoload"); - //RenameSection("Hexen1.Autoload", "hexen.hexen.Autoload"); RenameSection("Chex3.Autoload", "chex.3.Autoload"); RenameSection("Chex1.Autoload", "chex.1.Autoload"); RenameSection("HexenDK.Autoload", "hexen.deathkings.Autoload"); diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index d5ad659af..e5c12b0ef 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -345,9 +345,16 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize) // each one so that we don't risk refiltering already filtered lumps. DWORD max = NumLumps; max -= FilterLumpsByGameType(gameinfo.gametype, lumps, lumpsize, max); - max -= FilterLumps(gameinfo.ConfigName, lumps, lumpsize, max); - max -= FilterLumps(LumpFilterGroup, lumps, lumpsize, max); - max -= FilterLumps(LumpFilterIWAD, lumps, lumpsize, max); + + long len; + int lastpos = -1; + FString file; + + while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0) + { + max -= FilterLumps(LumpFilterIWAD.Left(len), lumps, lumpsize, max); + lastpos = len; + } JunkLeftoverFilters(lumps, lumpsize, max); } From dfda74ffe3496997caef6732fd302bb52eb683ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 13:52:08 +0200 Subject: [PATCH 20/58] - automatically create autoload section based on IWADINFO. This has an important implication: Previously the config was loaded before IWADINFO so in order to allow the config to access the data this had to be switched around. This means that zdoom.pk3 will not be looked for in the global IWAD search paths anymore, but since it shouldn't be there to begin with it should be an acceptable compromise. --- src/d_iwad.cpp | 1 - src/d_main.cpp | 24 +++++++++++------ src/d_main.h | 16 +++++++++--- src/gameconfigfile.cpp | 58 ++++++++++++++++++++++++------------------ src/gameconfigfile.h | 3 ++- src/m_misc.cpp | 4 +-- src/m_misc.h | 3 ++- 7 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index e09baa26d..7574347bc 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -387,7 +387,6 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, bool iwadparmfound = false; FString custwad; - ParseIWadInfos(zdoom_wad); wads.Resize(mIWadNames.Size()); foundwads.Resize(mIWads.Size()); memset(&foundwads[0], 0, foundwads.Size() * sizeof(foundwads[0])); diff --git a/src/d_main.cpp b/src/d_main.cpp index 78d12e651..5f4f09d4d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1978,10 +1978,6 @@ static void D_DoomInit() } FRandom::StaticClearRandom (); - - Printf ("M_LoadDefaults: Load system defaults.\n"); - M_LoadDefaults (); // load before initing other systems - } //========================================================================== @@ -2203,7 +2199,8 @@ void D_DoomMain (void) DArgs *execFiles; TArray pwads; FString *args; - int argcount; + int argcount; + FIWadManager *iwad_man; // +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"); @@ -2233,8 +2230,6 @@ void D_DoomMain (void) } D_DoomInit(); - PClass::StaticInit (); - atterm(FinalGC); // [RH] Make sure zdoom.pk3 is always loaded, // as it contains magic stuff we need. @@ -2246,6 +2241,14 @@ void D_DoomMain (void) } FString basewad = wad; + iwad_man = new FIWadManager; + iwad_man->ParseIWadInfos(basewad); + + Printf ("M_LoadDefaults: Load system defaults.\n"); + M_LoadDefaults (iwad_man); // load before initing other systems + + PClass::StaticInit (); + atterm(FinalGC); // reinit from here @@ -2267,7 +2270,11 @@ void D_DoomMain (void) // restart is initiated without a defined IWAD assume for now that it's not going to change. if (iwad.IsEmpty()) iwad = lastIWAD; - FIWadManager *iwad_man = new FIWadManager; + if (iwad_man == NULL) + { + iwad_man = new FIWadManager; + iwad_man->ParseIWadInfos(basewad); + } const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad); gameinfo.gametype = iwad_info->gametype; gameinfo.flags = iwad_info->flags; @@ -2486,6 +2493,7 @@ void D_DoomMain (void) FBaseCVar::EnableNoSet (); delete iwad_man; // now we won't need this anymore + iwad_man = NULL; // [RH] Run any saved commands from the command line or autoexec.cfg now. gamestate = GS_FULLCONSOLE; diff --git a/src/d_main.h b/src/d_main.h index e4641c41d..afca8bc3b 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -115,15 +115,13 @@ extern FStartupInfo DoomStartupInfo; // //========================================================================== -struct FIWadManager +class FIWadManager { -private: TArray mIWads; TArray mIWadNames; TArray mLumpsFound; void ParseIWadInfo(const char *fn, const char *data, int datasize); - void ParseIWadInfos(const char *fn); void ClearChecks(); void CheckLumpName(const char *name); int GetIWadInfo(); @@ -131,7 +129,19 @@ private: int CheckIWAD (const char *doomwaddir, WadStuff *wads); int IdentifyVersion (TArray &wadfiles, const char *iwad, const char *zdoom_wad); public: + void ParseIWadInfos(const char *fn); const FIWADInfo *FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad); + const FString *GetAutoname(unsigned int num) const + { + if (num < mIWads.Size()) return &mIWads[num].Autoname; + else return NULL; + } + int GetIWadFlags(unsigned int num) const + { + if (num < mIWads.Size()) return mIWads[num].flags; + else return false; + } + }; diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index e17a3e127..112bcbe1b 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -61,6 +61,7 @@ extern HWND Window; #include "doomstat.h" #include "i_system.h" #include "gi.h" +#include "d_main.h" EXTERN_CVAR (Bool, con_centernotify) EXTERN_CVAR (Int, msg0color) @@ -75,7 +76,7 @@ EXTERN_CVAR (Color, am_cdwallcolor) EXTERN_CVAR (Float, spc_amp) EXTERN_CVAR (Bool, wi_percents) -FGameConfigFile::FGameConfigFile () +FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man) { #ifdef __APPLE__ FString user_docs, user_app_support, local_app_support; @@ -163,30 +164,36 @@ FGameConfigFile::FGameConfigFile () // Create auto-load sections, so users know what's available. // Note that this totem pole is the reverse of the order that // they will appear in the file. -#if 0 - CreateSectionAtStart("Harmony.Autoload"); - CreateSectionAtStart("UrbanBrawl.Autoload"); - CreateSectionAtStart("Chex3.Autoload"); - CreateSectionAtStart("Chex1.Autoload"); - CreateSectionAtStart("Chex.Autoload"); - CreateSectionAtStart("Strife.Autoload"); - CreateSectionAtStart("HexenDK.Autoload"); - CreateSectionAtStart("Hexen.Autoload"); - CreateSectionAtStart("HereticSR.Autoload"); - CreateSectionAtStart("Heretic.Autoload"); - CreateSectionAtStart("FreeDM.Autoload"); - CreateSectionAtStart("Freedoom2.Autoload"); - CreateSectionAtStart("Freedoom1.Autoload"); - CreateSectionAtStart("Freedoom.Autoload"); - CreateSectionAtStart("Plutonia.Autoload"); - CreateSectionAtStart("TNT.Autoload"); - CreateSectionAtStart("Doom2BFG.Autoload"); - CreateSectionAtStart("Doom2.Autoload"); - CreateSectionAtStart("DoomBFG.Autoload"); - CreateSectionAtStart("DoomU.Autoload"); - CreateSectionAtStart("Doom1.Autoload"); - CreateSectionAtStart("Doom.Autoload"); -#endif + + double last = 0; + if (SetSection ("LastRun")) + { + const char *lastver = GetValueForKey ("Version"); + if (lastver != NULL) last = atof(lastver); + } + + // don't create the autoload section if we are about to migrate an old config because it'd mess up the upcoming migration step. + // This will be taken care of once the game runs again with the migrated config file. + if (last >= 211) + { + const FString *pAuto; + for (int num = 0; (pAuto = iwad_man->GetAutoname(num)) != NULL; num++) + { + if (!(iwad_man->GetIWadFlags(num) & GI_SHAREWARE)) // we do not want autoload sections for shareware IWADs (which may have an autoname for resource filtering) + { + FString workname = *pAuto; + + while (workname.IsNotEmpty()) + { + FString section = workname + ".Autoload"; + CreateSectionAtStart(section.GetChars()); + long dotpos = workname.LastIndexOf('.'); + if (dotpos < 0) break; + workname.Truncate(dotpos); + } + } + } + } CreateSectionAtStart("Global.Autoload"); // The same goes for auto-exec files. @@ -345,6 +352,7 @@ void FGameConfigFile::DoGlobalSetup () RenameSection("FreeDM.Autoload", "doom.freedoom.freedm.Autoload"); RenameSection("Freedoom2.Autoload", "doom.freedoom.phase2.Autoload"); RenameSection("Freedoom1.Autoload", "doom.freedoom.phase1.Autoload"); + RenameSection("Freedoom.Autoload", "doom.freedoom.Autoload"); RenameSection("DoomBFG.Autoload", "doom.doom1.bfg.Autoload"); RenameSection("DoomU.Autoload", "doom.doom1.ultimate.Autoload"); RenameSection("Doom1.Autoload", "doom.doom1.registered.Autoload"); diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 57956f7cd..5862bb79e 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -38,11 +38,12 @@ #include "configfile.h" class DArgs; +class FIWadManager; class FGameConfigFile : public FConfigFile { public: - FGameConfigFile (); + FGameConfigFile (FIWadManager *iwad_man); ~FGameConfigFile (); void DoGlobalSetup (); diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 7f4fa482d..1369bdb52 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -410,9 +410,9 @@ CCMD (writeini) // M_LoadDefaults // -void M_LoadDefaults () +void M_LoadDefaults (FIWadManager *iwad_man) { - GameConfig = new FGameConfigFile; + GameConfig = new FGameConfigFile(iwad_man); GameConfig->DoGlobalSetup (); atterm (M_SaveDefaultsFinal); } diff --git a/src/m_misc.h b/src/m_misc.h index 9599306de..ea146c690 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -28,6 +28,7 @@ class FConfigFile; class FGameConfigFile; +class FIWadManager; extern FGameConfigFile *GameConfig; @@ -40,7 +41,7 @@ void M_FindResponseFile (void); // Pass a NULL to get the original behavior. void M_ScreenShot (const char *filename); -void M_LoadDefaults (); +void M_LoadDefaults (FIWadManager *iwad_man); bool M_SaveDefaults (const char *filename); void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen); From a013703e1ce8a41dafb148c02b2ee3d3b20673b2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 16:44:03 +0200 Subject: [PATCH 21/58] - add a NULL pointer check for the config to BaseFileSearch. --- src/d_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 5f4f09d4d..1244cc88f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1657,7 +1657,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf return wad; } - if (GameConfig->SetSection ("FileSearch.Directories")) + if (GameConfig != NULL && GameConfig->SetSection ("FileSearch.Directories")) { const char *key; const char *value; From 7d2ab461d9820c5f42d1d9ddaad564bcab1789c6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 20:59:43 +0200 Subject: [PATCH 22/58] - don't use 'countof' to iterate through a static array that's defined inside a function. Some GCC versions apparently do not like that. --- src/gameconfigfile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 112bcbe1b..a168579a0 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -433,6 +433,7 @@ void FGameConfigFile::DoKeySetup(const char *gamename) { "Bindings", &Bindings }, { "DoubleBindings", &DoubleBindings }, { "AutomapBindings", &AutomapBindings }, + NULL, NULL }; const char *key, *value; @@ -442,7 +443,7 @@ void FGameConfigFile::DoKeySetup(const char *gamename) C_SetDefaultBindings (); - for (int i = 0; i < countof(binders); ++i) + for (int i = 0; binders[i].label != NULL; ++i) { strncpy(subsection, binders[i].label, sublen); if (SetSection(section)) From 4971e7def1462461579ae30750c679365536e564 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 21:40:14 +0200 Subject: [PATCH 23/58] - another GCC countof fix... --- src/resourcefiles/resourcefile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index e5c12b0ef..11d60795e 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -430,13 +430,14 @@ int FResourceFile::FilterLumpsByGameType(int type, void *lumps, size_t lumpsize, { GAME_Raven, "game-Raven" }, { GAME_DoomStrifeChex, "game-DoomStrifeChex" }, { GAME_DoomChex, "game-DoomChex" }, + { GAME_Any, NULL } }; if (type == 0) { return 0; } int count = 0; - for (int i = 0; i < countof(blanket); ++i) + for (int i = 0; blanket[i].name != NULL; ++i) { if (type & blanket[i].match) { From 2cc6e74b31b503232bc95b427e9454e05c7dcb4c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 21:43:55 +0200 Subject: [PATCH 24/58] - renamed Hacx's autoload sections to remove minor version numbers. --- wadsrc/static/iwadinfo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index ceceafd2b..a92bc554d 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -36,7 +36,7 @@ IWad Name = "Hacx 2.0" Game = "Doom" Config = "Hacx" - Autoname = "hacx.2_0" + Autoname = "hacx.2" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-E" BannerColors = "ff ff ff", "00 88 22" @@ -47,7 +47,7 @@ IWad Name = "Hacx: Twitch'n Kill" Game = "Doom" Config = "Hacx" - Autoname = "hacx.1_2" + Autoname = "hacx.1" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-R" BannerColors = "00 00 a8", "a8 a8 a8" From c584e9ec9525799af10cd81fbb35e03f565f290b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 6 Apr 2015 23:23:50 +0200 Subject: [PATCH 25/58] - fixed destructor call of FConfigSection in FConfigFile. --- src/configfile.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/configfile.cpp b/src/configfile.cpp index e64005fc4..b8db74eb3 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -116,8 +116,7 @@ FConfigFile::~FConfigFile () delete[] (char *)entry; entry = nextentry; } - section->~FConfigSection(); - delete[] (char *)section; + delete section; section = nextsection; } } From cf7c04b6053800e86f187f72367269c9fec34625 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 08:41:45 +0200 Subject: [PATCH 26/58] - more autoload name changing: hacx.1/2 -> hacx.hacx1/2 and chex.1/3 -> chex.chex1/3 --- wadsrc/static/iwadinfo.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index a92bc554d..a274a1f2f 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -36,7 +36,7 @@ IWad Name = "Hacx 2.0" Game = "Doom" Config = "Hacx" - Autoname = "hacx.2" + Autoname = "hacx.hacx2" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-E" BannerColors = "ff ff ff", "00 88 22" @@ -47,7 +47,7 @@ IWad Name = "Hacx: Twitch'n Kill" Game = "Doom" Config = "Hacx" - Autoname = "hacx.1" + Autoname = "hacx.hacx1" Mapinfo = "mapinfo/hacxharm.txt" MustContain = "MAP01", "HACX-R" BannerColors = "00 00 a8", "a8 a8 a8" @@ -67,7 +67,7 @@ IWad IWad { Name = "Chex(R) Quest 3" - Autoname = "chex.3" + Autoname = "chex.chex3" Game = "Chex" Config = "Chex" Mapinfo = "mapinfo/chex.txt" @@ -79,7 +79,7 @@ IWad IWad { Name = "Chex(R) Quest" - Autoname = "chex.1" + Autoname = "chex.chex1" Game = "Chex" Config = "Chex" Mapinfo = "mapinfo/chex.txt" From e75bdf86dbc419434f9cf833245a75a06a4ec831 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 08:46:42 +0200 Subject: [PATCH 27/58] - move section renaming code into FGameConfigFile's constructor so renaming of the old and creation of the new autoload sections can be done in one step, not two. --- src/gameconfigfile.cpp | 63 +++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index a168579a0..3f83da408 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -172,25 +172,38 @@ FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man) if (lastver != NULL) last = atof(lastver); } - // don't create the autoload section if we are about to migrate an old config because it'd mess up the upcoming migration step. - // This will be taken care of once the game runs again with the migrated config file. - if (last >= 211) + if (last < 211) { - const FString *pAuto; - for (int num = 0; (pAuto = iwad_man->GetAutoname(num)) != NULL; num++) + RenameSection("Chex3.Autoload", "chex.chex3.Autoload"); + RenameSection("Chex1.Autoload", "chex.chex1.Autoload"); + RenameSection("HexenDK.Autoload", "hexen.deathkings.Autoload"); + RenameSection("HereticSR.Autoload", "heretic.shadow.Autoload"); + RenameSection("FreeDM.Autoload", "doom.freedoom.freedm.Autoload"); + RenameSection("Freedoom2.Autoload", "doom.freedoom.phase2.Autoload"); + RenameSection("Freedoom1.Autoload", "doom.freedoom.phase1.Autoload"); + RenameSection("Freedoom.Autoload", "doom.freedoom.Autoload"); + RenameSection("DoomBFG.Autoload", "doom.doom1.bfg.Autoload"); + RenameSection("DoomU.Autoload", "doom.doom1.ultimate.Autoload"); + RenameSection("Doom1.Autoload", "doom.doom1.registered.Autoload"); + RenameSection("TNT.Autoload", "doom.doom2.tnt.Autoload"); + RenameSection("Plutonia.Autoload", "doom.doom2.plutonia.Autoload"); + RenameSection("Doom2BFG.Autoload", "doom.doom2.bfg.Autoload"); + RenameSection("Doom2.Autoload", "doom.doom2.commercial.Autoload"); + } + const FString *pAuto; + for (int num = 0; (pAuto = iwad_man->GetAutoname(num)) != NULL; num++) + { + if (!(iwad_man->GetIWadFlags(num) & GI_SHAREWARE)) // we do not want autoload sections for shareware IWADs (which may have an autoname for resource filtering) { - if (!(iwad_man->GetIWadFlags(num) & GI_SHAREWARE)) // we do not want autoload sections for shareware IWADs (which may have an autoname for resource filtering) - { - FString workname = *pAuto; + FString workname = *pAuto; - while (workname.IsNotEmpty()) - { - FString section = workname + ".Autoload"; - CreateSectionAtStart(section.GetChars()); - long dotpos = workname.LastIndexOf('.'); - if (dotpos < 0) break; - workname.Truncate(dotpos); - } + while (workname.IsNotEmpty()) + { + FString section = workname + ".Autoload"; + CreateSectionAtStart(section.GetChars()); + long dotpos = workname.LastIndexOf('.'); + if (dotpos < 0) break; + workname.Truncate(dotpos); } } } @@ -343,24 +356,6 @@ void FGameConfigFile::DoGlobalSetup () SetValueForKey ("5", "use ArtiInvulnerability2"); } } - if (last < 211) - { - RenameSection("Chex3.Autoload", "chex.3.Autoload"); - RenameSection("Chex1.Autoload", "chex.1.Autoload"); - RenameSection("HexenDK.Autoload", "hexen.deathkings.Autoload"); - RenameSection("HereticSR.Autoload", "heretic.shadow.Autoload"); - RenameSection("FreeDM.Autoload", "doom.freedoom.freedm.Autoload"); - RenameSection("Freedoom2.Autoload", "doom.freedoom.phase2.Autoload"); - RenameSection("Freedoom1.Autoload", "doom.freedoom.phase1.Autoload"); - RenameSection("Freedoom.Autoload", "doom.freedoom.Autoload"); - RenameSection("DoomBFG.Autoload", "doom.doom1.bfg.Autoload"); - RenameSection("DoomU.Autoload", "doom.doom1.ultimate.Autoload"); - RenameSection("Doom1.Autoload", "doom.doom1.registered.Autoload"); - RenameSection("TNT.Autoload", "doom.doom2.tnt.Autoload"); - RenameSection("Plutonia.Autoload", "doom.doom2.plutonia.Autoload"); - RenameSection("Doom2BFG.Autoload", "doom.doom2.bfg.Autoload"); - RenameSection("Doom2.Autoload", "doom.doom2.commercial.Autoload"); - } } } } From 6f5dbdefb05587dbe07e9b044f5af9b5ec93d221 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 08:51:21 +0200 Subject: [PATCH 28/58] - fixed: args of non-actor mapthings were ignored. --- 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 76afec801..e3317e1a2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4617,7 +4617,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } // copy args to mapthing so that we have them in one place for the rest of this function - if (mentry->Special >= 0) + if (mentry->Type != NULL && mentry->Special >= 0) { mthing->special = mentry->Special; memcpy(mthing->args, mentry->Args, sizeof(mthing->args)); From dd91141b357d10adc35e9a1959c15ee1dc197d67 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 09:11:46 +0200 Subject: [PATCH 29/58] - updated the blurb that's being put above the IWAD specific autoload sections. --- src/gameconfigfile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 3f83da408..c4f970db9 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -239,9 +239,10 @@ FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man) "# Wad files to automatically load depending on the game and IWAD you are\n" "# playing. You may have have files that are loaded for all similar IWADs\n" "# (the game) and files that are only loaded for particular IWADs. For example,\n" - "# any files listed under Doom.Autoload will be loaded for any version of Doom,\n" - "# but files listed under Doom2.Autoload will only load when you are\n" - "# playing Doom 2.\n\n"); + "# any files listed under 'doom.Autoload' will be loaded for any version of Doom,\n" + "# but files listed under 'doom.doom2.Autoload' will only load when you are\n" + "# playing a Doom 2 based game (doom2.wad, tnt.wad or plutonia.wad), and files listed under\n" + "# 'doom.doom2.commercial.Autoload' only when playing doom2.wad.\n\n"); } FGameConfigFile::~FGameConfigFile () From 268e7df992f8cb15029e21bfa67094b550e08de2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 14:09:55 +0200 Subject: [PATCH 30/58] - fixed: We must not allow the engine to start without a default MAPINFO definition. Both 'Adventures of Square' IWADs were missing an entry for base MAPINFO and as a result did not define the common editor numbers. To prevent this, a new mindefaults MAPINFO was added to zdoom.pk3 which now gets loaded if IWADINFO does not specify a game-specific file. This minimum setting sets all gamedefaults to a reasonable base value and defines all other things that are required to be defined. --- src/d_iwad.cpp | 5 +++ wadsrc/static/iwadinfo.txt | 2 + wadsrc/static/mapinfo/mindefaults.txt | 59 +++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 wadsrc/static/mapinfo/mindefaults.txt diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 7574347bc..3fc365e8c 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -219,6 +219,11 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize) sc.ScriptError("Unknown keyword '%s'", sc.String); } } + if (iwad->MapInfo.IsEmpty()) + { + // We must at least load the minimum defaults to allow the engine to run. + iwad->MapInfo = "mapinfo/mindefaults.txt"; + } } else if (sc.Compare("NAMES")) { diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index a274a1f2f..6c958ddfa 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -6,6 +6,7 @@ IWad Autoname = "square.square" Game = "Doom" Config = "Square" + Mapinfo = "mapinfo/mindefaults.txt" MustContain = "SQU-IWAD", "E1A1" BannerColors = "ff ff ff", "80 00 80" } @@ -16,6 +17,7 @@ IWad Autoname = "square.squareware" Game = "Doom" Config = "Square" + Mapinfo = "mapinfo/mindefaults.txt" MustContain = "SQU-SWE1", "E1A1" BannerColors = "ff ff ff", "80 00 80" } diff --git a/wadsrc/static/mapinfo/mindefaults.txt b/wadsrc/static/mapinfo/mindefaults.txt new file mode 100644 index 000000000..cbb3fa06b --- /dev/null +++ b/wadsrc/static/mapinfo/mindefaults.txt @@ -0,0 +1,59 @@ +// defines the minimum needed entries to let an unknown IWAD run + +gameinfo +{ + titlepage = "-NOFLAT-" + titletime = 999 + infopage = "-NOFLAT-" + titlemusic = "" + advisorytime = 0 + chatsound = "" + finalemusic = "" + finaleflat = "-NOFLAT-" + finalepage = "-NOFLAT-" + quitsound = "" + borderflat = "-NOFLAT-" + border = DoomBorder + telefogheight = 0 + defkickback = 100 + skyflatname = "F_SKY1" + translator = "xlat/doom.txt" + defaultbloodcolor = "68 00 00" + defaultbloodparticlecolor = "ff 00 00" + backpacktype = "Backpack" + armoricons = "AICNA0", 0.75, "AICNC0" + statusbar = "sbarinfo/doom.txt" + intermissionmusic = "" + intermissioncounter = true + dimcolor = "6f 00 6b" + dimamount = 0.8 + definventorymaxamount = 25 + defaultrespawntime = 12 + defaultdropstyle = 1 + endoom = "ENDOOM" + player5start = 4001 + pickupcolor = "c0 c0 c0" + quitmessages = "Do you want to quit?" + + menufontcolor_title = "purple" + menufontcolor_label = "default" + menufontcolor_value = "gray" + menufontcolor_action = "gray" + menufontcolor_header = "blue" + menufontcolor_highlight = "lightblue" + menufontcolor_selection = "purple" + menubackbutton = "M_BACK_D" + playerclasses = "DoomPlayer" + pausesign = "-NOFLAT-" + gibfactor = 1 + cursorpic = "doomcurs" + textscreenx = 10 + textscreeny = 10 + defaultendsequence = "Inter_Cast" + maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt" + statscreen_mapnamefont = "BigFont" + statscreen_finishedpatch = "WIF" + statscreen_enteringpatch = "WIENTER" +} + +include "mapinfo/common.txt" From c5a4221b587bf7d5a9f7cfc42c1a6ead720c2722 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Apr 2015 16:27:57 +0200 Subject: [PATCH 31/58] - fixed handling of args for non-actor mapthings again. As it turns out there was insufficient information in the data to properly decide this case so a new flag was added to make it all more reliable. --- src/g_doomedmap.cpp | 9 ++++++--- src/info.h | 3 ++- src/p_mobj.cpp | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/g_doomedmap.cpp b/src/g_doomedmap.cpp index 131ddd076..c9deb7256 100644 --- a/src/g_doomedmap.cpp +++ b/src/g_doomedmap.cpp @@ -80,7 +80,8 @@ const char *SpecialMapthingNames[] = { struct MapinfoEdMapItem { FName classname; // DECORATE is read after MAPINFO so we do not have the actual classes available here yet. - int special; + short special; + bool argsdefined; int args[5]; // These are for error reporting. We must store the file information because it's no longer available when these items get resolved. FString filename; @@ -180,14 +181,15 @@ void FMapInfoParser::ParseDoomEdNums() editem.special = -1; } memset(editem.args, 0, sizeof(editem.args)); + editem.argsdefined = false; int minargs = 0; int maxargs = 5; FString specialname; if (sc.CheckString(",")) { - // todo: parse a special or args - if (editem.special < 0) editem.special = 0; // mark args as used - if this is done we need to prevent assignment of map args in P_SpawnMapThing. + editem.argsdefined = true; // mark args as used - if this is done we need to prevent assignment of map args in P_SpawnMapThing. + if (editem.special < 0) editem.special = 0; if (!sc.CheckNumber()) { sc.MustGetString(); @@ -264,6 +266,7 @@ void InitActorNumsFromMapinfo() FDoomEdEntry ent; ent.Type = cls; ent.Special = pair->Value.special; + ent.ArgsDefined = pair->Value.argsdefined; memcpy(ent.Args, pair->Value.args, sizeof(ent.Args)); DoomEdMap.Insert(pair->Key, ent); } diff --git a/src/info.h b/src/info.h index 8eed93e48..bdbb69940 100644 --- a/src/info.h +++ b/src/info.h @@ -282,7 +282,8 @@ struct FActorInfo struct FDoomEdEntry { const PClass *Type; - int Special; + short Special; + bool ArgsDefined; int Args[5]; }; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e3317e1a2..2571413c8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4617,9 +4617,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } // copy args to mapthing so that we have them in one place for the rest of this function - if (mentry->Type != NULL && mentry->Special >= 0) + if (mentry->ArgsDefined) { - mthing->special = mentry->Special; + if (mentry->Type!= NULL) mthing->special = mentry->Special; memcpy(mthing->args, mentry->Args, sizeof(mthing->args)); } From e4cadc90a5aa9eff55fe4bc4a3b5a0d1d046fb3c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 7 Apr 2015 11:08:28 -0500 Subject: [PATCH 32/58] Fix grammar: then -> than --- src/d_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 1244cc88f..da901bb68 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2310,7 +2310,7 @@ void D_DoomMain (void) if (hashfile) { - Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer then usual.\n"); + Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer than usual.\n"); } Printf ("W_Init: Init WADfiles.\n"); From 6428b399d6a931471f3d7bf1620599cb0e4193d1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 7 Apr 2015 12:37:33 -0500 Subject: [PATCH 33/58] Try to sanitize the exec+pullin mess - Old mess: * Execute autoexec files right away. * Execute -exec files right away. * Execute command line commands right away. - If, during any of the above, an unknown command or a set of an unknown variable is encountered, store it for later. - Pullin commands are directly executed and add to the list of files to load. * Do a little setup, including parsing CVARINFOs. * Retry saved commands in case CVARINFO added a cvar they refer to. - New, less messy, mess: * Parse autoexec files into an array. * Parse -exec files. * Parse command line commands. - During all of the above, exec commands are also parsed into the array immediately rather than being saved for execution later. - Pullin commands are parsed into a different array. The pullin command doesn't actually do anything directly anymore. * Add all the pullin files to the list of files to load. * Do a little setup, including parsing CVARINFOs. * Execute every command that was parsed in the preceding steps. --- src/c_cmds.cpp | 7 +- src/c_dispatch.cpp | 241 +++++++++++++++++++++------------------------ src/c_dispatch.h | 63 +++++++----- src/d_main.cpp | 32 ++++-- 4 files changed, 178 insertions(+), 165 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 74968404d..a40f1f1a2 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -450,11 +450,10 @@ CCMD (exec) for (int i = 1; i < argv.argc(); ++i) { - switch (C_ExecFile (argv[i], gamestate == GS_STARTUP)) + if (!C_ExecFile(argv[i])) { - case 1: Printf ("Could not open \"%s\"\n", argv[1]); break; - case 2: Printf ("Error parsing \"%s\"\n", argv[1]); break; - default: break; + Printf ("Could not exec \"%s\"\n", argv[i]); + break; } } } diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 6a526a661..d72993cb7 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -185,9 +185,6 @@ static const char *KeyConfCommands[] = "clearplayerclasses" }; -static TArray StoredStartupSets; -static bool RunningStoredStartups; - // CODE -------------------------------------------------------------------- IMPLEMENT_CLASS (DWaitingCommand) @@ -540,18 +537,6 @@ void ResetButtonStates () } } -void C_ExecStoredSets() -{ - assert(!RunningStoredStartups); - RunningStoredStartups = true; - for (unsigned i = 0; i < StoredStartupSets.Size(); ++i) - { - C_DoCommand(StoredStartupSets[i]); - } - StoredStartupSets.Clear(); - RunningStoredStartups = false; -} - void C_DoCommand (const char *cmd, int keynum) { FConsoleCommand *com; @@ -627,22 +612,7 @@ void C_DoCommand (const char *cmd, int keynum) if ( (com = FindNameInHashTable (Commands, beg, len)) ) { - if (gamestate == GS_STARTUP && !RunningStoredStartups && - len == 3 && strnicmp(beg, "set", 3) == 0) - { - // Save setting of unknown cvars for later, in case a loaded wad has a - // CVARINFO that defines it. - FCommandLine args(beg); - if (args.argc() > 1 && FindCVar(args[1], NULL) == NULL) - { - StoredStartupSets.Push(beg); - } - else - { - com->Run(args, players[consoleplayer].mo, keynum); - } - } - else if (gamestate != GS_STARTUP || ParsingKeyConf || + if (gamestate != GS_STARTUP || ParsingKeyConf || (len == 3 && strnicmp (beg, "set", 3) == 0) || (len == 7 && strnicmp (beg, "logfile", 7) == 0) || (len == 9 && strnicmp (beg, "unbindall", 9) == 0) || @@ -687,15 +657,7 @@ void C_DoCommand (const char *cmd, int keynum) } else { // We don't know how to handle this command - if (gamestate == GS_STARTUP && !RunningStoredStartups) - { - // Save it for later, in case a CVARINFO defines it. - StoredStartupSets.Push(beg); - } - else - { - Printf ("Unknown command \"%.*s\"\n", (int)len, beg); - } + Printf ("Unknown command \"%.*s\"\n", (int)len, beg); } } } @@ -1368,7 +1330,7 @@ CCMD (key) // Execute any console commands specified on the command line. // These all begin with '+' as opposed to '-'. -void C_ExecCmdLineParams () +FExecList *C_ParseCmdLineParams(FExecList *exec) { for (int currArg = 1; currArg < Args->NumArgs(); ) { @@ -1389,10 +1351,15 @@ void C_ExecCmdLineParams () cmdString = BuildString (cmdlen, Args->GetArgList (argstart)); if (!cmdString.IsEmpty()) { - C_DoCommand (&cmdString[1]); + if (exec == NULL) + { + exec = new FExecList; + } + exec->AddCommand(&cmdString[1]); } } } + return exec; } bool FConsoleCommand::IsAlias () @@ -1469,28 +1436,60 @@ void FConsoleAlias::SafeDelete () } } -static BYTE PullinBad = 2; -static const char *PullinFile; -extern TArray allwads; +void FExecList::AddCommand(const char *cmd, const char *file) +{ + // Pullins are special and need to be separated from general commands. + // They also turned out to be a really bad idea, since they make things + // more complicated. :( + if (file != NULL && strnicmp(cmd, "pullin", 6) == 0 && isspace(cmd[6])) + { + FCommandLine line(cmd); + C_SearchForPullins(this, file, line); + } + // Recursive exec: Parse this file now. + else if (strnicmp(cmd, "exec", 4) == 0 && isspace(cmd[4])) + { + FCommandLine argv(cmd); + for (int i = 1; i < argv.argc(); ++i) + { + C_ParseExecFile(argv[i], this); + } + } + else + { + Commands.Push(cmd); + } +} -int C_ExecFile (const char *file, bool usePullin) +void FExecList::ExecCommands() const +{ + for (unsigned i = 0; i < Commands.Size(); ++i) + { + AddCommandString(Commands[i].LockBuffer()); + Commands[i].UnlockBuffer(); + } +} + +void FExecList::AddPullins(TArray &wads) const +{ + for (unsigned i = 0; i < Pullins.Size(); ++i) + { + D_AddFile(wads, Pullins[i]); + } +} + +FExecList *C_ParseExecFile(const char *file, FExecList *exec) { FILE *f; char cmd[4096]; int retval = 0; - BYTE pullinSaved = PullinBad; - const char *fileSaved = PullinFile; - if ( (f = fopen (file, "r")) ) { - PullinBad = 1-usePullin; - PullinFile = file; - - while (fgets (cmd, 4095, f)) + while (fgets(cmd, countof(cmd)-1, f)) { // Comments begin with // - char *stop = cmd + strlen (cmd) - 1; + char *stop = cmd + strlen(cmd) - 1; char *comment = cmd; int inQuote = 0; @@ -1517,88 +1516,78 @@ int C_ExecFile (const char *file, bool usePullin) { // Comment in middle of line *comment = 0; } - - AddCommandString (cmd); + if (exec == NULL) + { + exec = new FExecList; + } + exec->AddCommand(cmd, file); } - if (!feof (f)) + if (!feof(f)) { - retval = 2; + Printf("Error parsing \"%s\"\n", file); } - fclose (f); + fclose(f); } else { - retval = 1; + Printf ("Could not open \"%s\"\n", file); + } + return exec; +} + +bool C_ExecFile (const char *file) +{ + FExecList *exec = C_ParseExecFile(file, NULL); + if (exec != NULL) + { + exec->ExecCommands(); + if (exec->Pullins.Size() > 0) + { + Printf(TEXTCOLOR_BOLD "Notice: Pullin files were ignored.\n"); + } + delete exec; + } + return exec != NULL; +} + +void C_SearchForPullins(FExecList *exec, const char *file, FCommandLine &argv) +{ + const char *lastSlash; + + assert(exec != NULL); + assert(file != NULL); +#ifdef __unix__ + lastSlash = strrchr(file, '/'); +#else + const char *lastSlash1, *lastSlash2; + + lastSlash1 = strrchr(file, '/'); + lastSlash2 = strrchr(file, '\\'); + lastSlash = MAX(lastSlash1, lastSlash2); +#endif + + for (int i = 1; i < argv.argc(); ++i) + { + // Try looking for the wad in the same directory as the .cfg + // before looking for it in the current directory. + if (lastSlash != NULL) + { + FString path(file, (lastSlash - file) + 1); + path += argv[i]; + if (FileExists(path)) + { + exec->Pullins.Push(path); + continue; + } + } + exec->Pullins.Push(argv[i]); } - PullinBad = pullinSaved; - PullinFile = fileSaved; - return retval; } CCMD (pullin) { - if (PullinBad == 2) - { - Printf ("This command is only valid from .cfg\n" - "files and only when used at startup.\n"); - } - else if (argv.argc() > 1) - { - const char *lastSlash; - -#ifdef __unix__ - lastSlash = strrchr (PullinFile, '/'); -#else - const char *lastSlash1, *lastSlash2; - - lastSlash1 = strrchr (PullinFile, '/'); - lastSlash2 = strrchr (PullinFile, '\\'); - lastSlash = MAX (lastSlash1, lastSlash2); -#endif - - if (PullinBad) - { - Printf ("Not loading:"); - } - for (int i = 1; i < argv.argc(); ++i) - { - if (PullinBad) - { - Printf (" %s", argv[i]); - } - else - { - // Try looking for the wad in the same directory as the .cfg - // before looking for it in the current directory. - char *path = argv[i]; - - if (lastSlash != NULL) - { - size_t pathlen = lastSlash - PullinFile + strlen (argv[i]) + 2; - path = new char[pathlen]; - strncpy (path, PullinFile, (lastSlash - PullinFile) + 1); - strcpy (path + (lastSlash - PullinFile) + 1, argv[i]); - if (!FileExists (path)) - { - delete[] path; - path = argv[i]; - } - else - { - FixPathSeperator (path); - } - } - D_AddFile (allwads, path); - if (path != argv[i]) - { - delete[] path; - } - } - } - if (PullinBad) - { - Printf ("\n"); - } - } + // Actual handling for pullin is now completely special-cased above + Printf (TEXTCOLOR_BOLD "Pullin" TEXTCOLOR_NORMAL " is only valid from .cfg\n" + "files and only when used at startup.\n"); } diff --git a/src/c_dispatch.h b/src/c_dispatch.h index b494005c7..f9aeb0dc3 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -39,31 +39,6 @@ class FConfigFile; class APlayerPawn; -extern bool CheckCheatmode (bool printmsg = true); - -void C_ExecCmdLineParams (); -void C_ExecStoredSets(); - -// Add commands to the console as if they were typed in. Can handle wait -// and semicolon-separated commands. This function may modify the source -// string, but the string will be restored to its original state before -// returning. Therefore, commands passed must not be in read-only memory. -void AddCommandString (char *text, int keynum=0); - -// Process a single console command. Does not handle wait. -void C_DoCommand (const char *cmd, int keynum=0); - -int C_ExecFile (const char *cmd, bool usePullin); - -// Write out alias commands to a file for all current aliases. -void C_ArchiveAliases (FConfigFile *f); - -void C_SetAlias (const char *name, const char *cmd); -void C_ClearAliases (); - -// build a single string out of multiple strings -FString BuildString (int argc, FString *argv); - // Class that can parse command lines class FCommandLine { @@ -83,6 +58,44 @@ private: bool noescapes; }; +// Contains the contents of an exec'ed file +struct FExecList +{ + TArray Commands; + TArray Pullins; + + void AddCommand(const char *cmd, const char *file = NULL); + void ExecCommands() const; + void AddPullins(TArray &wads) const; +}; + + +extern bool CheckCheatmode (bool printmsg = true); + +FExecList *C_ParseCmdLineParams(FExecList *exec); + +// Add commands to the console as if they were typed in. Can handle wait +// and semicolon-separated commands. This function may modify the source +// string, but the string will be restored to its original state before +// returning. Therefore, commands passed must not be in read-only memory. +void AddCommandString (char *text, int keynum=0); + +// Process a single console command. Does not handle wait. +void C_DoCommand (const char *cmd, int keynum=0); + +FExecList *C_ParseExecFile(const char *file, FExecList *source); +void C_SearchForPullins(FExecList *exec, const char *file, class FCommandLine &args); +bool C_ExecFile(const char *file); + +// Write out alias commands to a file for all current aliases. +void C_ArchiveAliases (FConfigFile *f); + +void C_SetAlias (const char *name, const char *cmd); +void C_ClearAliases (); + +// build a single string out of multiple strings +FString BuildString (int argc, FString *argv); + typedef void (*CCmdRun) (FCommandLine &argv, APlayerPawn *instigator, int key); class FConsoleCommand diff --git a/src/d_main.cpp b/src/d_main.cpp index da901bb68..9b46d42c2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1723,12 +1723,13 @@ bool ConsiderPatches (const char *arg) // //========================================================================== -void D_MultiExec (DArgs *list, bool usePullin) +FExecList *D_MultiExec (DArgs *list, FExecList *exec) { for (int i = 0; i < list->NumArgs(); ++i) { - C_ExecFile (list->GetArg (i), usePullin); + exec = C_ParseExecFile(list->GetArg(i), exec); } + return exec; } static void GetCmdLineFiles(TArray &wadfiles) @@ -2291,18 +2292,24 @@ void D_DoomMain (void) AddAutoloadFiles(iwad_info->Autoname); - // Run automatically executed files + // Process automatically executed files + FExecList *exec; execFiles = new DArgs; - GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName); - D_MultiExec (execFiles, true); + GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName); + exec = D_MultiExec(execFiles, NULL); - // Run .cfg files at the start of the command line. + // Process .cfg files at the start of the command line. execFiles = Args->GatherFiles ("-exec"); - D_MultiExec (execFiles, true); + exec = D_MultiExec(execFiles, exec); - C_ExecCmdLineParams (); // [RH] do all +set commands on the command line + // [RH] process all + commands on the command line + exec = C_ParseCmdLineParams(exec); CopyFiles(allwads, pwads); + if (exec != NULL) + { + exec->AddPullins(allwads); + } // Since this function will never leave we must delete this array here manually. pwads.Clear(); @@ -2324,8 +2331,13 @@ void D_DoomMain (void) // Now that wads are loaded, define mod-specific cvars. ParseCVarInfo(); - // Try setting previously unknown cvars again, as a CVARINFO may have made them known. - C_ExecStoredSets(); + // Actually exec command line commands and exec files. + if (exec != NULL) + { + exec->ExecCommands(); + delete exec; + exec = NULL; + } // [RH] Initialize localizable strings. GStrings.LoadStrings (false); From 9b95c134a766995dbb90a38fcad618384c3170df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 9 Apr 2015 09:14:53 +0200 Subject: [PATCH 34/58] - fixed: Lumps from a directory need to store the full file path so that they still can be accessed when the internal path is changed due to a filter directory. --- src/resourcefiles/file_directory.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/resourcefiles/file_directory.cpp b/src/resourcefiles/file_directory.cpp index f6adf0723..2be8da1b1 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -72,7 +72,7 @@ struct FDirectoryLump : public FResourceLump virtual FileReader *NewReader(); virtual int FillCache(); -private: + FString mFullPath; }; @@ -300,6 +300,8 @@ void FDirectory::AddEntry(const char *fullpath, int size) { FDirectoryLump *lump_p = &Lumps[Lumps.Reserve(1)]; + // Store the full path here so that we can access the file later, even if it is from a filter directory. + lump_p->mFullPath = fullpath; // The lump's name is only the part relative to the main directory lump_p->LumpNameSetup(fullpath + strlen(Filename)); lump_p->LumpSize = size; @@ -319,9 +321,7 @@ FileReader *FDirectoryLump::NewReader() { try { - FString fullpath = Owner->Filename; - fullpath += FullName; - return new FileReader(fullpath); + return new FileReader(mFullPath); } catch (CRecoverableError &) { @@ -339,6 +339,11 @@ int FDirectoryLump::FillCache() { Cache = new char[LumpSize]; FileReader *reader = NewReader(); + if (reader == NULL) + { + memset(Cache, 0, sizeof(Cache)); + return 0; + } reader->Read(Cache, LumpSize); delete reader; RefCount = 1; From 0c5d55d0a3f35889d9f51fc3dd8317eea7cbd5d4 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Thu, 9 Apr 2015 21:16:59 +0200 Subject: [PATCH 35/58] - More GAMENAME replacements in strings. These changes will change only some displayed messages. --- src/g_game.cpp | 8 ++++---- src/g_shared/shared_sbar.cpp | 2 +- src/posix/i_system.cpp | 4 ++-- src/sound/music_midi_timidity.cpp | 4 ++-- src/win32/i_cd.cpp | 4 ++-- src/win32/i_crash.cpp | 5 +---- src/win32/i_main.cpp | 4 ++-- src/win32/win32video.cpp | 2 +- 8 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index c442ee875..8101ca23d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2516,7 +2516,7 @@ bool G_ProcessIFFDemo (FString &mapname) id = ReadLong (&demo_p); if (id != ZDEM_ID) { - Printf ("Not a ZDoom demo file!\n"); + Printf ("Not a " GAMENAME " demo file!\n"); return true; } @@ -2541,12 +2541,12 @@ bool G_ProcessIFFDemo (FString &mapname) demover = ReadWord (&demo_p); // ZDoom version demo was created with if (demover < MINDEMOVERSION) { - Printf ("Demo requires an older version of ZDoom!\n"); + Printf ("Demo requires an older version of " GAMENAME "!\n"); //return true; } if (ReadWord (&demo_p) > DEMOGAMEVERSION) // Minimum ZDoom version { - Printf ("Demo requires a newer version of ZDoom!\n"); + Printf ("Demo requires a newer version of " GAMENAME "!\n"); return true; } if (demover >= 0x21a) @@ -2673,7 +2673,7 @@ void G_DoPlayDemo (void) if (ReadLong (&demo_p) != FORM_ID) { - const char *eek = "Cannot play non-ZDoom demos.\n"; + const char *eek = "Cannot play non-" GAMENAME " demos.\n"; C_ForgetCVars(); M_Free(demobuffer); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index d8e113824..c0442fc74 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1502,7 +1502,7 @@ void DBaseStatusBar::DrawTopStuff (EHudState state) { screen->DrawText (SmallFont, CR_TAN, 0, ST_Y - 40 * CleanYfac, "Demo was recorded with a different version\n" - "of ZDoom. Expect it to go out of sync.", + "of " GAMENAME ". Expect it to go out of sync.", DTA_CleanNoMove, true, TAG_DONE); } diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index 0a1b2f69a..fd6bb4c0c 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -331,7 +331,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad) gtk_container_add (GTK_CONTAINER(window), vbox); // Create the top label. - widget = gtk_label_new ("ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"); + widget = gtk_label_new (GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:"); gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0); gtk_misc_set_alignment (GTK_MISC(widget), 0, 0); @@ -450,7 +450,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) { FString cmd("kdialog --title \"" GAMESIG " "); cmd << GetVersionString() << ": Select an IWAD to use\"" - " --menu \"ZDoom found more than one IWAD\n" + " --menu \"" GAMENAME " found more than one IWAD\n" "Select from the list below to determine which one to use:\""; for(i = 0; i < numwads; ++i) diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 38ba8557e..3ce8d89d3 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -22,7 +22,7 @@ void ChildSigHandler (int signum) #ifdef _WIN32 BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode); -static char TimidityTitle[] = "TiMidity (ZDoom Launched)"; +static char TimidityTitle[] = "TiMidity (" GAMENAME " Launched)"; const char TimidityPPMIDIDevice::EventName[] = "TiMidity Killer"; CVAR (String, timidity_exe, "timidity.exe", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -347,7 +347,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity() } if (!good) { - Printf(PRINT_BOLD, "ZDoom requires a special version of TiMidity++\n"); + Printf(PRINT_BOLD, GAMENAME " requires a special version of TiMidity++\n"); } UnmapViewOfFile((LPVOID)exeBase); diff --git a/src/win32/i_cd.cpp b/src/win32/i_cd.cpp index b4982b865..32477f2dd 100644 --- a/src/win32/i_cd.cpp +++ b/src/win32/i_cd.cpp @@ -175,7 +175,7 @@ bool FCDThread::Init () CD_WindowClass.style = CS_NOCLOSE; CD_WindowClass.lpfnWndProc = CD_WndProc; CD_WindowClass.hInstance = g_hInst; - CD_WindowClass.lpszClassName = "ZDoom CD Player"; + CD_WindowClass.lpszClassName = GAMENAME " CD Player"; CD_WindowAtom = RegisterClass (&CD_WindowClass); if (CD_WindowAtom == 0) @@ -183,7 +183,7 @@ bool FCDThread::Init () CD_Window = CreateWindow ( (LPCTSTR)(INT_PTR)(int)CD_WindowAtom, - "ZDoom CD Player", + GAMENAME " CD Player", 0, 0, 0, 10, 10, NULL, diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index 453549ab7..0735e3553 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -125,10 +125,7 @@ RtlVirtualUnwind ( #define UPLOAD_BOUNDARY "Von-DnrNbJl0 P9d_BD;cEEsQVWpYMq0pbZ6NUmYHus;yIbFbkgB?.N=YC5O=BGZm+Rab5" #define DBGHELP_URI "/msredist/dbghelp.dl_" -// If you are working on your own modified version of ZDoom, change -// the last part of the UPLOAD_AGENT (between parentheses) to your -// own program's name. e.g. (Skulltag) or (ZDaemon) or (ZDoomFu) -#define UPLOAD_AGENT "ZDoom/" VERSIONSTR " (" GAMESIG ")" +#define UPLOAD_AGENT GAMENAME "/" VERSIONSTR " (" GAMESIG ")" // Time, in milliseconds, to wait for a send() or recv() to complete. #define TIMEOUT 60000 diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index c63e7bc1c..ea167428f 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -143,7 +143,7 @@ LONG ErrorIconChar; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static const char WinClassName[] = "ZDoomMainWindow"; +static const char WinClassName[] = GAMENAME "MainWindow"; static HMODULE hwtsapi32; // handle to wtsapi32.dll static void (*TermFuncs[MAX_TERMS])(void); static int NumTerms; @@ -1224,7 +1224,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n // This should only happen on basic Windows 95 installations, but since we // don't support Windows 95, we have no obligation to provide assistance in // getting it installed. - MessageBoxA(NULL, "Could not load riched20.dll", "ZDoom Error", MB_OK | MB_ICONSTOP); + MessageBoxA(NULL, "Could not load riched20.dll", GAMENAME " Error", MB_OK | MB_ICONSTOP); exit(0); } diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index b6d6d670e..3420ec0da 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -301,7 +301,7 @@ void Win32Video::InitDDraw () DDraw->Release (); DDraw = NULL; I_FatalError ("DirectDraw returned no display modes.\n\n" - "If you started ZDoom from a fullscreen DOS box, run it from " + "If you started " GAMENAME " from a fullscreen DOS box, run it from " "a DOS window instead. If that does not work, you may need to reboot."); } if (Args->CheckParm ("-2")) From a81dd798a82acc12ec1c561964b46ec30672e29d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2015 14:35:32 +0200 Subject: [PATCH 36/58] - fixed incorrect memset argument. --- 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 2be8da1b1..8b85425f1 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -341,7 +341,7 @@ int FDirectoryLump::FillCache() FileReader *reader = NewReader(); if (reader == NULL) { - memset(Cache, 0, sizeof(Cache)); + memset(Cache, 0, LumpSize); return 0; } reader->Read(Cache, LumpSize); From 0a1d1db0ba4e4f23c655b9b1a84da56324683495 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2015 17:40:26 +0200 Subject: [PATCH 37/58] =?UTF-8?q?-=20fixed=20missing=20#inc=C3=B6udes=20of?= =?UTF-8?q?=20version.h=20for=20GAMENAME.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sound/music_midi_timidity.cpp | 3 +++ src/win32/i_cd.cpp | 1 + src/win32/win32video.cpp | 1 + 3 files changed, 5 insertions(+) diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 3ce8d89d3..a8c099d52 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -2,6 +2,7 @@ #include "c_cvars.h" #include "cmdlib.h" #include "templates.h" +#include "version.h" #ifndef _WIN32 #include @@ -20,6 +21,8 @@ void ChildSigHandler (int signum) #endif #ifdef _WIN32 + + BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode); static char TimidityTitle[] = "TiMidity (" GAMENAME " Launched)"; diff --git a/src/win32/i_cd.cpp b/src/win32/i_cd.cpp index 32477f2dd..29167f276 100644 --- a/src/win32/i_cd.cpp +++ b/src/win32/i_cd.cpp @@ -45,6 +45,7 @@ #include "c_dispatch.h" #include "m_argv.h" #include "i_system.h" +#include "version.h" #include "i_cd.h" #include "helperthread.h" diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 3420ec0da..3071ae8e7 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -70,6 +70,7 @@ #include "r_defs.h" #include "v_text.h" #include "r_swrenderer.h" +#include "version.h" #include "win32iface.h" From 9f2b3efd13c513d06ad7a647766d6618d64deb82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2015 18:09:18 +0200 Subject: [PATCH 38/58] - fixed: The terrain types array needs to be extended if a texture outside its bounds is processed - this can happen for textures with long names. --- src/p_terrain.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_terrain.h b/src/p_terrain.h index 9f00d07bc..482c66b00 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -69,6 +69,12 @@ public: } void Set(int index, int value) { + if ((unsigned)index >= Types.Size()) + { + int oldsize = Types.Size(); + Resize(index + 1); + memset(&Types[oldsize], 0xff, (index + 1 - oldsize)*sizeof(WORD)); + } Types[index] = value; } }; From 7217c69be433dcb47963ced1d4963d679caf8395 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 12 Apr 2015 15:22:39 -0400 Subject: [PATCH 39/58] - Fixed portability issue in ANIMATED with systems that treat char as unsigned. --- src/textures/animations.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index ffff062c6..0290a293f 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -177,8 +177,8 @@ void FTextureManager::InitAnimated (void) { FMemLump animatedlump = Wads.ReadLump (lumpnum); int animatedlen = Wads.LumpLength(lumpnum); - const char *animdefs = (const char *)animatedlump.GetMem(); - const char *anim_p; + const BYTE *animdefs = (const BYTE *)animatedlump.GetMem(); + const BYTE *anim_p; FTextureID pic1, pic2; int animtype; DWORD animspeed; @@ -186,7 +186,7 @@ void FTextureManager::InitAnimated (void) // Init animation animtype = FAnimDef::ANIM_Forward; - for (anim_p = animdefs; *anim_p != -1; anim_p += 23) + for (anim_p = animdefs; *anim_p != 0xFF; anim_p += 23) { // make sure the current chunk of data is inside the lump boundaries. if (anim_p + 22 >= animdefs + animatedlen) @@ -196,8 +196,8 @@ void FTextureManager::InitAnimated (void) if (*anim_p /* .istexture */ & 1) { // different episode ? - if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() || - !(pic2 = CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists()) + if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, FTexture::TEX_Wall, texflags)).Exists() || + !(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .endname */, FTexture::TEX_Wall, texflags)).Exists()) continue; // [RH] Bit 1 set means allow decals on walls with this texture @@ -205,16 +205,16 @@ void FTextureManager::InitAnimated (void) } else { - if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() || - !(pic2 = CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists()) + if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, FTexture::TEX_Flat, texflags)).Exists() || + !(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .startname */, FTexture::TEX_Flat, texflags)).Exists()) continue; } FTexture *tex1 = Texture(pic1); FTexture *tex2 = Texture(pic2); - animspeed = (BYTE(anim_p[19]) << 0) | (BYTE(anim_p[20]) << 8) | - (BYTE(anim_p[21]) << 16) | (BYTE(anim_p[22]) << 24); + animspeed = (anim_p[19] << 0) | (anim_p[20] << 8) | + (anim_p[21] << 16) | (anim_p[22] << 24); // SMMU-style swirly hack? Don't apply on already-warping texture if (animspeed > 65535 && tex1 != NULL && !tex1->bWarped) @@ -242,7 +242,7 @@ void FTextureManager::InitAnimated (void) if (pic1 == pic2) { // This animation only has one frame. Skip it. (Doom aborted instead.) - Printf ("Animation %s in ANIMATED has only one frame\n", anim_p + 10); + Printf ("Animation %s in ANIMATED has only one frame\n", (const char*)(anim_p + 10)); continue; } // [RH] Allow for backward animations as well as forward. From 6fc63daabd41a4dffbd63045ee72f1f3eb07bf82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 13 Apr 2015 22:08:44 +0200 Subject: [PATCH 40/58] - fixed: Zips whose central directory cannot be read need to print an error message. --- src/resourcefiles/file_zip.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 5d6ff6c9e..c7e787c70 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -168,7 +168,7 @@ bool FZipFile::Open(bool quiet) if (centraldir == 0) { - if (!quiet) Printf("\n%s: ZIP file corrupt!\n", Filename); + if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", Filename); return false; } @@ -180,7 +180,7 @@ bool FZipFile::Open(bool quiet) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - if (!quiet) Printf("\n%s: Multipart Zip files are not supported.\n", Filename); + if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", Filename); return false; } @@ -188,9 +188,10 @@ bool FZipFile::Open(bool quiet) Lumps = new FZipLump[NumLumps]; // Load the entire central directory. Too bad that this contains variable length entries... - void *directory = malloc(LittleLong(info.DirectorySize)); + int dirsize = LittleLong(info.DirectorySize); + void *directory = malloc(dirsize); Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET); - Reader->Read(directory, LittleLong(info.DirectorySize)); + Reader->Read(directory, dirsize); char *dirptr = (char*)directory; FZipLump *lump_p = Lumps; @@ -204,6 +205,13 @@ bool FZipFile::Open(bool quiet) LittleShort(zip_fh->NameLength) + LittleShort(zip_fh->ExtraLength) + LittleShort(zip_fh->CommentLength); + + if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. + { + free(directory); + if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", Filename); + return false; + } // skip Directories if (name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0) @@ -221,7 +229,7 @@ bool FZipFile::Open(bool quiet) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - if (!quiet) Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method); + if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method); skipped++; continue; } @@ -229,7 +237,7 @@ bool FZipFile::Open(bool quiet) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - if (!quiet) Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars()); + if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars()); skipped++; continue; } @@ -260,7 +268,7 @@ bool FZipFile::Open(bool quiet) NumLumps -= skipped; free(directory); - if (!quiet) Printf(", %d lumps\n", NumLumps); + if (!quiet) Printf(TEXTCOLOR_NORMAL ", %d lumps\n", NumLumps); PostProcessArchive(&Lumps[0], sizeof(FZipLump)); return true; From ccb49a4242f9b06d3c01daba86ed3893f4ce1f26 Mon Sep 17 00:00:00 2001 From: Blue-Shadow Date: Tue, 14 Apr 2015 19:13:25 +0300 Subject: [PATCH 41/58] Fixed: missing '=' in conversation ID defs Conversation ID definitions in strifeteaser1 were missing the equal sign between the ID and actor class name. --- .../strifeteaser1/mapinfo/conversationids.txt | 282 +++++++++--------- 1 file changed, 141 insertions(+), 141 deletions(-) diff --git a/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt b/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt index 268702d52..b1b6ae380 100644 --- a/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt +++ b/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt @@ -1,144 +1,144 @@ conversationids { - 2 WeaponSmith - 3 BarKeep - 4 Armorer - 5 Medic - 6 Peasant1 - 7 Peasant2 - 8 Peasant3 - 9 Peasant4 - 10 Peasant5 - 11 Peasant6 - 12 Peasant7 - 13 Peasant8 - 14 Peasant9 - 15 Peasant10 - 16 Peasant11 - 17 Peasant12 - 18 Peasant13 - 19 Peasant14 - 20 Peasant15 - 21 Peasant16 - 22 Peasant17 - 23 Peasant18 - 24 Peasant19 - 25 Peasant20 - 26 Peasant21 - 27 Peasant22 - 37 Beggar1 - 38 Beggar2 - 39 Beggar3 - 40 Beggar4 - 41 Beggar5 - 42 Rebel1 - 43 Rebel2 - 44 Rebel3 - 45 Rebel4 - 46 Rebel5 - 47 Rebel6 - 48 Macil1 - 49 Macil2 - 52 AcolyteTan - 53 AcolyteRed - 54 AcolyteRust - 55 AcolyteGray - 56 AcolyteDGreen - 57 AcolyteGold - 58 AcolyteShadow - 61 Templar - 62 Oracle - 63 Loremaster - 70 AlienSpectre2 - 94 InquisitorArm - 121 MedPatch - 122 MedicalKit - 123 SurgeryKit - 124 DegninOre - 125 MetalArmor - 126 LeatherArmor - 129 BaseKey - 130 GovsKey - 131 Passcard - 132 IDBadge - 133 PrisonKey - 134 SeveredHand - 135 Power1Key - 136 Power2Key - 137 Power3Key - 138 GoldKey - 139 IDCard - 140 SilverKey - 141 OracleKey - 142 MilitaryID - 143 OrderKey - 144 WarehouseKey - 145 BrassKey - 146 RedCrystalKey - 147 BlueCrystalKey - 148 ChapelKey - 149 CatacombKey - 150 SecurityKey - 151 CoreKey - 152 MaulerKey - 153 FactoryKey - 154 MineKey - 155 NewKey5 - 156 ShadowArmor - 157 EnvironmentalSuit - 158 GuardUniform - 159 OfficersUniform - 160 StrifeMap - 161 Coin - 162 Gold10 - 163 Gold25 - 164 Gold50 - 165 BeldinsRing - 166 OfferingChalice - 167 Ear - 168 Communicator - 169 Targeter - 170 HEGrenadeRounds - 171 PhosphorusGrenadeRounds - 173 ClipOfBullets - 174 BoxOfBullets - 175 MiniMissiles - 176 CrateOfMissiles - 177 EnergyPod - 178 EnergyPack - 179 PoisonBolts - 180 ElectricBolts - 181 AmmoSatchel - 182 AssaultGun - 183 AssaultGunStanding - 184 FlameThrower - 185 FlameThrowerParts - 186 MiniMissileLauncher - 187 Mauler - 188 StrifeCrossbow - 189 StrifeGrenadeLauncher - 190 Sigil1 - 191 Sigil2 - 192 Sigil3 - 193 Sigil4 - 194 Sigil5 - 196 RatBuddy - 230 DeadCrusader - 280 AmmoFillup - 281 HealthFillup - 282 info - 283 RaiseAlarm - 284 OpenDoor222 - 285 CloseDoor222 - 286 PrisonPass - 287 UpgradeStamina - 288 UpgradeAccuracy - 289 InterrogatorReport - 292 OraclePass - 293 QuestItem1 - 294 QuestItem2 - 295 QuestItem3 - 296 QuestItem4 - 297 QuestItem5 - 298 QuestItem6 + 2 = WeaponSmith + 3 = BarKeep + 4 = Armorer + 5 = Medic + 6 = Peasant1 + 7 = Peasant2 + 8 = Peasant3 + 9 = Peasant4 + 10 = Peasant5 + 11 = Peasant6 + 12 = Peasant7 + 13 = Peasant8 + 14 = Peasant9 + 15 = Peasant10 + 16 = Peasant11 + 17 = Peasant12 + 18 = Peasant13 + 19 = Peasant14 + 20 = Peasant15 + 21 = Peasant16 + 22 = Peasant17 + 23 = Peasant18 + 24 = Peasant19 + 25 = Peasant20 + 26 = Peasant21 + 27 = Peasant22 + 37 = Beggar1 + 38 = Beggar2 + 39 = Beggar3 + 40 = Beggar4 + 41 = Beggar5 + 42 = Rebel1 + 43 = Rebel2 + 44 = Rebel3 + 45 = Rebel4 + 46 = Rebel5 + 47 = Rebel6 + 48 = Macil1 + 49 = Macil2 + 52 = AcolyteTan + 53 = AcolyteRed + 54 = AcolyteRust + 55 = AcolyteGray + 56 = AcolyteDGreen + 57 = AcolyteGold + 58 = AcolyteShadow + 61 = Templar + 62 = Oracle + 63 = Loremaster + 70 = AlienSpectre2 + 94 = InquisitorArm + 121 = MedPatch + 122 = MedicalKit + 123 = SurgeryKit + 124 = DegninOre + 125 = MetalArmor + 126 = LeatherArmor + 129 = BaseKey + 130 = GovsKey + 131 = Passcard + 132 = IDBadge + 133 = PrisonKey + 134 = SeveredHand + 135 = Power1Key + 136 = Power2Key + 137 = Power3Key + 138 = GoldKey + 139 = IDCard + 140 = SilverKey + 141 = OracleKey + 142 = MilitaryID + 143 = OrderKey + 144 = WarehouseKey + 145 = BrassKey + 146 = RedCrystalKey + 147 = BlueCrystalKey + 148 = ChapelKey + 149 = CatacombKey + 150 = SecurityKey + 151 = CoreKey + 152 = MaulerKey + 153 = FactoryKey + 154 = MineKey + 155 = NewKey5 + 156 = ShadowArmor + 157 = EnvironmentalSuit + 158 = GuardUniform + 159 = OfficersUniform + 160 = StrifeMap + 161 = Coin + 162 = Gold10 + 163 = Gold25 + 164 = Gold50 + 165 = BeldinsRing + 166 = OfferingChalice + 167 = Ear + 168 = Communicator + 169 = Targeter + 170 = HEGrenadeRounds + 171 = PhosphorusGrenadeRounds + 173 = ClipOfBullets + 174 = BoxOfBullets + 175 = MiniMissiles + 176 = CrateOfMissiles + 177 = EnergyPod + 178 = EnergyPack + 179 = PoisonBolts + 180 = ElectricBolts + 181 = AmmoSatchel + 182 = AssaultGun + 183 = AssaultGunStanding + 184 = FlameThrower + 185 = FlameThrowerParts + 186 = MiniMissileLauncher + 187 = Mauler + 188 = StrifeCrossbow + 189 = StrifeGrenadeLauncher + 190 = Sigil1 + 191 = Sigil2 + 192 = Sigil3 + 193 = Sigil4 + 194 = Sigil5 + 196 = RatBuddy + 230 = DeadCrusader + 280 = AmmoFillup + 281 = HealthFillup + 282 = info + 283 = RaiseAlarm + 284 = OpenDoor222 + 285 = CloseDoor222 + 286 = PrisonPass + 287 = UpgradeStamina + 288 = UpgradeAccuracy + 289 = InterrogatorReport + 292 = OraclePass + 293 = QuestItem1 + 294 = QuestItem2 + 295 = QuestItem3 + 296 = QuestItem4 + 297 = QuestItem5 + 298 = QuestItem6 } From 238046655c13329a150d65e27d344bf93f38792c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 31 Mar 2015 17:09:19 +0200 Subject: [PATCH 42/58] - wrapped all accesses to the sector tag into accessor functions, as preparation for allowing multiple tags per sector. --- src/compatibility.cpp | 2 +- src/fragglescript/t_func.cpp | 18 ++++-------------- src/g_strife/a_strifestuff.cpp | 2 +- src/p_acs.cpp | 4 ++-- src/p_floor.cpp | 2 +- src/p_lights.cpp | 2 +- src/p_linkedsectors.cpp | 2 +- src/p_lnspec.cpp | 6 +++--- src/p_mobj.cpp | 2 +- src/p_sectors.cpp | 30 ++++++++++++++++++++++++++++++ src/p_setup.cpp | 20 ++++++-------------- src/p_teleport.cpp | 4 ++-- src/p_udmf.cpp | 2 +- src/p_writemap.cpp | 2 +- src/p_xlat.cpp | 2 +- src/r_defs.h | 5 +++++ 16 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index fd309ec8b..ff3a67e61 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -551,7 +551,7 @@ void SetCompatibilityParams() { if ((unsigned)CompatParams[i + 1] < (unsigned)numsectors) { - sectors[CompatParams[i + 1]].tag = CompatParams[i + 2]; + sectors[CompatParams[i + 1]].SetTag(CompatParams[i + 2]); } i += 3; break; diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0bddcd7fd..0359aa423 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1158,7 +1158,7 @@ void FParser::SF_ObjSector(void) } t_return.type = svt_int; - t_return.value.i = mo ? mo->Sector->tag : 0; // nullptr check + t_return.value.i = mo ? mo->Sector->GetTag() : 0; // nullptr check } //========================================================================== @@ -4291,7 +4291,7 @@ void FParser::SF_KillInSector() while ((mo=it.Next())) { - if (mo->flags3&MF3_ISMONSTER && mo->Sector->tag==tag) P_DamageMobj(mo, NULL, NULL, 1000000, NAME_Massacre); + if (mo->flags3&MF3_ISMONSTER && mo->Sector->HasTag(tag)) P_DamageMobj(mo, NULL, NULL, 1000000, NAME_Massacre); } } } @@ -4388,19 +4388,9 @@ void FParser::SF_ChangeTag() { for (int secnum = -1; (secnum = P_FindSectorFromTag (t_argv[0].value.i, secnum)) >= 0; ) { - sectors[secnum].tag=t_argv[1].value.i; - } - - // Recreate the hash tables - int i; - - for (i=numsectors; --i>=0; ) sectors[i].firsttag = -1; - for (i=numsectors; --i>=0; ) - { - int j = (unsigned) sectors[i].tag % (unsigned) numsectors; - sectors[i].nexttag = sectors[j].firsttag; - sectors[j].firsttag = i; + sectors[secnum].SetTag(t_argv[1].value.i); } + sector_t::HashTags(); } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 95b0030a0..e8dff183f 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -636,7 +636,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) } else if ((sec->special & 0xFF) == Scroll_StrifeCurrent) { - int anglespeed = sec->tag - 100; + int anglespeed = sec->GetTag() - 100; fixed_t speed = (anglespeed % 10) << (FRACBITS - 4); angle_t finean = (anglespeed / 10) << (32-3); finean >>= ANGLETOFINESHIFT; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 5556507b7..3dd0cfef0 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3211,7 +3211,7 @@ do_count: if (actor->health > 0 && (kind == NULL || actor->IsA (kind))) { - if (actor->Sector->tag == tag || tag == -1) + if (actor->Sector->HasTag(tag) || tag == -1) { // Don't count items in somebody's inventory if (!actor->IsKindOf (RUNTIME_CLASS(AInventory)) || @@ -3231,7 +3231,7 @@ do_count: if (actor->health > 0 && (kind == NULL || actor->IsA (kind))) { - if (actor->Sector->tag == tag || tag == -1) + if (actor->Sector->HasTag(tag) || tag == -1) { // Don't count items in somebody's inventory if (!actor->IsKindOf (RUNTIME_CLASS(AInventory)) || diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 9a5a6eaf8..231ccd5a3 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -572,7 +572,7 @@ static int P_FindSectorFromTagLinear (int tag, int start) { for (int i=start+1;iGetSector()->tag == tag) + if (effect->GetSector()->HasTag(tag)) { effect->Destroy(); } diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index 2d06bc043..acf1d6906 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -278,7 +278,7 @@ static void RemoveTaggedSectors(extsector_t::linked::plane &scrollplane, int tag { for(int i = scrollplane.Sectors.Size()-1; i>=0; i--) { - if (scrollplane.Sectors[i].Sector->tag == tag) + if (scrollplane.Sectors[i].Sector->HasTag(tag)) { scrollplane.Sectors.Delete(i); } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index b550eeb77..76f7a0371 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1266,7 +1266,7 @@ FUNC(LS_Thing_Destroy) while (actor) { AActor *temp = iterator.Next (); - if (actor->flags & MF_SHOOTABLE && actor->Sector->tag == arg2) + if (actor->flags & MF_SHOOTABLE && actor->Sector->HasTag(arg2)) P_DamageMobj (actor, NULL, it, arg1 ? TELEFRAG_DAMAGE : actor->health, NAME_None); actor = temp; } @@ -1279,7 +1279,7 @@ FUNC(LS_Thing_Destroy) while (actor) { AActor *temp = iterator.Next (); - if (actor->flags & MF_SHOOTABLE && (arg2 == 0 || actor->Sector->tag == arg2)) + if (actor->flags & MF_SHOOTABLE && (arg2 == 0 || actor->Sector->HasTag(arg2))) P_DamageMobj (actor, NULL, it, arg1 ? TELEFRAG_DAMAGE : actor->health, NAME_None); actor = temp; } @@ -2167,7 +2167,7 @@ static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed { if (scroller->IsType (type)) { - if (sectors[scroller->GetAffectee ()].tag == tag) + if (sectors[scroller->GetAffectee ()].HasTag(tag)) { i++; scroller->SetRate (dx, dy); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2571413c8..ffb12fddd 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3437,7 +3437,7 @@ void AActor::Tick () } else if (scrolltype == Scroll_StrifeCurrent) { // Strife scroll special - int anglespeed = sec->tag - 100; + int anglespeed = sec->GetTag() - 100; fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*CARRYFACTOR); angle_t fineangle = (anglespeed / 10) << (32-3); fineangle >>= ANGLETOFINESHIFT; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 904c76c1b..f34eadb44 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -825,6 +825,36 @@ sector_t *sector_t::GetHeightSec() const } +bool sector_t::HasTag(int checktag) const +{ + return tag == checktag; +} + +void sector_t::SetTag(int tagnum, bool discardall) +{ + tag = tagnum; +} + +int sector_t::GetTag() const +{ + return tag; +} + +void sector_t::HashTags() +{ + int i; + + for (i=numsectors; --i>=0; ) // Initially make all slots empty. + sectors[i].firsttag = -1; + for (i=numsectors; --i>=0; ) // Proceed from last to first sector + { // so that lower sectors appear first + int j = (unsigned) sectors[i].tag % (unsigned) numsectors; // Hash func + sectors[i].nexttag = sectors[j].firsttag; // Prepend sector to chain + sectors[j].firsttag = i; + } +} + + bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const { bool copy = false; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 80c84ffde..990a18ae5 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1514,7 +1514,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); ss->secretsector = !!(ss->special&SECRET_MASK); - ss->tag = LittleShort(ms->tag); + ss->SetTag(LittleShort(ms->tag)); ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 ss->seqType = defSeqType; @@ -2495,7 +2495,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, intmaps for (s = 0; s < numsectors; s++) { - if (sectors[s].tag == tag) + if (sectors[s].HasTag(tag)) { if (!colorgood) color = sectors[s].ColorMap->Color; if (!foggood) fog = sectors[s].ColorMap->Fade; @@ -3131,9 +3131,9 @@ static void P_GroupLines (bool buildmap) { if (sector->linecount == 0) { - Printf ("Sector %i (tag %i) has no lines\n", i, sector->tag); + Printf ("Sector %i (tag %i) has no lines\n", i, sector->GetTag()); // 0 the sector's tag so that no specials can use it - sector->tag = 0; + sector->SetTag(0); } else { @@ -3309,18 +3309,10 @@ void P_LoadBehavior (MapData * map) // Hash the sector tags across the sectors and linedefs. static void P_InitTagLists () { - int i; - - for (i=numsectors; --i>=0; ) // Initially make all slots empty. - sectors[i].firsttag = -1; - for (i=numsectors; --i>=0; ) // Proceed from last to first sector - { // so that lower sectors appear first - int j = (unsigned) sectors[i].tag % (unsigned) numsectors; // Hash func - sectors[i].nexttag = sectors[j].firsttag; // Prepend sector to chain - sectors[j].firsttag = i; - } + sector_t::HashTags(); // killough 4/17/98: same thing, only for linedefs + int i; for (i=numlines; --i>=0; ) // Initially make all slots empty. lines[i].firstid = -1; diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 3e3b03c4e..e30457b15 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -250,7 +250,7 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom) int count = 0; while ( (searcher = iterator.Next ()) ) { - if (tag == 0 || searcher->Sector->tag == tag) + if (tag == 0 || searcher->Sector->HasTag(tag)) { count++; } @@ -289,7 +289,7 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom) while (count > 0) { searcher = iterator.Next (); - if (tag == 0 || searcher->Sector->tag == tag) + if (tag == 0 || searcher->Sector->HasTag(tag)) { count--; } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 31634ee81..4ad3c3efc 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1316,7 +1316,7 @@ public: continue; case NAME_Id: - sec->tag = (short)CheckInt(key); + sec->SetTag((short)CheckInt(key), false); continue; default: diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 83ed40b5b..e21eb506e 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -262,7 +262,7 @@ static int WriteSECTORS (FILE *file) uppercopy (ms.ceilingpic, GetTextureName (sectors[i].GetTexture(sector_t::ceiling))); ms.lightlevel = LittleShort((short)sectors[i].lightlevel); ms.special = LittleShort(sectors[i].special); - ms.tag = LittleShort(sectors[i].tag); + ms.tag = LittleShort(sectors[i].GetTag()); fwrite (&ms, sizeof(ms), 1, file); } return numsectors * sizeof(ms); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index be2d154c3..68780fdba 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -304,7 +304,7 @@ void P_TranslateTeleportThings () while ( (dest = iterator.Next()) ) { - if (dest->Sector->tag == 0) + if (dest->Sector->GetTag() == 0) { dest->tid = 1; dest->AddToHash (); diff --git a/src/r_defs.h b/src/r_defs.h index dd2136508..5cdbb9f82 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -633,6 +633,11 @@ struct sector_t return pos == floor? floorplane:ceilingplane; } + bool HasTag(int checktag) const; + void SetTag(int tagnum, bool discardall = true); + int GetTag() const; + static void HashTags(); + bool PlaneMoving(int pos); From 2faf836aa143afa2fd378a8fc90effb029d3ce23 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Apr 2015 18:48:19 +0200 Subject: [PATCH 43/58] - some minor rework of tag access interface after I realized that some stuff (e.g. Strife's scrolling sector special) need the primary tag to treated specially. --- src/compatibility.cpp | 3 ++- src/fragglescript/t_func.cpp | 5 +++-- src/g_strife/a_strifestuff.cpp | 2 +- src/p_mobj.cpp | 2 +- src/p_sectors.cpp | 9 +++++++-- src/p_setup.cpp | 6 +++--- src/p_udmf.cpp | 2 +- src/p_writemap.cpp | 2 +- src/p_xlat.cpp | 2 +- src/r_defs.h | 5 +++-- 10 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index ff3a67e61..096811def 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -551,7 +551,8 @@ void SetCompatibilityParams() { if ((unsigned)CompatParams[i + 1] < (unsigned)numsectors) { - sectors[CompatParams[i + 1]].SetTag(CompatParams[i + 2]); + sectors[CompatParams[i + 1]].ClearTags(); + sectors[CompatParams[i + 1]].SetMainTag(CompatParams[i + 2]); } i += 3; break; diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0359aa423..039d261d7 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1158,7 +1158,7 @@ void FParser::SF_ObjSector(void) } t_return.type = svt_int; - t_return.value.i = mo ? mo->Sector->GetTag() : 0; // nullptr check + t_return.value.i = mo ? mo->Sector->GetMainTag() : 0; // nullptr check } //========================================================================== @@ -4388,7 +4388,8 @@ void FParser::SF_ChangeTag() { for (int secnum = -1; (secnum = P_FindSectorFromTag (t_argv[0].value.i, secnum)) >= 0; ) { - sectors[secnum].SetTag(t_argv[1].value.i); + sectors[secnum].ClearTags(); + sectors[secnum].SetMainTag(t_argv[1].value.i); } sector_t::HashTags(); } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index e8dff183f..aa9f629db 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -636,7 +636,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) } else if ((sec->special & 0xFF) == Scroll_StrifeCurrent) { - int anglespeed = sec->GetTag() - 100; + int anglespeed = sec->GetMainTag() - 100; fixed_t speed = (anglespeed % 10) << (FRACBITS - 4); angle_t finean = (anglespeed / 10) << (32-3); finean >>= ANGLETOFINESHIFT; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index ffb12fddd..14837a1e2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3437,7 +3437,7 @@ void AActor::Tick () } else if (scrolltype == Scroll_StrifeCurrent) { // Strife scroll special - int anglespeed = sec->GetTag() - 100; + int anglespeed = sec->GetMainTag() - 100; fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*CARRYFACTOR); angle_t fineangle = (anglespeed / 10) << (32-3); fineangle >>= ANGLETOFINESHIFT; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index f34eadb44..d96540351 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -830,16 +830,21 @@ bool sector_t::HasTag(int checktag) const return tag == checktag; } -void sector_t::SetTag(int tagnum, bool discardall) +void sector_t::SetMainTag(int tagnum) { tag = tagnum; } -int sector_t::GetTag() const +int sector_t::GetMainTag() const { return tag; } +void sector_t::ClearTags() +{ + tag = 0; +} + void sector_t::HashTags() { int i; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 990a18ae5..62270567c 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1514,7 +1514,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); ss->secretsector = !!(ss->special&SECRET_MASK); - ss->SetTag(LittleShort(ms->tag)); + ss->SetMainTag(LittleShort(ms->tag)); ss->thinglist = NULL; ss->touching_thinglist = NULL; // phares 3/14/98 ss->seqType = defSeqType; @@ -3131,9 +3131,9 @@ static void P_GroupLines (bool buildmap) { if (sector->linecount == 0) { - Printf ("Sector %i (tag %i) has no lines\n", i, sector->GetTag()); + Printf ("Sector %i (tag %i) has no lines\n", i, sector->GetMainTag()); // 0 the sector's tag so that no specials can use it - sector->SetTag(0); + sector->ClearTags(); } else { diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 4ad3c3efc..aab952f21 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1316,7 +1316,7 @@ public: continue; case NAME_Id: - sec->SetTag((short)CheckInt(key), false); + sec->SetMainTag((short)CheckInt(key)); continue; default: diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index e21eb506e..2f11ee5c1 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -262,7 +262,7 @@ static int WriteSECTORS (FILE *file) uppercopy (ms.ceilingpic, GetTextureName (sectors[i].GetTexture(sector_t::ceiling))); ms.lightlevel = LittleShort((short)sectors[i].lightlevel); ms.special = LittleShort(sectors[i].special); - ms.tag = LittleShort(sectors[i].GetTag()); + ms.tag = LittleShort(sectors[i].GetMainTag()); fwrite (&ms, sizeof(ms), 1, file); } return numsectors * sizeof(ms); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 68780fdba..2d48e6053 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -304,7 +304,7 @@ void P_TranslateTeleportThings () while ( (dest = iterator.Next()) ) { - if (dest->Sector->GetTag() == 0) + if (dest->Sector->GetMainTag() == 0) { dest->tid = 1; dest->AddToHash (); diff --git a/src/r_defs.h b/src/r_defs.h index 5cdbb9f82..41821cb62 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -634,8 +634,9 @@ struct sector_t } bool HasTag(int checktag) const; - void SetTag(int tagnum, bool discardall = true); - int GetTag() const; + void SetMainTag(int tagnum); + int GetMainTag() const; + void ClearTags(); static void HashTags(); bool PlaneMoving(int pos); From 425e5b9ffcba30d8bf212a7a76759bab2dc0e73b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Apr 2015 22:39:57 +0200 Subject: [PATCH 44/58] - replaced P_FindSectorFromTag with an FSectorTagIterator class. This is done to encapsulate the gory details of tag search in one place so that the implementation of multiple tags per sector remains contained to a few isolated spots in the code. This also moves the special 'tag == 0 -> activate backsector' handling into the iterator class. --- src/fragglescript/t_func.cpp | 76 +++++++++----- src/fragglescript/t_script.cpp | 6 +- src/g_shared/a_skies.cpp | 4 +- src/p_3dfloors.cpp | 3 +- src/p_3dmidtex.cpp | 4 +- src/p_acs.cpp | 29 +++--- src/p_ceiling.cpp | 4 +- src/p_doors.cpp | 7 +- src/p_floor.cpp | 114 ++++----------------- src/p_lights.cpp | 54 +++++----- src/p_linkedsectors.cpp | 4 +- src/p_lnspec.cpp | 89 +++++++++------- src/p_pillar.cpp | 12 +-- src/p_plats.cpp | 51 ++++------ src/p_slopes.cpp | 2 +- src/p_spec.cpp | 181 +++++++++++++++++++++------------ src/p_spec.h | 39 ++++++- src/p_teleport.cpp | 8 +- 18 files changed, 356 insertions(+), 331 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 039d261d7..5aae0d572 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -312,18 +312,24 @@ static int T_GetPlayerNum(const svalue_t &arg) // sectors directly by passing a negative value // //========================================================================== -int T_FindSectorFromTag(int tagnum,int startsector) +class FSSectorTagIterator : public FSectorTagIterator { - if (tagnum<=0) +public: + FSSectorTagIterator(int tag) + : FSectorTagIterator(tag) { - if (startsector<0) + if (tag < 0) { - if (tagnum==-32768) return 0; - if (-tagnum= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sector = §ors[i]; S_Sound(sector, CHAN_BODY, T_FindSound(stringvalue(t_argv[1])), 1.0f, ATTN_NORM); @@ -1595,7 +1602,8 @@ void FParser::SF_FloorHeight(void) // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { if (sectors[i].floordata) continue; // don't move floors that are active! @@ -1612,7 +1620,7 @@ void FParser::SF_FloorHeight(void) } else { - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); @@ -1671,7 +1679,8 @@ void FParser::SF_MoveFloor(void) // move all sectors with tag - while ((secnum = T_FindSectorFromTag(tagnum, secnum)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; // Don't start a second thinker on the same floor @@ -1733,7 +1742,8 @@ void FParser::SF_CeilingHeight(void) dest = fixedvalue(t_argv[1]); // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { if (sectors[i].ceilingdata) continue; // don't move ceilings that are active! @@ -1750,7 +1760,7 @@ void FParser::SF_CeilingHeight(void) } else { - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); @@ -1823,7 +1833,8 @@ void FParser::SF_MoveCeiling(void) silent=t_argc>4 ? intvalue(t_argv[4]):1; // move all sectors with tag - while ((secnum = T_FindSectorFromTag(tagnum, secnum)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; @@ -1851,7 +1862,7 @@ void FParser::SF_LightLevel(void) tagnum = intvalue(t_argv[0]); // argv is sector tag - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { @@ -1865,7 +1876,8 @@ void FParser::SF_LightLevel(void) int i = -1; // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].SetLightLevel(intvalue(t_argv[1])); } @@ -1984,7 +1996,8 @@ void FParser::SF_FadeLight(void) destlevel = intvalue(t_argv[1]); speed = t_argc>2 ? intvalue(t_argv[2]) : 1; - for (i = -1; (i = P_FindSectorFromTag(sectag,i)) >= 0;) + FSectorTagIterator it(sectag); + while ((i = it.Next()) >= 0) { if (!sectors[i].lightingdata) new DLightLevel(§ors[i],destlevel,speed); } @@ -2006,7 +2019,7 @@ void FParser::SF_FloorTexture(void) tagnum = intvalue(t_argv[0]); // argv is sector tag - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); return;} @@ -2019,7 +2032,8 @@ void FParser::SF_FloorTexture(void) FTextureID picnum = TexMan.GetTexture(t_argv[1].string, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].SetTexture(sector_t::floor, picnum); } @@ -2057,7 +2071,7 @@ void FParser::SF_SectorColormap(void) tagnum = intvalue(t_argv[0]); // argv is sector tag - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); return;} @@ -2068,7 +2082,8 @@ void FParser::SF_SectorColormap(void) { DWORD cm = R_ColormapNumForName(t_argv[1].value.s); - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].midmap=cm; sectors[i].heightsec=§ors[i]; @@ -2094,7 +2109,7 @@ void FParser::SF_CeilingTexture(void) tagnum = intvalue(t_argv[0]); // argv is sector tag - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); return;} @@ -2107,7 +2122,8 @@ void FParser::SF_CeilingTexture(void) FTextureID picnum = TexMan.GetTexture(t_argv[1].string, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].SetTexture(sector_t::ceiling, picnum); } @@ -4201,7 +4217,7 @@ void FParser::SF_SetColor(void) { tagnum = intvalue(t_argv[0]); - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { @@ -4222,7 +4238,8 @@ void FParser::SF_SetColor(void) else return; // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].ColorMap = GetSpecialLights (color, sectors[i].ColorMap->Fade, 0); } @@ -4314,7 +4331,7 @@ void FParser::SF_SectorType(void) tagnum = intvalue(t_argv[0]); // argv is sector tag - secnum = T_FindSectorFromTag(tagnum, -1); + secnum = T_FindFirstSectorFromTag(tagnum); if(secnum < 0) { script_error("sector not found with tagnum %i\n", tagnum); return;} @@ -4327,7 +4344,8 @@ void FParser::SF_SectorType(void) int spec = intvalue(t_argv[1]); // set all sectors with tag - while ((i = T_FindSectorFromTag(tagnum, i)) >= 0) + FSSectorTagIterator itr(tagnum); + while ((i = itr.Next()) >= 0) { sectors[i].special = spec; } @@ -4386,7 +4404,9 @@ void FParser::SF_ChangeTag() { if (CheckArgs(2)) { - for (int secnum = -1; (secnum = P_FindSectorFromTag (t_argv[0].value.i, secnum)) >= 0; ) + FSectorTagIterator it(t_argv[0].value.i); + int secnum; + while ((secnum = it.Next()) >= 0) { sectors[secnum].ClearTags(); sectors[secnum].SetMainTag(t_argv[1].value.i); diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 09c65d073..98911a418 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -452,9 +452,9 @@ bool DFraggleThinker::wait_finished(DRunningScript *script) case wt_tagwait: { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag(script->wait_data, secnum)) >= 0) + int secnum; + FSectorTagIterator itr(script->wait_data); + while ((secnum = itr.Next()) >= 0) { sector_t *sec = §ors[secnum]; if(sec->floordata || sec->ceilingdata || sec->lightingdata) diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index 616b87c9e..d62a2a07b 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -119,7 +119,9 @@ void ASkyCamCompat::BeginPlay () // Finally, skyboxify all tagged sectors // This involves changing their texture to the sky flat, because while // EE works with any texture for its skybox portals, ZDoom doesn't. - for (int secnum =-1; (secnum = P_FindSectorFromTag (skybox_id, secnum)) != -1; ) + FSectorTagIterator it(skybox_id); + int secnum; + while ((secnum = it.Next()) >= 0) { // plane: 0=floor, 1=ceiling, 2=both if (refline->args[2] == 1 || refline->args[2] == 2) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 58c2dbde7..5d63751c2 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -220,7 +220,8 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) int tag=line->args[0]; sector_t * sec = line->frontsector, * ss; - for (s=-1; (s = P_FindSectorFromTag(tag,s)) >= 0;) + FSectorTagIterator it(tag); + while ((s = it.Next()) >= 0) { ss=§ors[s]; diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 7f934e2f5..d3c26f47a 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -157,7 +157,9 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c } else { - for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; ) + FSectorTagIterator it(tag); + int sec; + while ((sec = it.Next()) >= 0) { for (int line = 0; line < sectors[sec].linecount; line ++) { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 3dd0cfef0..fbe5b0069 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1341,7 +1341,7 @@ DPlaneWatcher::DPlaneWatcher (AActor *it, line_t *line, int lineSide, bool ceili { int secnum; - secnum = P_FindSectorFromTag (tag, -1); + secnum = P_FindFirstSectorFromTag (tag); if (secnum >= 0) { secplane_t plane; @@ -3268,7 +3268,8 @@ void DLevelScript::ChangeFlat (int tag, int name, bool floorOrCeiling) flat = TexMan.GetTexture (flatname, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable); - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { int pos = floorOrCeiling? sector_t::ceiling : sector_t::floor; sectors[secnum].SetTexture(pos, flat); @@ -4839,10 +4840,10 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const return 0; // Not implemented yet case ACSF_GetSectorUDMFInt: - return GetUDMFInt(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1])); + return GetUDMFInt(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1])); case ACSF_GetSectorUDMFFixed: - return GetUDMFFixed(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1])); + return GetUDMFFixed(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1])); case ACSF_GetSideUDMFInt: return GetUDMFInt(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2])); @@ -5169,11 +5170,11 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const int space = args[2] < CHAN_FLOOR || args[2] > CHAN_INTERIOR ? CHAN_FULLHEIGHT : args[2]; if (seqname != NULL) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) + FSectorTagIterator it(args[0]); + int s; + while ((s = it.Next()) >= 0) { - SN_StartSequence(§ors[secnum], args[2], seqname, 0); + SN_StartSequence(§ors[s], args[2], seqname, 0); } } } @@ -5952,11 +5953,13 @@ int DLevelScript::RunScript () // Wait for tagged sector(s) to go inactive, then enter // state running { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (statedata, secnum)) >= 0) + int secnum; + FSectorTagIterator it(statedata); + while ((secnum = it.Next()) >= 0) + { if (sectors[secnum].floordata || sectors[secnum].ceilingdata) return resultValue; + } // If we got here, none of the tagged sectors were busy state = SCRIPT_Running; @@ -8518,7 +8521,7 @@ scriptwait: fixed_t z = 0; if (tag != 0) - secnum = P_FindSectorFromTag (tag, -1); + secnum = P_FindFirstSectorFromTag (tag); else secnum = int(P_PointInSector (x, y) - sectors); @@ -8540,7 +8543,7 @@ scriptwait: case PCD_GETSECTORLIGHTLEVEL: { - int secnum = P_FindSectorFromTag (STACK(1), -1); + int secnum = P_FindFirstSectorFromTag (STACK(1)); int z = -1; if (secnum >= 0) diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index d0c54761a..7efef80a5 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -510,9 +510,9 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, P_ActivateInStasisCeiling (tag); } - secnum = -1; // affects all sectors with the same tag as the linedef - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { rtn |= !!DCeiling::Create(§ors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush); } diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 844f23af9..49ed20f46 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -484,8 +484,8 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, else { // [RH] Remote door - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sec = §ors[secnum]; // if the ceiling is already moving, don't start the door action @@ -812,7 +812,8 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) return false; } - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sec = §ors[secnum]; if (sec->ceilingdata != NULL) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 231ccd5a3..97e23571b 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -290,28 +290,13 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, rtn = false; // check if a manual trigger; if so do just the sector on the backside - if (tag == 0) - { - if (!line || !(sec = line->backsector)) - return rtn; - secnum = (int)(sec-sectors); - goto manual_floor; - } - - secnum = -1; - while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator it(tag, line); + while ((secnum = it.Next()) >= 0) { sec = §ors[secnum]; - -manual_floor: // ALREADY MOVING? IF SO, KEEP GOING... if (sec->PlaneMoving(sector_t::floor)) { - // There was a test for 0/non-0 here, supposed to prevent 0-tags from executing "continue" and searching for unrelated sectors - // Unfortunately, the condition had been reversed, so that searches for tag-0 would continue, - // while numbered tags would abort (return false, even if some floors have been successfully triggered) - - // All occurences of the condition (faulty or not) have been replaced by a looping condition: Looping only occurs if we're looking for a non-0 tag. continue; } @@ -545,9 +530,9 @@ manual_floor: bool EV_FloorCrushStop (int tag) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + int secnum; + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sec = sectors + secnum; @@ -562,21 +547,6 @@ bool EV_FloorCrushStop (int tag) return true; } -//========================================================================== -// -// Linear tag search to emulate stair building from Doom.exe -// -//========================================================================== - -static int P_FindSectorFromTagLinear (int tag, int start) -{ - for (int i=start+1;i> FRACBITS; - int (* FindSector) (int tag, int start) = - (i_compatflags & COMPATF_STAIRINDEX)? P_FindSectorFromTagLinear : P_FindSectorFromTag; - // check if a manual trigger, if so do just the sector on the backside - if (tag == 0) - { - if (!line || !(sec = line->backsector)) - return rtn; - secnum = (int)(sec-sectors); - manual = true; - goto manual_stair; - } - + FSectorTagIterator itr(tag, line); // The compatibility mode doesn't work with a hashing algorithm. // It needs the original linear search method. This was broken in Boom. - - secnum = -1; - while ((secnum = FindSector (tag, secnum)) >= 0) + bool compatible = tag != 0 && (i_compatflags & COMPATF_STAIRINDEX); + while ((secnum = itr.NextCompat(compatible, secnum)) >= 0) { sec = §ors[secnum]; -manual_stair: // ALREADY MOVING? IF SO, KEEP GOING... //jff 2/26/98 add special lockout condition to wait for entire //staircase to build before retriggering if (sec->PlaneMoving(sector_t::floor) || sec->stairlock) { - if (!manual) - continue; - else - return rtn; + continue; } // new floor thinker @@ -781,14 +734,6 @@ manual_stair: // [RH] make sure the first sector doesn't point to a previous one, otherwise // it can infinite loop when the first sector stops moving. sectors[osecnum].prevsec = -1; - if (manual) - { - return rtn; - } - if (!(i_compatflags & COMPATF_STAIRINDEX)) - { - secnum = osecnum; //jff 3/4/98 restore loop index - } } return rtn; } @@ -811,21 +756,13 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) vertex_t* spot; fixed_t height; - secnum = -1; rtn = false; - if (tag == 0) - { - if (!line || !(s1 = line->backsector)) - return rtn; - goto manual_donut; - } - - while (tag && (secnum = P_FindSectorFromTag(tag,secnum)) >= 0) + FSectorTagIterator itr(tag, line); + while ((secnum = itr.Next()) >= 0) { s1 = §ors[secnum]; // s1 is pillar's sector -manual_donut: // ALREADY MOVING? IF SO, KEEP GOING... if (s1->PlaneMoving(sector_t::floor)) continue; // safe now, because we check that tag is non-0 in the looping condition [fdari] @@ -1042,19 +979,12 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, secnum = -1; rtn = false; - if (tag == 0) - { - if (!line || !(sec = line->backsector)) - return rtn; - goto manual_elevator; - } - + FSectorTagIterator itr(tag, line); // act on all sectors with the same tag as the triggering linedef - while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) // never loop for a non-0 tag (condition moved to beginning of loop) [FDARI] + while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; -manual_elevator: // If either floor or ceiling is already activated, skip it if (sec->PlaneMoving(sector_t::floor) || sec->ceilingdata) //jff 2/22/98 continue; // the loop used to break at the end if tag were 0, but would miss that step if "continue" occured [FDARI] @@ -1142,10 +1072,10 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag) sector_t *sec; sector_t *secm; - secnum = -1; rtn = false; // change all sectors with the same tag as the linedef - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sec = §ors[secnum]; @@ -1374,20 +1304,12 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset, bool retCode; retCode = false; - sectorIndex = -1; - if (tag == 0) - { - if (!line || !(sector = line->backsector)) - return retCode; - goto manual_waggle; - } + FSectorTagIterator itr(tag, line); - - while (tag && (sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + while ((sectorIndex = itr.Next()) >= 0) { sector = §ors[sectorIndex]; -manual_waggle: if ((!ceiling && sector->PlaneMoving(sector_t::floor)) || (ceiling && sector->PlaneMoving(sector_t::ceiling))) { // Already busy with another thinker diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 8743ae21b..b4bfa1669 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -189,9 +189,8 @@ DFlicker::DFlicker (sector_t *sector, int upper, int lower) void EV_StartLightFlickering (int tag, int upper, int lower) { int secnum; - - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { new DFlicker (§ors[secnum], upper, lower); } @@ -359,9 +358,8 @@ DStrobe::DStrobe (sector_t *sector, int utics, int ltics, bool inSync) void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics) { int secnum; - - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) @@ -374,9 +372,8 @@ void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics) void EV_StartLightStrobing (int tag, int utics, int ltics) { int secnum; - - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) @@ -396,16 +393,14 @@ void EV_StartLightStrobing (int tag, int utics, int ltics) void EV_TurnTagLightsOff (int tag) { - int i; int secnum; - - // [RH] Don't do a linear search - for (secnum = -1; (secnum = P_FindSectorFromTag (tag, secnum)) >= 0; ) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sector = sectors + secnum; int min = sector->lightlevel; - for (i = 0; i < sector->linecount; i++) + for (int i = 0; i < sector->linecount; i++) { sector_t *tsec = getNextSector (sector->lines[i],sector); if (!tsec) @@ -427,10 +422,9 @@ void EV_TurnTagLightsOff (int tag) void EV_LightTurnOn (int tag, int bright) { - int secnum = -1; - - // [RH] Don't do a linear search - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + int secnum; + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sector = sectors + secnum; int tbright = bright; //jff 5/17/98 search for maximum PER sector @@ -480,15 +474,14 @@ void EV_LightTurnOn (int tag, int bright) void EV_LightTurnOnPartway (int tag, fixed_t frac) { - int i; - frac = clamp (frac, 0, FRACUNIT); // Search all sectors for ones with same tag as activating line - i = -1; - while ((i = P_FindSectorFromTag (tag, i)) >= 0) + int secnum; + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { - sector_t *temp, *sector = sectors + i; + sector_t *temp, *sector = §ors[secnum]; int j, bright = 0, min = sector->lightlevel; for (j = 0; j < sector->linecount; ++j) @@ -520,9 +513,9 @@ void EV_LightTurnOnPartway (int tag, fixed_t frac) void EV_LightChange (int tag, int value) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + int secnum; + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sectors[secnum].SetLightLevel(sectors[secnum].lightlevel + value); } @@ -681,8 +674,8 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics) lower = temp; } - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) @@ -701,9 +694,8 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics) void EV_StartLightFading (int tag, int value, int tics) { int secnum; - - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) + FSectorTagIterator it(tag); + while ((secnum = it.Next()) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index acf1d6906..a2587f745 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -316,7 +316,9 @@ bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype) if (movetype > 0) { - for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; ) + int sec; + FSectorTagIterator itr(tag); + while ((sec = itr.Next()) >= 0) { // Don't attach to self! if (control != §ors[sec]) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 76f7a0371..3a8ebf541 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1914,9 +1914,9 @@ FUNC(LS_Sector_ChangeSound) if (!arg0) return false; - secNum = -1; rtn = false; - while ((secNum = P_FindSectorFromTag (arg0, secNum)) >= 0) + FSectorTagIterator itr(arg0); + while ((secNum = itr.Next()) >= 0) { sectors[secNum].seqType = arg1; rtn = true; @@ -1933,9 +1933,9 @@ FUNC(LS_Sector_ChangeFlags) if (!arg0) return false; - secNum = -1; rtn = false; - while ((secNum = P_FindSectorFromTag (arg0, secNum)) >= 0) + FSectorTagIterator itr(arg0); + while ((secNum = itr.Next()) >= 0) { sectors[secNum].Flags = (sectors[secNum].Flags | arg1) & ~arg2; rtn = true; @@ -1969,10 +1969,11 @@ void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type) } size_t numcollected = Collection.Size (); - int secnum = -1; + int secnum; // Now create pushers for any sectors that don't already have them. - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag); + while ((secnum = itr.Next()) >= 0) { unsigned int i; for (i = 0; i < numcollected; i++) @@ -2020,9 +2021,9 @@ FUNC(LS_Sector_SetTranslucent) { if (arg0 != 0) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + int secnum; + FSectorTagIterator itr(arg0); + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetAlpha(arg1, Scale(arg2, OPAQUE, 255)); sectors[secnum].ChangeFlags(arg1, ~PLANEF_ADDITIVE, arg3? PLANEF_ADDITIVE:0); @@ -2037,7 +2038,7 @@ FUNC(LS_Sector_SetLink) { if (arg0 != 0) // control tag == 0 is for static initialization and must not be handled here { - int control = P_FindSectorFromTag(arg0, -1); + int control = P_FindFirstSectorFromTag(arg0); if (control >= 0) { return P_AddSectorLinks(§ors[control], arg1, arg2, arg3); @@ -2181,7 +2182,8 @@ static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed } // Need to create scrollers for the sector(s) - for (i = -1; (i = P_FindSectorFromTag (tag, i)) >= 0; ) + FSectorTagIterator itr(tag); + while ((i = itr.Next()) >= 0) { new DScroller (type, dx, dy, -1, i, 0); } @@ -2240,8 +2242,10 @@ FUNC(LS_Sector_SetDamage) // problems by adding an unwanted constructor. // Since it doesn't really matter whether the type is translated // here or in P_PlayerInSpecialSector I think it's the best solution. - int secnum = -1; - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) { + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) + { sectors[secnum].damage = arg1; sectors[secnum].mod = arg2; } @@ -2251,14 +2255,15 @@ FUNC(LS_Sector_SetDamage) FUNC(LS_Sector_SetGravity) // Sector_SetGravity (tag, intpart, fracpart) { - int secnum = -1; float gravity; if (arg2 > 99) arg2 = 99; gravity = (float)arg1 + (float)arg2 * 0.01f; - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) sectors[secnum].gravity = gravity; return true; @@ -2267,9 +2272,9 @@ FUNC(LS_Sector_SetGravity) FUNC(LS_Sector_SetColor) // Sector_SetColor (tag, r, g, b, desaturate) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetColor(arg1, arg2, arg3, arg4); } @@ -2280,9 +2285,9 @@ FUNC(LS_Sector_SetColor) FUNC(LS_Sector_SetFade) // Sector_SetFade (tag, r, g, b) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetFade(arg1, arg2, arg3); } @@ -2292,11 +2297,12 @@ FUNC(LS_Sector_SetFade) FUNC(LS_Sector_SetCeilingPanning) // Sector_SetCeilingPanning (tag, x-int, x-frac, y-int, y-frac) { - int secnum = -1; fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetXOffset(sector_t::ceiling, xofs); sectors[secnum].SetYOffset(sector_t::ceiling, yofs); @@ -2307,11 +2313,12 @@ FUNC(LS_Sector_SetCeilingPanning) FUNC(LS_Sector_SetFloorPanning) // Sector_SetFloorPanning (tag, x-int, x-frac, y-int, y-frac) { - int secnum = -1; fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetXOffset(sector_t::floor, xofs); sectors[secnum].SetYOffset(sector_t::floor, yofs); @@ -2322,7 +2329,6 @@ FUNC(LS_Sector_SetFloorPanning) FUNC(LS_Sector_SetFloorScale) // Sector_SetFloorScale (tag, x-int, x-frac, y-int, y-frac) { - int secnum = -1; fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); @@ -2331,7 +2337,9 @@ FUNC(LS_Sector_SetFloorScale) if (yscale) yscale = FixedDiv (FRACUNIT, yscale); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { if (xscale) sectors[secnum].SetXScale(sector_t::floor, xscale); @@ -2344,7 +2352,6 @@ FUNC(LS_Sector_SetFloorScale) FUNC(LS_Sector_SetCeilingScale) // Sector_SetCeilingScale (tag, x-int, x-frac, y-int, y-frac) { - int secnum = -1; fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); @@ -2353,7 +2360,9 @@ FUNC(LS_Sector_SetCeilingScale) if (yscale) yscale = FixedDiv (FRACUNIT, yscale); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { if (xscale) sectors[secnum].SetXScale(sector_t::ceiling, xscale); @@ -2366,14 +2375,14 @@ FUNC(LS_Sector_SetCeilingScale) FUNC(LS_Sector_SetFloorScale2) // Sector_SetFloorScale2 (tag, x-factor, y-factor) { - int secnum = -1; - if (arg1) arg1 = FixedDiv (FRACUNIT, arg1); if (arg2) arg2 = FixedDiv (FRACUNIT, arg2); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { if (arg1) sectors[secnum].SetXScale(sector_t::floor, arg1); @@ -2386,14 +2395,14 @@ FUNC(LS_Sector_SetFloorScale2) FUNC(LS_Sector_SetCeilingScale2) // Sector_SetFloorScale2 (tag, x-factor, y-factor) { - int secnum = -1; - if (arg1) arg1 = FixedDiv (FRACUNIT, arg1); if (arg2) arg2 = FixedDiv (FRACUNIT, arg2); - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { if (arg1) sectors[secnum].SetXScale(sector_t::ceiling, arg1); @@ -2406,11 +2415,12 @@ FUNC(LS_Sector_SetCeilingScale2) FUNC(LS_Sector_SetRotation) // Sector_SetRotation (tag, floor-angle, ceiling-angle) { - int secnum = -1; angle_t ceiling = arg2 * ANGLE_1; angle_t floor = arg1 * ANGLE_1; - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sectors[secnum].SetAngle(sector_t::floor, floor); sectors[secnum].SetAngle(sector_t::ceiling, ceiling); @@ -2997,10 +3007,11 @@ FUNC(LS_ForceField) FUNC(LS_ClearForceField) // ClearForceField (tag) { - int secnum = -1; bool rtn = false; - while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) + FSectorTagIterator itr(arg0); + int secnum; + while ((secnum = itr.Next()) >= 0) { sector_t *sec = §ors[secnum]; rtn = true; diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index 809542949..98169c345 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -220,16 +220,8 @@ bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, bool rtn = false; // check if a manual trigger; if so do just the sector on the backside - if (tag == 0) - { - if (!line || !(sec = line->backsector)) - return rtn; - secnum = (int)(sec-sectors); - goto manual_pillar; - } - - secnum = -1; - while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag, line); + while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index d87c30991..7600637b2 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -233,42 +233,33 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, fixed_t newheight = 0; vertex_t *spot; + if (tag != 0) + { + // Activate all plats that are in_stasis + switch (type) + { + case DPlat::platToggle: + rtn = true; + case DPlat::platPerpetualRaise: + P_ActivateInStasis (tag); + break; + + default: + break; + } + } + + // [RH] If tag is zero, use the sector on the back side // of the activating line (if any). - if (!tag) - { - if (!line || !(sec = line->backsector)) - return false; - secnum = (int)(sec - sectors); - manual = true; - goto manual_plat; - } - - // Activate all plats that are in_stasis - switch (type) - { - case DPlat::platToggle: - rtn = true; - case DPlat::platPerpetualRaise: - P_ActivateInStasis (tag); - break; - - default: - break; - } - - secnum = -1; - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag, line); + while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; -manual_plat: if (sec->PlaneMoving(sector_t::floor)) { - if (!manual) - continue; - else - return false; + continue; } // Find lowest & highest floors around sector @@ -406,8 +397,6 @@ manual_plat: default: break; } - if (manual) - return rtn; } return rtn; } diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 41f7a1837..ab0ea6592 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -123,7 +123,7 @@ static void P_CopyPlane (int tag, sector_t *dest, bool copyCeil) int secnum; size_t planeofs; - secnum = P_FindSectorFromTag (tag, -1); + secnum = P_FindFirstSectorFromTag (tag); if (secnum == -1) { return; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 676191555..0fe88e112 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -195,15 +195,36 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info) // Find the next sector with a specified tag. // Rewritten by Lee Killough to use chained hashing to improve speed -int P_FindSectorFromTag (int tag, int start) +int FSectorTagIterator::Next() { - start = start >= 0 ? sectors[start].nexttag : - sectors[(unsigned) tag % (unsigned) numsectors].firsttag; - while (start >= 0 && sectors[start].tag != tag) + int ret; + if (searchtag == INT_MIN) + { + ret = start; + start = -1; + } + else + { + while (start != -1 && sectors[start].tag != searchtag) start = sectors[start].nexttag; + if (start == -1) return -1; + ret = start; start = sectors[start].nexttag; - return start; + } + return ret; } +int FSectorTagIterator::NextCompat(bool compat, int start) +{ + if (!compat) return Next(); + + for (int i = start + 1; i < numsectors; i++) + { + if (sectors[i].HasTag(searchtag)) return i; + } + return -1; +} + + // killough 4/16/98: Same thing, only for linedefs int P_FindLineFromID (int id, int start) @@ -266,7 +287,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) special && // not for lines without a special line->args[0] == line->id && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0] line->args[0] && // only if there's a tag (which is stored in the first arg) - P_FindSectorFromTag (line->args[0], -1) == -1) // only if no sector is tagged to this linedef + P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef { P_ChangeSwitchTexture (line->sidedef[0], repeat, special); line->special = 0; @@ -657,9 +678,9 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type, void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags) { - int secnum = -1; - - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag); + int secnum; + while ((secnum = itr.Next()) >= 0) { AActor *actor, *next; sector_t *sec = §ors[secnum]; @@ -884,12 +905,14 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor) if (copyFloor) { - for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) + FSectorTagIterator itr(target); + while ((secnum = itr.Next()) >= 0) sectors[secnum].ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); } else { - for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) + FSectorTagIterator itr(target); + while ((secnum = itr.Next()) >= 0) sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); } ChangeStatNum (STAT_LIGHTTRANSFER); @@ -912,12 +935,14 @@ void DLightTransfer::DoTransfer (int level, int target, bool floor) if (floor) { - for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) + FSectorTagIterator itr(target); + while ((secnum = itr.Next()) >= 0) sectors[secnum].SetPlaneLight(sector_t::floor, level); } else { - for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; ) + FSectorTagIterator itr(target); + while ((secnum = itr.Next()) >= 0) sectors[secnum].SetPlaneLight(sector_t::ceiling, level); } } @@ -1173,7 +1198,9 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) reference->flags |= MF_JUSTATTACKED; anchor->flags |= MF_JUSTATTACKED; - for (int s=-1; (s = P_FindSectorFromTag(sectortag,s)) >= 0;) + int s; + FSectorTagIterator itr(sectortag); + while ((s = itr.Next()) >= 0) { SetPortal(§ors[s], plane, reference, alpha); } @@ -1193,7 +1220,8 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) } else { - for (int s=-1; (s = P_FindSectorFromTag(lines[j].args[0],s)) >= 0;) + FSectorTagIterator itr(lines[j].args[0]); + while ((s = itr.Next()) >= 0) { SetPortal(§ors[s], plane, reference, alpha); } @@ -1374,38 +1402,41 @@ void P_SpawnSpecials (void) // killough 3/7/98: // support for drawn heights coming from different sector case Transfer_Heights: - sec = lines[i].frontsector; - if (lines[i].args[1] & 2) { - sec->MoreFlags |= SECF_FAKEFLOORONLY; + sec = lines[i].frontsector; + if (lines[i].args[1] & 2) + { + sec->MoreFlags |= SECF_FAKEFLOORONLY; + } + if (lines[i].args[1] & 4) + { + sec->MoreFlags |= SECF_CLIPFAKEPLANES; + } + if (lines[i].args[1] & 8) + { + sec->MoreFlags |= SECF_UNDERWATER; + } + else if (forcewater) + { + sec->MoreFlags |= SECF_FORCEDUNDERWATER; + } + if (lines[i].args[1] & 16) + { + sec->MoreFlags |= SECF_IGNOREHEIGHTSEC; + } + if (lines[i].args[1] & 32) + { + sec->MoreFlags |= SECF_NOFAKELIGHT; + } + FSectorTagIterator itr(lines[i].args[0]); + while ((s = itr.Next()) >= 0) + { + sectors[s].heightsec = sec; + sec->e->FakeFloor.Sectors.Push(§ors[s]); + sectors[s].AdjustFloorClip(); + } + break; } - if (lines[i].args[1] & 4) - { - sec->MoreFlags |= SECF_CLIPFAKEPLANES; - } - if (lines[i].args[1] & 8) - { - sec->MoreFlags |= SECF_UNDERWATER; - } - else if (forcewater) - { - sec->MoreFlags |= SECF_FORCEDUNDERWATER; - } - if (lines[i].args[1] & 16) - { - sec->MoreFlags |= SECF_IGNOREHEIGHTSEC; - } - if (lines[i].args[1] & 32) - { - sec->MoreFlags |= SECF_NOFAKELIGHT; - } - for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;) - { - sectors[s].heightsec = sec; - sec->e->FakeFloor.Sectors.Push(§ors[s]); - sectors[s].AdjustFloorClip(); - } - break; // killough 3/16/98: Add support for setting // floor lighting independently (e.g. lava) @@ -1458,9 +1489,10 @@ void P_SpawnSpecials (void) { case Init_Gravity: { - float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f); - for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;) - sectors[s].gravity = grav; + float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f); + FSectorTagIterator itr(lines[i].args[0]); + while ((s = itr.Next()) >= 0) + sectors[s].gravity = grav; } break; @@ -1470,7 +1502,8 @@ void P_SpawnSpecials (void) case Init_Damage: { int damage = P_AproxDistance (lines[i].dx, lines[i].dy) >> FRACBITS; - for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;) + FSectorTagIterator itr(lines[i].args[0]); + while ((s = itr.Next()) >= 0) { sectors[s].damage = damage; sectors[s].mod = 0;//MOD_UNKNOWN; @@ -1493,9 +1526,12 @@ void P_SpawnSpecials (void) // or ceiling texture, to distinguish floor and ceiling sky. case Init_TransferSky: - for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;) - sectors[s].sky = (i+1) | PL_SKYFLAT; - break; + { + FSectorTagIterator itr(lines[i].args[0]); + while ((s = itr.Next()) >= 0) + sectors[s].sky = (i + 1) | PL_SKYFLAT; + break; + } } break; } @@ -1756,7 +1792,7 @@ static void P_SpawnScrollers(void) if (lines[i].special == Sector_CopyScroller) { // don't allow copying the scroller if the sector has the same tag as it would just duplicate it. - if (lines[i].args[0] != lines[i].frontsector->tag) + if (lines[i].frontsector->HasTag(lines[i].args[0])) { copyscrollers.Push(i); } @@ -1832,25 +1868,29 @@ static void P_SpawnScrollers(void) register int s; case Scroll_Ceiling: - for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + { + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) { - new DScroller (DScroller::sc_ceiling, -dx, dy, control, s, accel); + new DScroller(DScroller::sc_ceiling, -dx, dy, control, s, accel); } - for(unsigned j = 0;j < copyscrollers.Size(); j++) + for (unsigned j = 0; j < copyscrollers.Size(); j++) { line_t *line = &lines[copyscrollers[j]]; if (line->args[0] == l->args[0] && (line->args[1] & 1)) { - new DScroller (DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector-sectors), accel); + new DScroller(DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector - sectors), accel); } } break; + } case Scroll_Floor: if (l->args[2] != 1) { // scroll the floor texture - for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) { new DScroller (DScroller::sc_floor, -dx, dy, control, s, accel); } @@ -1867,7 +1907,8 @@ static void P_SpawnScrollers(void) if (l->args[2] > 0) { // carry objects on the floor - for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) { new DScroller (DScroller::sc_carry, dx, dy, control, s, accel); } @@ -2041,7 +2082,8 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) // higher friction value actually means 'less friction'. movefactor = FrictionToMoveFactor(friction); - for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; ) + FSectorTagIterator itr(tag); + while ((s = itr.Next()) >= 0) { // killough 8/28/98: // @@ -2153,7 +2195,7 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, int DPusher::CheckForSectorMatch (EPusher type, int tag) { - if (m_Type == type && sectors[m_Affectee].tag == tag) + if (m_Type == type && sectors[m_Affectee].HasTag(tag)) return m_Affectee; else return -1; @@ -2356,20 +2398,27 @@ static void P_SpawnPushers () switch (l->special) { case Sector_SetWind: // wind - for (s = -1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0 ; ) - new DPusher (DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); + { + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) + new DPusher(DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); l->special = 0; break; + } case Sector_SetCurrent: // current - for (s = -1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0 ; ) - new DPusher (DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); + { + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) + new DPusher(DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s); l->special = 0; break; + } case PointPush_SetForce: // push/pull if (l->args[0]) { // [RH] Find thing by sector - for (s = -1; (s = P_FindSectorFromTag (l->args[0], s)) >= 0 ; ) + FSectorTagIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) { AActor *thing = P_GetPushThing (s); if (thing) { // No MT_P* means no effect diff --git a/src/p_spec.h b/src/p_spec.h index 5b4f0ba99..b538ab7d5 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -242,8 +242,45 @@ inline sector_t *getNextSector (line_t *line, const sector_t *sec) line->frontsector; } +class FSectorTagIterator +{ +protected: + int searchtag; + int start; + +public: + FSectorTagIterator(int tag) + { + searchtag = tag; + start = sectors[(unsigned)tag % (unsigned)numsectors].firsttag; + } + + // Special constructor for actions that treat tag 0 as 'back of activation line' + FSectorTagIterator(int tag, line_t *line) + { + if (tag == 0) + { + searchtag = INT_MIN; + start = (line == NULL || line->backsector == NULL)? -1 : (int)(line->backsector - sectors); + } + else + { + searchtag = tag; + start = sectors[(unsigned)tag % (unsigned)numsectors].firsttag; + } + } + + int Next(); + int NextCompat(bool compat, int secnum); +}; + + +inline int P_FindFirstSectorFromTag(int tag) +{ + FSectorTagIterator it(tag); + return it.Next(); +} -int P_FindSectorFromTag (int tag, int start); int P_FindLineFromID (int id, int start); diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index e30457b15..921c11ff5 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -300,9 +300,10 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom) if (tag != 0) { - int secnum = -1; + int secnum; - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag); + while ((secnum = itr.Next()) >= 0) { // Scanning the snext links of things in the sector will not work, because // TeleportDests have MF_NOSECTOR set. So you have to search *everything*. @@ -726,7 +727,8 @@ bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int gro int secnum; secnum = -1; - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + FSectorTagIterator itr(tag); + while ((secnum = itr.Next()) >= 0) { msecnode_t *node; const sector_t * const sec = §ors[secnum]; From 47543bb7669b6791a98b6f195fd98afa1d539829 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Apr 2015 00:47:06 +0200 Subject: [PATCH 45/58] - while we're at it, let's also wrap line ID searches in an iterator class so that we can do multiple IDs per line later as well. --- src/fragglescript/t_func.cpp | 23 +++++++++++++-------- src/p_3dmidtex.cpp | 4 +++- src/p_acs.cpp | 28 ++++++++++++++----------- src/p_linkedsectors.cpp | 4 +++- src/p_lnspec.cpp | 40 +++++++++++++++++++++--------------- src/p_pillar.cpp | 1 - src/p_slopes.cpp | 5 +++-- src/p_spec.cpp | 29 +++++++++++++++----------- src/p_spec.h | 23 +++++++++++++++++++-- src/p_teleport.cpp | 3 ++- 10 files changed, 103 insertions(+), 57 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 5aae0d572..7650b174e 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -2297,9 +2297,11 @@ void FParser::SF_SetLineBlocking(void) { blocking=blocks[blocking]; int tag=intvalue(t_argv[0]); - for (int i = -1; (i = P_FindLineFromID(tag, i)) >= 0;) + FLineIdIterator itr(tag); + int i; + while ((i = itr.Next()) >= 0) { - lines[i].flags = (lines[i].flags & ~(ML_BLOCKING|ML_BLOCKEVERYTHING)) | blocking; + lines[i].flags = (lines[i].flags & ~(ML_BLOCKING | ML_BLOCKEVERYTHING)) | blocking; } } } @@ -2318,7 +2320,9 @@ void FParser::SF_SetLineMonsterBlocking(void) int blocking = intvalue(t_argv[1]) ? ML_BLOCKMONSTERS : 0; int tag=intvalue(t_argv[0]); - for (int i = -1; (i = P_FindLineFromID(tag, i)) >= 0;) + FLineIdIterator itr(tag); + int i; + while ((i = itr.Next()) >= 0) { lines[i].flags = (lines[i].flags & ~ML_BLOCKMONSTERS) | blocking; } @@ -2373,12 +2377,13 @@ void FParser::SF_SetLineTexture(void) texture = stringvalue(t_argv[3]); texturenum = TexMan.GetTexture(texture, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); - for (i = -1; (i = P_FindLineFromID(tag, i)) >= 0;) + FLineIdIterator itr(tag); + while ((i = itr.Next()) >= 0) { // bad sidedef, Hexen just SEGV'd here! - if(lines[i].sidedef[side] != NULL) + if (lines[i].sidedef[side] != NULL) { - if (position >=0 && position <=2) + if (position >= 0 && position <= 2) { lines[i].sidedef[side]->SetTexture(position, texturenum); } @@ -2392,7 +2397,8 @@ void FParser::SF_SetLineTexture(void) int sections = intvalue(t_argv[3]); // set all sectors with tag - for (i = -1; (i = P_FindLineFromID(tag, i)) >= 0;) + FLineIdIterator itr(tag); + while ((i = itr.Next()) >= 0) { side_t *sided = lines[i].sidedef[side]; if(sided != NULL) @@ -4373,7 +4379,8 @@ void FParser::SF_SetLineTrigger() id=intvalue(t_argv[0]); spec=intvalue(t_argv[1]); if (t_argc>2) tag=intvalue(t_argv[2]); - for (i = -1; (i = P_FindLineFromID (id, i)) >= 0; ) + FLineIdIterator itr(id); + while ((i = itr.Next()) >= 0) { if (t_argc==2) tag=lines[i].id; maplinedef_t mld; diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index d3c26f47a..4939f55dc 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -143,7 +143,9 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c if (tag == 0) { - for(int line = -1; (line = P_FindLineFromID(lineid,line)) >= 0; ) + FLineIdIterator itr(lineid); + int line; + while ((line = itr.Next()) >= 0) { line_t *ln = &lines[line]; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fbe5b0069..9ea8624f6 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3300,7 +3300,8 @@ void DLevelScript::SetLineTexture (int lineid, int side, int position, int name) texture = TexMan.GetTexture (texname, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); - while ((linenum = P_FindLineFromID (lineid, linenum)) >= 0) + FLineIdIterator itr(lineid); + while ((linenum = itr.Next()) >= 0) { side_t *sidedef; @@ -4458,7 +4459,7 @@ int DLevelScript::SideFromID(int id, int side) } else { - int line = P_FindLineFromID(id, -1); + int line = P_FindFirstLineFromID(id); if (line == -1) return -1; if (lines[line].sidedef[side] == NULL) return -1; return lines[line].sidedef[side]->Index; @@ -4474,7 +4475,7 @@ int DLevelScript::LineFromID(int id) } else { - return P_FindLineFromID(id, -1); + return P_FindFirstLineFromID(id); } } @@ -5693,9 +5694,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_SetLineActivation: if (argCount >= 2) { - int line = -1; - - while ((line = P_FindLineFromID(args[0], line)) >= 0) + int line; + FLineIdIterator itr(args[0]); + while ((line = itr.Next()) >= 0) { lines[line].activation = args[1]; } @@ -5705,7 +5706,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_GetLineActivation: if (argCount > 0) { - int line = P_FindLineFromID(args[0], -1); + int line = P_FindFirstLineFromID(args[0]); return line >= 0 ? lines[line].activation : 0; } break; @@ -7999,9 +8000,10 @@ scriptwait: case PCD_SETLINEBLOCKING: { - int line = -1; + int line; - while ((line = P_FindLineFromID (STACK(2), line)) >= 0) + FLineIdIterator itr(STACK(2)); + while ((line = itr.Next()) >= 0) { switch (STACK(1)) { @@ -8034,9 +8036,10 @@ scriptwait: case PCD_SETLINEMONSTERBLOCKING: { - int line = -1; + int line; - while ((line = P_FindLineFromID (STACK(2), line)) >= 0) + FLineIdIterator itr(STACK(2)); + while ((line = itr.Next()) >= 0) { if (STACK(1)) lines[line].flags |= ML_BLOCKMONSTERS; @@ -8061,7 +8064,8 @@ scriptwait: arg0 = -FName(FBehavior::StaticLookupString(arg0)); } - while ((linenum = P_FindLineFromID (STACK(7), linenum)) >= 0) + FLineIdIterator itr(STACK(7)); + while ((linenum = itr.Next()) >= 0) { line_t *line = &lines[linenum]; line->special = specnum; diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index a2587f745..8f78aadda 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -348,7 +348,9 @@ void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling) { extsector_t::linked::plane &scrollplane = ceiling? control->e->Linked.Ceiling : control->e->Linked.Floor; - for(int line = -1; (line = P_FindLineFromID(id, line)) >= 0; ) + FLineIdIterator itr(id); + int line; + while ((line = itr.Next()) >= 0) { line_t *ld = &lines[line]; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 3a8ebf541..16d0402f3 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2093,10 +2093,11 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int } size_t numcollected = Collection.Size (); - int linenum = -1; + int linenum; // Now create scrollers for any walls that don't already have them. - while ((linenum = P_FindLineFromID (id, linenum)) >= 0) + FLineIdIterator itr(id); + while ((linenum = itr.Next()) >= 0) { if (lines[linenum].sidedef[sidechoice] != NULL) { @@ -2431,30 +2432,28 @@ FUNC(LS_Sector_SetRotation) FUNC(LS_Line_AlignCeiling) // Line_AlignCeiling (lineid, side) { - int line = P_FindLineFromID (arg0, -1); bool ret = 0; - if (line < 0) - I_Error ("Sector_AlignCeiling: Lineid %d is undefined", arg0); - do + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) { ret |= P_AlignFlat (line, !!arg1, 1); - } while ( (line = P_FindLineFromID (arg0, line)) >= 0); + } return ret; } FUNC(LS_Line_AlignFloor) // Line_AlignFloor (lineid, side) { - int line = P_FindLineFromID (arg0, -1); bool ret = 0; - if (line < 0) - I_Error ("Sector_AlignFloor: Lineid %d is undefined", arg0); - do + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) { ret |= P_AlignFlat (line, !!arg1, 0); - } while ( (line = P_FindLineFromID (arg0, line)) >= 0); + } return ret; } @@ -2466,7 +2465,9 @@ FUNC(LS_Line_SetTextureOffset) if (arg0 == 0 || arg3 < 0 || arg3 > 1) return false; - for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; ) + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) { side_t *side = lines[line].sidedef[arg3]; if (side != NULL) @@ -2517,7 +2518,9 @@ FUNC(LS_Line_SetTextureScale) if (arg0 == 0 || arg3 < 0 || arg3 > 1) return false; - for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; ) + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) { side_t *side = lines[line].sidedef[arg3]; if (side != NULL) @@ -2588,7 +2591,9 @@ FUNC(LS_Line_SetBlocking) if (arg2 & 1) clearflags |= flagtrans[i]; } - for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; ) + FLineIdIterator itr(arg0); + int line; + while ((line = itr.Next()) >= 0) { lines[line].flags = (lines[line].flags & ~clearflags) | setflags; } @@ -2881,8 +2886,9 @@ FUNC(LS_SetPlayerProperty) FUNC(LS_TranslucentLine) // TranslucentLine (id, amount, type) { - int linenum = -1; - while ((linenum = P_FindLineFromID (arg0, linenum)) >= 0) + FLineIdIterator itr(arg0); + int linenum; + while ((linenum = itr.Next()) >= 0) { lines[linenum].Alpha = Scale(clamp(arg1, 0, 255), FRACUNIT, 255); if (arg2 == 0) diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index 98169c345..884218bee 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -225,7 +225,6 @@ bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, { sec = §ors[secnum]; -manual_pillar: if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling)) continue; diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index ab0ea6592..c0b9b5ef0 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -45,9 +45,10 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, bool slopeCeil) { - int linenum = -1; + int linenum; - while ((linenum = P_FindLineFromID (lineid, linenum)) != -1) + FLineIdIterator itr(lineid); + while ((linenum = itr.Next()) >= 0) { const line_t *line = &lines[linenum]; sector_t *sec; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 0fe88e112..c072122b8 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -227,18 +227,16 @@ int FSectorTagIterator::NextCompat(bool compat, int start) // killough 4/16/98: Same thing, only for linedefs -int P_FindLineFromID (int id, int start) +int FLineIdIterator::Next() { - start = start >= 0 ? lines[start].nextid : - lines[(unsigned) id % (unsigned) numlines].firstid; - while (start >= 0 && lines[start].id != id) - start = lines[start].nextid; - return start; + while (start != -1 && lines[start].id != searchtag) start = lines[start].nextid; + if (start == -1) return -1; + int ret = start; + start = lines[start].nextid; + return ret; } - - //============================================================================ // // P_ActivateLine @@ -1010,7 +1008,8 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags wallflags = WALLF_ABSLIGHTING | WALLF_NOFAKECONTRAST; } - for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; ) + FLineIdIterator itr(target); + while ((linenum = itr.Next()) >= 0) { if (flags & WLF_SIDE1 && lines[linenum].sidedef[0] != NULL) { @@ -1040,7 +1039,8 @@ void DWallLightTransfer::DoTransfer (short lightlevel, int target, BYTE flags) { int linenum; - for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; ) + FLineIdIterator itr(target); + while ((linenum = itr.Next()) >= 0) { line_t *line = &lines[linenum]; @@ -1927,10 +1927,15 @@ static void P_SpawnScrollers(void) // killough 3/1/98: scroll wall according to linedef // (same direction and speed as scrolling floors) case Scroll_Texture_Model: - for (s=-1; (s = P_FindLineFromID (l->args[0],s)) >= 0;) + { + FLineIdIterator itr(l->args[0]); + while ((s = itr.Next()) >= 0) + { if (s != i) - new DScroller (dx, dy, lines+s, control, accel); + new DScroller(dx, dy, lines + s, control, accel); + } break; + } case Scroll_Texture_Offsets: // killough 3/2/98: scroll according to sidedef offsets diff --git a/src/p_spec.h b/src/p_spec.h index b538ab7d5..45eaf7e41 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -274,6 +274,22 @@ public: int NextCompat(bool compat, int secnum); }; +class FLineIdIterator +{ +protected: + int searchtag; + int start; + +public: + FLineIdIterator(int id) + { + searchtag = id; + start = lines[(unsigned) id % (unsigned) numlines].firstid; + } + + int Next(); +}; + inline int P_FindFirstSectorFromTag(int tag) { @@ -281,8 +297,11 @@ inline int P_FindFirstSectorFromTag(int tag) return it.Next(); } -int P_FindLineFromID (int id, int start); - +inline int P_FindFirstLineFromID(int tag) +{ + FLineIdIterator it(tag); + return it.Next(); +} // // P_LIGHTS diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 921c11ff5..de16a57fa 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -424,7 +424,8 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO if (side || thing->flags2 & MF2_NOTELEPORT || !line || line->sidedef[1] == NULL) return false; - for (i = -1; (i = P_FindLineFromID (id, i)) >= 0; ) + FLineIdIterator itr(id); + while ((i = itr.Next()) >= 0) { if (line-lines == i) continue; From 006868c072f6bbaf995078ec4c8718aab396afd6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Apr 2015 18:00:20 -0500 Subject: [PATCH 46/58] Miscellaneous warning fixes --- src/gameconfigfile.cpp | 2 +- src/p_user.cpp | 10 +++++----- src/w_wad.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index c4f970db9..30dc2276d 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -429,7 +429,7 @@ void FGameConfigFile::DoKeySetup(const char *gamename) { "Bindings", &Bindings }, { "DoubleBindings", &DoubleBindings }, { "AutomapBindings", &AutomapBindings }, - NULL, NULL + { NULL, NULL } }; const char *key, *value; diff --git a/src/p_user.cpp b/src/p_user.cpp index 6042d5662..5f9a69c3a 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -295,23 +295,23 @@ player_t::player_t() respawn_time(0), camera(0), air_finished(0), + MUSINFOactor(0), + MUSINFOtics(-1), + crouching(0), + crouchdir(0), Bot(0), BlendR(0), BlendG(0), BlendB(0), BlendA(0), LogText(), - crouching(0), - crouchdir(0), crouchfactor(0), crouchoffset(0), crouchviewdelta(0), ConversationNPC(0), ConversationPC(0), ConversationNPCAngle(0), - ConversationFaceTalker(0), - MUSINFOactor(0), - MUSINFOtics(-1) + ConversationFaceTalker(0) { memset (&cmd, 0, sizeof(cmd)); memset (frags, 0, sizeof(frags)); diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 4d0b51623..2b3413460 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -317,7 +317,7 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo) sprintf(cksumout + (j * 2), "%02X", cksum[j]); } - fprintf(hashfile, "file: %s, hash: %s, size: %d\n", filename, cksumout, reader->GetLength()); + fprintf(hashfile, "file: %s, hash: %s, size: %ld\n", filename, cksumout, reader->GetLength()); } else From 902593198b3b8f7cb5314375707085d483b9e85b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Apr 2015 09:37:06 +0200 Subject: [PATCH 47/58] - wrapped all line ID accesss just like sector tags --- src/fragglescript/t_func.cpp | 17 +++++++++-------- src/p_3dfloors.cpp | 2 +- src/p_3dmidtex.cpp | 2 +- src/p_lnspec.cpp | 4 ++-- src/p_sectors.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/p_setup.cpp | 33 +++++++++++---------------------- src/p_spec.cpp | 4 ++-- src/p_udmf.cpp | 31 ++++++++++++++++++++++++++++--- src/p_xlat.cpp | 3 ++- src/r_defs.h | 7 +++++++ 10 files changed, 99 insertions(+), 40 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 7650b174e..0251b8fba 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -4382,16 +4382,17 @@ void FParser::SF_SetLineTrigger() FLineIdIterator itr(id); while ((i = itr.Next()) >= 0) { - if (t_argc==2) tag=lines[i].id; + if (t_argc == 2) tag = lines[i].GetMainId(); maplinedef_t mld; - mld.special=spec; - mld.tag=tag; - mld.flags=0; + mld.special = spec; + mld.tag = tag; + mld.flags = 0; int f = lines[i].flags; - P_TranslateLineDef(&lines[i], &mld); - lines[i].id=tag; - lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_SPAC_MASK|ML_FIRSTSIDEONLY)) | - (f & ~(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_SPAC_MASK|ML_FIRSTSIDEONLY)); + P_TranslateLineDef(&lines[i], &mld); + lines[i].ClearIds(); + lines[i].SetMainId(tag); + lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) | + (f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)); } } diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 5d63751c2..a59b78112 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -844,7 +844,7 @@ void P_Spawn3DFloors (void) { if (line->args[1]&8) { - line->id = line->args[4]; + line->SetMainId(line->args[4]); } else { diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 4939f55dc..ff0d3a181 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -167,7 +167,7 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c { line_t *ln = sectors[sec].lines[line]; - if (lineid != 0 && ln->id != lineid) continue; + if (lineid != 0 && !ln->HasId(lineid)) continue; if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX)) { diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 16d0402f3..16372b206 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2063,7 +2063,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int { int wallnum = scroller->GetWallNum (); - if (wallnum >= 0 && sides[wallnum].linedef->id == id && + if (wallnum >= 0 && sides[wallnum].linedef->HasId(id) && int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum && Where == scroller->GetScrollParts()) { @@ -2082,7 +2082,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int while ( (collect.Obj = iterator.Next ()) ) { if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 && - sides[collect.RefNum].linedef->id == id && + sides[collect.RefNum].linedef->HasId(id) && int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum && Where == ((DScroller *)collect.Obj)->GetScrollParts()) { diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index d96540351..7061af788 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -859,6 +859,42 @@ void sector_t::HashTags() } } +void line_t::SetMainId(int newid) +{ + id = newid; +} + +int line_t::GetMainId() const +{ + return id; +} + +void line_t::ClearIds() +{ + id = -1; +} + +bool line_t::HasId(int checkid) const +{ + return id == checkid; +} + + +void line_t::HashIds() +{ + // killough 4/17/98: same thing, only for linedefs + int i; + + for (i=numlines; --i>=0; ) // Initially make all slots empty. + lines[i].firstid = -1; + for (i=numlines; --i>=0; ) // Proceed from last to first linedef + { // so that lower linedefs appear first + int j = (unsigned) lines[i].id % (unsigned) numlines; // Hash func + lines[i].nextid = lines[j].firstid; // Prepend linedef to chain + lines[j].firstid = i; + } +} + bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 62270567c..9c47e1fdc 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1920,40 +1920,40 @@ void P_SetLineID (line_t *ld) case Line_SetIdentification: if (!(level.flags2 & LEVEL2_HEXENHACK)) { - ld->id = ld->args[0] + 256 * ld->args[4]; + ld->SetMainId(ld->args[0] + 256 * ld->args[4]); ld->flags |= ld->args[1]<<16; } else { - ld->id = ld->args[0]; + ld->SetMainId(ld->args[0]); } ld->special = 0; break; case TranslucentLine: - ld->id = ld->args[0]; + ld->SetMainId(ld->args[0]); ld->flags |= ld->args[3]<<16; break; case Teleport_Line: case Scroll_Texture_Model: - ld->id = ld->args[0]; + ld->SetMainId(ld->args[0]); break; case Polyobj_StartLine: - ld->id = ld->args[3]; + ld->SetMainId(ld->args[3]); break; case Polyobj_ExplicitLine: - ld->id = ld->args[4]; + ld->SetMainId(ld->args[4]); break; case Plane_Align: - ld->id = ld->args[2]; + ld->SetMainId(ld->args[2]); break; case Static_Init: - if (ld->args[1] == Init_SectorLink) ld->id = ld->args[0]; + if (ld->args[1] == Init_SectorLink) ld->SetMainId(ld->args[0]); break; } } @@ -2038,7 +2038,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) { for (j = 0; j < numlines; j++) { - if (lines[j].id == ld->args[0]) + if (lines[j].HasId(ld->args[0])) { lines[j].Alpha = alpha; if (additive) @@ -2233,7 +2233,7 @@ void P_LoadLineDefs2 (MapData * map) ld->v1 = &vertexes[LittleShort(mld->v1)]; ld->v2 = &vertexes[LittleShort(mld->v2)]; ld->Alpha = FRACUNIT; // [RH] Opaque by default - ld->id = -1; + ld->ClearIds(); P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1])); @@ -3310,18 +3310,7 @@ void P_LoadBehavior (MapData * map) static void P_InitTagLists () { sector_t::HashTags(); - - // killough 4/17/98: same thing, only for linedefs - int i; - - for (i=numlines; --i>=0; ) // Initially make all slots empty. - lines[i].firstid = -1; - for (i=numlines; --i>=0; ) // Proceed from last to first linedef - { // so that lower linedefs appear first - int j = (unsigned) lines[i].id % (unsigned) numlines; // Hash func - lines[i].nextid = lines[j].firstid; // Prepend linedef to chain - lines[j].firstid = i; - } + line_t::HashIds(); } void P_GetPolySpots (MapData * map, TArray &spots, TArray &anchors) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c072122b8..8dbb73f37 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -279,11 +279,11 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) } // some old WADs use this method to create walls that change the texture when shot. else if (activationType == SPAC_Impact && // only for shootable triggers - (level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack! + (level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack! !repeat && // only non-repeatable triggers (specialGeneric_Crusher) && // not for Boom's generalized linedefs special && // not for lines without a special - line->args[0] == line->id && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0] + line->HasId(line->args[0]) && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0] line->args[0] && // only if there's a tag (which is stored in the first arg) P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef { diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index aab952f21..75ad855fe 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -780,7 +780,7 @@ public: memset(ld, 0, sizeof(*ld)); ld->Alpha = FRACUNIT; - ld->id = -1; + ld->ClearIds(); ld->sidedef[0] = ld->sidedef[1] = NULL; if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; @@ -813,7 +813,7 @@ public: continue; case NAME_Id: - ld->id = CheckInt(key); + ld->SetMainId(CheckInt(key)); continue; case NAME_Sidefront: @@ -1040,6 +1040,19 @@ public: break; } +#if 0 // for later + if (if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2)) + { + char *endp; + int num = strtol(key.GetChars(), &endp, 10); + if (num > 0 && *endp == NULL) + { + // only allow ID## with ## as a proper number + ld->SetId((short)CheckInt(key), false); + } + } +#endif + if (!strnicmp("user_", key.GetChars(), 5)) { AddUserKey(key, UDMF_Line, index); @@ -1053,7 +1066,7 @@ public: maplinedef_t mld; memset(&mld, 0, sizeof(mld)); mld.special = ld->special; - mld.tag = ld->id; + mld.tag = ld->GetMainId(); P_TranslateLineDef(ld, &mld); ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY)); } @@ -1497,6 +1510,18 @@ public: default: break; } +#if 0 // for later + if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2)) + { + char *endp; + int num = strtol(key.GetChars(), &endp, 10); + if (num > 0 && *endp == NULL) + { + // only allow ID## with ## as a proper number + sec->SetTag((short)CheckInt(key), false); + } + } +#endif if (!strnicmp("user_", key.GetChars(), 5)) { diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 2d48e6053..ef1e92849 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -104,7 +104,8 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) // line also needs to have its ID set to the same as its tag. // An external conversion program would need to do this more // intelligently. - ld->id = tag; + ld->ClearIds(); + ld->SetMainId(tag); // 0 specials are never translated. if (special == 0) diff --git a/src/r_defs.h b/src/r_defs.h index 41821cb62..1865777d3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -905,6 +905,13 @@ struct line_t sector_t *frontsector, *backsector; int validcount; // if == validcount, already checked int locknumber; // [Dusk] lock number for special + + + void SetMainId(int newid); + int GetMainId() const; + void ClearIds(); + bool HasId(int id) const; + static void HashIds(); }; // phares 3/14/98 From 418e6a16b85fb84833a65c80d89110e9c3406577 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Apr 2015 09:43:43 +0200 Subject: [PATCH 48/58] - fixed UDMF user variables could be set for the base namespaces which do not define them. --- src/p_udmf.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 75ad855fe..cdbb8dc4c 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -722,6 +722,7 @@ public: break; default: + CHECK_N(Zd | Zdt) if (0 == strnicmp("user_", key.GetChars(), 5)) { // Custom user key - Sets an actor's user variable directly FMapThingUserData ud; @@ -1041,7 +1042,7 @@ public: } #if 0 // for later - if (if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2)) + if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2)) { char *endp; int num = strtol(key.GetChars(), &endp, 10); @@ -1053,7 +1054,7 @@ public: } #endif - if (!strnicmp("user_", key.GetChars(), 5)) + if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5)) { AddUserKey(key, UDMF_Line, index); } @@ -1239,7 +1240,7 @@ public: break; } - if (!strnicmp("user_", key.GetChars(), 5)) + if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5)) { AddUserKey(key, UDMF_Side, index); } @@ -1523,7 +1524,7 @@ public: } #endif - if (!strnicmp("user_", key.GetChars(), 5)) + if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5)) { AddUserKey(key, UDMF_Sector, index); } From 203f88ce6efb0811c06ce2b88085f876102ba42d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Apr 2015 20:10:27 +0200 Subject: [PATCH 49/58] - some sanitizing of sector tag/line id management: * make setting the line ID with P_TranslateLineDef explicit because there's one FraggleScript function that needs to work around the changes caused by this. There's also some functions setting only a temporary linedef. These would inevitably cause problems if the underlying data gets changed. * remove FS function 'ChangeTag'. Fortunately this was just some long forgotten test stuff that can be removed without affecting any maps, but the feature would cause some serious problems in a more complex system. With these changes it is guaranteed that after map setup the tag/ids won't change anymore. --- src/fragglescript/t_func.cpp | 28 +++++----------------------- src/p_setup.cpp | 15 ++++----------- src/p_setup.h | 2 +- src/p_udmf.cpp | 4 ++-- src/p_xlat.cpp | 16 +++++++++------- src/thingdef/thingdef_codeptr.cpp | 4 ++-- 6 files changed, 23 insertions(+), 46 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0251b8fba..a0609377e 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -67,6 +67,7 @@ #include "v_font.h" #include "r_data/colormaps.h" #include "farchive.h" +#include "p_setup.h" static FRandom pr_script("FScript"); @@ -2226,9 +2227,6 @@ void FParser::SF_RunCommand(void) // //========================================================================== -// any linedef type -extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld); - void FParser::SF_LineTrigger() { if (CheckArgs(1)) @@ -2237,7 +2235,7 @@ void FParser::SF_LineTrigger() maplinedef_t mld; mld.special=intvalue(t_argv[0]); mld.tag=t_argc > 1 ? intvalue(t_argv[1]) : 0; - P_TranslateLineDef(&line, &mld); + P_TranslateLineDef(&line, &mld, false); P_ExecuteSpecial(line.special, NULL, Script->trigger, false, line.args[0],line.args[1],line.args[2],line.args[3],line.args[4]); } @@ -4382,15 +4380,12 @@ void FParser::SF_SetLineTrigger() FLineIdIterator itr(id); while ((i = itr.Next()) >= 0) { - if (t_argc == 2) tag = lines[i].GetMainId(); maplinedef_t mld; mld.special = spec; mld.tag = tag; mld.flags = 0; int f = lines[i].flags; - P_TranslateLineDef(&lines[i], &mld); - lines[i].ClearIds(); - lines[i].SetMainId(tag); + P_TranslateLineDef(&lines[i], &mld, false); lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) | (f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)); @@ -4401,26 +4396,13 @@ void FParser::SF_SetLineTrigger() //========================================================================== // -// new for GZDoom: Changes a sector's tag -// (I only need this because MAP02 in RTC-3057 has some issues with the GL -// renderer that I can't fix without the scripts. But loading a FS on top on -// ACS still works so I can hack around it with this.) +// // //========================================================================== void FParser::SF_ChangeTag() { - if (CheckArgs(2)) - { - FSectorTagIterator it(t_argv[0].value.i); - int secnum; - while ((secnum = it.Next()) >= 0) - { - sectors[secnum].ClearTags(); - sectors[secnum].SetMainTag(t_argv[1].value.i); - } - sector_t::HashTags(); - } + // Development garbage! } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 9c47e1fdc..4a1527514 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -96,7 +96,6 @@ CVAR (Bool, gennodes, false, CVAR_SERVERINFO|CVAR_GLOBALCONFIG); CVAR (Bool, genglnodes, false, CVAR_SERVERINFO); CVAR (Bool, showloadtimes, false, 0); -static void P_InitTagLists (); static void P_Shutdown (); bool P_IsBuildMap(MapData *map); @@ -2146,11 +2145,10 @@ void P_LoadLineDefs (MapData * map) // [RH] Translate old linedef special and flags to be // compatible with the new format. - P_TranslateLineDef (ld, mld); + P_TranslateLineDef (ld, mld, true); ld->v1 = &vertexes[LittleShort(mld->v1)]; ld->v2 = &vertexes[LittleShort(mld->v2)]; - //ld->id = -1; ID has been assigned in P_TranslateLineDef P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1])); @@ -3209,7 +3207,9 @@ static void P_GroupLines (bool buildmap) // [RH] Moved this here times[4].Clock(); - P_InitTagLists(); // killough 1/30/98: Create xref tables for tags + // killough 1/30/98: Create xref tables for tags + sector_t::HashTags(); + line_t::HashIds(); times[4].Unclock(); times[5].Clock(); @@ -3306,13 +3306,6 @@ void P_LoadBehavior (MapData * map) } } -// Hash the sector tags across the sectors and linedefs. -static void P_InitTagLists () -{ - sector_t::HashTags(); - line_t::HashIds(); -} - void P_GetPolySpots (MapData * map, TArray &spots, TArray &anchors) { if (map->HasBehavior) diff --git a/src/p_setup.h b/src/p_setup.h index ee26f4c57..20caa5d76 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -115,7 +115,7 @@ struct line_t; struct maplinedef_t; void P_LoadTranslator(const char *lumpname); -void P_TranslateLineDef (line_t *ld, maplinedef_t *mld); +void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setlineid); int P_TranslateSectorSpecial (int); int GetUDMFInt(int type, int index, const char *key); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index cdbb8dc4c..09cee8441 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -754,7 +754,7 @@ public: mld.flags = 0; mld.special = th->special; mld.tag = th->args[0]; - P_TranslateLineDef(&ld, &mld); + P_TranslateLineDef(&ld, &mld, true); th->special = ld.special; memcpy(th->args, ld.args, sizeof (ld.args)); } @@ -1068,7 +1068,7 @@ public: memset(&mld, 0, sizeof(mld)); mld.special = ld->special; mld.tag = ld->GetMainId(); - P_TranslateLineDef(ld, &mld); + P_TranslateLineDef(ld, &mld, false); ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY)); } if (passuse && (ld->activation & SPAC_Use)) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index ef1e92849..4b1373817 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -60,7 +60,7 @@ typedef enum PushMany, } triggertype_e; -void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) +void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setid) { unsigned short special = (unsigned short) LittleShort(mld->special); short tag = LittleShort(mld->tag); @@ -100,12 +100,14 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) } flags = newflags; - // For purposes of maintaining BOOM compatibility, each - // line also needs to have its ID set to the same as its tag. - // An external conversion program would need to do this more - // intelligently. - ld->ClearIds(); - ld->SetMainId(tag); + if (setid) + { + // For purposes of maintaining BOOM compatibility, each + // line also needs to have its ID set to the same as its tag. + // An external conversion program would need to do this more + // intelligently. + ld->SetMainId(tag); + } // 0 specials are never translated. if (special == 0) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index cb59f8a1f..b63ba567f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -70,6 +70,7 @@ #include "m_bbox.h" #include "r_data/r_translate.h" #include "p_trace.h" +#include "p_setup.h" #include "gstrings.h" @@ -4506,7 +4507,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave) //=========================================================================== -void P_TranslateLineDef (line_t *ld, maplinedef_t *mld); DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LineEffect) { ACTION_PARAM_START(2); @@ -4520,7 +4520,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LineEffect) if ((oldjunk.special = special)) // Linedef type { oldjunk.tag = tag; // Sector tag for linedef - P_TranslateLineDef(&junk, &oldjunk); // Turn into native type + P_TranslateLineDef(&junk, &oldjunk, false); // Turn into native type res = !!P_ExecuteSpecial(junk.special, NULL, self, false, junk.args[0], junk.args[1], junk.args[2], junk.args[3], junk.args[4]); if (res && !(junk.flags & ML_REPEAT_SPECIAL)) // If only once, From 3cb4eb44a854a90cf621274a80fe1faf2de93b22 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Apr 2015 08:29:21 +0200 Subject: [PATCH 50/58] - fixed: APowerRegeneration::DoEffect did not call the super method. --- src/g_shared/a_artifacts.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 14b270435..87491073e 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1757,6 +1757,7 @@ IMPLEMENT_CLASS(APowerRegeneration) void APowerRegeneration::DoEffect() { + Super::DoEffect(); if (Owner != NULL && Owner->health > 0 && (level.time & 31) == 0) { if (P_GiveBody(Owner, Strength/FRACUNIT)) From e30958f44315c15f7c69122c85629a3b09985fe1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Apr 2015 18:07:45 +0200 Subject: [PATCH 51/58] - fixed: The check for completely invisible 3D floor in the sorting code checked the wrong flags. --- src/p_3dfloors.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index a59b78112..ae1c31a86 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -44,6 +44,7 @@ #include "r_data/colormaps.h" #ifdef _3DFLOORS +EXTERN_CVAR(Int, vid_renderer) //========================================================================== // @@ -201,7 +202,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag // kg3D - software renderer only hack // this is really required because of ceilingclip and floorclip - if(flags & FF_BOTHPLANES) + if((vid_renderer == 0) && (flags & FF_BOTHPLANES)) { P_Add3DFloor(sec, sec2, master, FF_EXISTS | FF_THISINSIDE | FF_RENDERPLANES | FF_NOSHADE | FF_SEETHROUGH | FF_SHOOTTHROUGH | (flags & (FF_INVERTSECTOR | FF_TRANSLUCENT | FF_ADDITIVETRANS)), alpha); @@ -220,8 +221,7 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) int tag=line->args[0]; sector_t * sec = line->frontsector, * ss; - FSectorTagIterator it(tag); - while ((s = it.Next()) >= 0) + for (s=-1; (s = P_FindSectorFromTag(tag,s)) >= 0;) { ss=§ors[s]; @@ -265,6 +265,7 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) else if (param==4) { flags=FF_EXISTS|FF_RENDERPLANES|FF_INVERTPLANES|FF_NOSHADE|FF_FIX; + if (param2 & 1) flags |= FF_SEETHROUGH; // marker for allowing missing texture checks alpha=255; } else @@ -489,7 +490,7 @@ void P_Recalculate3DFloors(sector_t * sector) // by the clipping code below. ffloors.Push(pick); } - else if ((pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) || (!(pick->flags&(FF_ALLSIDES|FF_BOTHPLANES)))) && pick->flags&FF_EXISTS) + else if ((pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) || (!(pick->flags&FF_RENDERALL))) && pick->flags&FF_EXISTS) { // We must check if this nonsolid segment gets clipped from the top by another 3D floor if (solid != NULL && solid_bottom < height) @@ -583,6 +584,7 @@ void P_Recalculate3DFloors(sector_t * sector) lightlist[0].extra_colormap = sector->ColorMap; lightlist[0].blend = 0; lightlist[0].flags = 0; + lightlist[0].fromsector = true; maxheight = sector->CenterCeiling(); minheight = sector->CenterFloor(); @@ -604,6 +606,7 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.extra_colormap = rover->GetColormap(); newlight.blend = rover->GetBlend(); newlight.flags = rover->flags; + newlight.fromsector = false; lightlist.Push(newlight); } else if (i==0) @@ -618,6 +621,7 @@ void P_Recalculate3DFloors(sector_t * sector) lightlist[0].extra_colormap = rover->GetColormap(); lightlist[0].blend = rover->GetBlend(); lightlist[0].flags = rover->flags; + lightlist[0].fromsector = false; } } if (rover->flags&FF_DOUBLESHADOW) @@ -642,6 +646,7 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.blend = 0; } newlight.flags = rover->flags; + newlight.fromsector = false; lightlist.Push(newlight); } } @@ -844,7 +849,7 @@ void P_Spawn3DFloors (void) { if (line->args[1]&8) { - line->SetMainId(line->args[4]); + line->id = line->args[4]; } else { From d166211ce073cbbcfc96de87edfdc7d24daccefc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Apr 2015 19:55:46 +0200 Subject: [PATCH 52/58] - reverted changes from copying over p_3dfloors.cpp with GZDoom's version. --- src/p_3dfloors.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index ae1c31a86..42d79dcc0 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -44,7 +44,6 @@ #include "r_data/colormaps.h" #ifdef _3DFLOORS -EXTERN_CVAR(Int, vid_renderer) //========================================================================== // @@ -202,7 +201,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag // kg3D - software renderer only hack // this is really required because of ceilingclip and floorclip - if((vid_renderer == 0) && (flags & FF_BOTHPLANES)) + if(flags & FF_BOTHPLANES) { P_Add3DFloor(sec, sec2, master, FF_EXISTS | FF_THISINSIDE | FF_RENDERPLANES | FF_NOSHADE | FF_SEETHROUGH | FF_SHOOTTHROUGH | (flags & (FF_INVERTSECTOR | FF_TRANSLUCENT | FF_ADDITIVETRANS)), alpha); @@ -221,7 +220,8 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) int tag=line->args[0]; sector_t * sec = line->frontsector, * ss; - for (s=-1; (s = P_FindSectorFromTag(tag,s)) >= 0;) + FSectorTagIterator it(tag); + while ((s = it.Next()) >= 0) { ss=§ors[s]; @@ -265,7 +265,6 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) else if (param==4) { flags=FF_EXISTS|FF_RENDERPLANES|FF_INVERTPLANES|FF_NOSHADE|FF_FIX; - if (param2 & 1) flags |= FF_SEETHROUGH; // marker for allowing missing texture checks alpha=255; } else @@ -584,7 +583,6 @@ void P_Recalculate3DFloors(sector_t * sector) lightlist[0].extra_colormap = sector->ColorMap; lightlist[0].blend = 0; lightlist[0].flags = 0; - lightlist[0].fromsector = true; maxheight = sector->CenterCeiling(); minheight = sector->CenterFloor(); @@ -606,7 +604,6 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.extra_colormap = rover->GetColormap(); newlight.blend = rover->GetBlend(); newlight.flags = rover->flags; - newlight.fromsector = false; lightlist.Push(newlight); } else if (i==0) @@ -621,7 +618,6 @@ void P_Recalculate3DFloors(sector_t * sector) lightlist[0].extra_colormap = rover->GetColormap(); lightlist[0].blend = rover->GetBlend(); lightlist[0].flags = rover->flags; - lightlist[0].fromsector = false; } } if (rover->flags&FF_DOUBLESHADOW) @@ -646,7 +642,6 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.blend = 0; } newlight.flags = rover->flags; - newlight.fromsector = false; lightlist.Push(newlight); } } @@ -849,7 +844,7 @@ void P_Spawn3DFloors (void) { if (line->args[1]&8) { - line->id = line->args[4]; + line->SetMainId(line->args[4]); } else { From 9b6756114b89c37d607705713bd7705cf08c8a20 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 16 Apr 2015 17:39:45 -0500 Subject: [PATCH 53/58] Scale mouse coordinates based on window size - Fixed: If you enlarged the game window (in windowed mode) so that the window is bigger than the selected resolution, the menu would still take its inputs from the portion in the upper left that matched the resolution. --- src/v_video.h | 4 ++-- src/win32/fb_d3d9.cpp | 22 ++++++++++++++++++++++ src/win32/fb_ddraw.cpp | 13 +++++++++++++ src/win32/i_input.cpp | 8 ++++---- src/win32/win32iface.h | 5 ++--- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/v_video.h b/src/v_video.h index 69741c7f8..5250cdaa9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -398,8 +398,8 @@ public: virtual void WipeEndScreen(); virtual bool WipeDo(int ticks); virtual void WipeCleanup(); - virtual int GetPixelDoubling() const { return 0; } - virtual int GetTrueHeight() { return GetHeight(); } + + virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y) {} uint32 GetLastFPS() const { return LastCount; } diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index e23275734..9fd185431 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1028,6 +1028,28 @@ bool D3DFB::IsFullscreen () return !Windowed; } +//========================================================================== +// +// D3DFB :: ScaleCoordsFromWindow +// +// Given coordinates in window space, return coordinates in what the game +// thinks screen space is. +// +//========================================================================== + +void D3DFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) +{ + RECT rect; + + if (GetClientRect(Window, &rect)) + { + x = SWORD(x * Width / (rect.right - rect.left)); + y = SWORD(y * TrueHeight / (rect.bottom - rect.top)); + } + // Subtract letterboxing borders + y -= (TrueHeight - Height) / 2; +} + //========================================================================== // // D3DFB :: Lock diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index 2aa694f3b..ecf570ff8 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -806,6 +806,19 @@ bool DDrawFB::Is8BitMode() return vid_displaybits == 8; } +void DDrawFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) +{ + RECT rect; + + if (GetClientRect(Window, &rect)) + { + x = SWORD(x * Width / (rect.right - rect.left)); + y = SWORD(y * TrueHeight / (rect.bottom - rect.top)); + } + // Subtract letterboxing borders + y -= (TrueHeight - Height) / 2; +} + bool DDrawFB::IsValid () { return PrimarySurf != NULL; diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index ed7c81cf1..a26ff320e 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -323,11 +323,11 @@ bool GUIWndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESU if (BlockMouseMove > 0) return true; } + ev.data1 = LOWORD(lParam); + ev.data2 = HIWORD(lParam); + if (screen != NULL) { - int shift = screen? screen->GetPixelDoubling() : 0; - ev.data1 = LOWORD(lParam) >> shift; - ev.data2 = HIWORD(lParam) >> shift; - if (screen) ev.data2 -= (screen->GetTrueHeight() - screen->GetHeight())/2; + screen->ScaleCoordsFromWindow(ev.data1, ev.data2); } if (wParam & MK_SHIFT) ev.data3 |= GKM_SHIFT; diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 2704de0fa..9699157cd 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -164,8 +164,8 @@ public: void SetVSync (bool vsync); void NewRefreshRate(); HRESULT GetHR (); - virtual int GetTrueHeight() { return TrueHeight; } bool Is8BitMode(); + void ScaleCoordsFromWindow(SWORD &x, SWORD &y); void Blank (); bool PaintToWindow (); @@ -269,8 +269,8 @@ public: bool WipeDo(int ticks); void WipeCleanup(); HRESULT GetHR (); - virtual int GetTrueHeight() { return TrueHeight; } bool Is8BitMode() { return false; } + void ScaleCoordsFromWindow(SWORD &x, SWORD &y); private: friend class D3DTex; @@ -380,7 +380,6 @@ private: void EndLineBatch(); void EndBatch(); void CopyNextFrontBuffer(); - int GetPixelDoubling() const { return PixelDoubling; } D3DCAPS9 DeviceCaps; From 1fa1e26cf9c91f6eb41f967e76799323541080ff Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 17 Apr 2015 00:24:33 -0400 Subject: [PATCH 54/58] - SDL backend could use the new ScaleCoordsFromWindow since it does similarly for fullscreen. --- src/posix/sdl/i_input.cpp | 32 +++----------------------------- src/posix/sdl/sdlvideo.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/posix/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp index 6fff2d2a9..372b23446 100644 --- a/src/posix/sdl/i_input.cpp +++ b/src/posix/sdl/i_input.cpp @@ -18,8 +18,6 @@ #include "templates.h" #include "s_sound.h" -void ScaleWithAspect (int &w, int &h, int Width, int Height); - static void I_CheckGUICapture (); static void I_CheckNativeMouse (); @@ -320,35 +318,11 @@ void MessagePump (const SDL_Event &sev) int x, y; SDL_GetMouseState (&x, &y); - // Detect if we're doing scaling in the Window and adjust the mouse - // coordinates accordingly. This could be more efficent, but I - // don't think performance is an issue in the menus. - SDL_Window *focus; - if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ())) - { - int w, h; - SDL_GetWindowSize (focus, &w, &h); - int realw = w, realh = h; - ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); - if (realw != SCREENWIDTH || realh != SCREENHEIGHT) - { - double xratio = (double)SCREENWIDTH/realw; - double yratio = (double)SCREENHEIGHT/realh; - if (realw < w) - { - x = (x - (w - realw)/2)*xratio; - y *= yratio; - } - else - { - y = (y - (h - realh)/2)*yratio; - x *= xratio; - } - } - } - event.data1 = x; event.data2 = y; + + screen->ScaleCoordsFromWindow(event.data1, event.data2); + event.type = EV_GUI_Event; if(sev.type == SDL_MOUSEMOTION) event.subtype = EV_GUI_MouseMove; diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index 309002456..c24fd797a 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -50,6 +50,7 @@ public: friend class SDLVideo; virtual void SetVSync (bool vsync); + virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y); private: PalEntry SourcePalette[256]; @@ -723,6 +724,35 @@ void SDLFB::SetVSync (bool vsync) #endif // __APPLE__ } +void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) +{ + // Detect if we're doing scaling in the Window and adjust the mouse + // coordinates accordingly. This could be more efficent, but I + // don't think performance is an issue in the menus. + if(IsFullscreen()) + { + int w, h; + SDL_GetWindowSize (Screen, &w, &h); + int realw = w, realh = h; + ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); + if (realw != SCREENWIDTH || realh != SCREENHEIGHT) + { + double xratio = (double)SCREENWIDTH/realw; + double yratio = (double)SCREENHEIGHT/realh; + if (realw < w) + { + x = (x - (w - realw)/2)*xratio; + y *= yratio; + } + else + { + y = (y - (h - realh)/2)*yratio; + x *= xratio; + } + } + } +} + ADD_STAT (blit) { FString out; From 6e28963141cf02da2ca108b0104b65fc90b649ff Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Apr 2015 19:40:45 +0200 Subject: [PATCH 55/58] - added a sanity check to GL nodes loader for a potential crash. --- src/p_glnodes.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 1b34e8bbc..547cecace 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -338,7 +338,14 @@ static bool LoadGLSegs(FileReader * lump) ml->side=LittleShort(ml->side); segs[i].sidedef = ldef->sidedef[ml->side]; - segs[i].frontsector = ldef->sidedef[ml->side]->sector; + if (ldef->sidedef[ml->side] != NULL) + { + segs[i].frontsector = ldef->sidedef[ml->side]->sector; + } + else + { + segs[i].frontsector = NULL; + } if (ldef->flags & ML_TWOSIDED && ldef->sidedef[ml->side^1] != NULL) { segs[i].backsector = ldef->sidedef[ml->side^1]->sector; @@ -346,7 +353,7 @@ static bool LoadGLSegs(FileReader * lump) else { ldef->flags &= ~ML_TWOSIDED; - segs[i].backsector = 0; + segs[i].backsector = NULL; } } @@ -385,7 +392,14 @@ static bool LoadGLSegs(FileReader * lump) ml->side=LittleShort(ml->side); segs[i].sidedef = ldef->sidedef[ml->side]; - segs[i].frontsector = ldef->sidedef[ml->side]->sector; + if (ldef->sidedef[ml->side] != NULL) + { + segs[i].frontsector = ldef->sidedef[ml->side]->sector; + } + else + { + segs[i].frontsector = NULL; + } if (ldef->flags & ML_TWOSIDED && ldef->sidedef[ml->side^1] != NULL) { segs[i].backsector = ldef->sidedef[ml->side^1]->sector; @@ -393,7 +407,7 @@ static bool LoadGLSegs(FileReader * lump) else { ldef->flags &= ~ML_TWOSIDED; - segs[i].backsector = 0; + segs[i].backsector = NULL; } } From f983f778f27ca17b1a45f62d367c174ab0c0b5c5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 17 Apr 2015 21:39:07 +0200 Subject: [PATCH 56/58] - moved ScaleCoordsFromWindow to the BaseWinFB base class to eliminate two identical implementations. (GZDoom would have had to implement a third identical copy in its GL framebuffer as well.) --- src/win32/fb_d3d9.cpp | 22 ---------------------- src/win32/fb_ddraw.cpp | 13 ------------- src/win32/win32iface.h | 6 ++++-- src/win32/win32video.cpp | 23 +++++++++++++++++++++++ 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 9fd185431..e23275734 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1028,28 +1028,6 @@ bool D3DFB::IsFullscreen () return !Windowed; } -//========================================================================== -// -// D3DFB :: ScaleCoordsFromWindow -// -// Given coordinates in window space, return coordinates in what the game -// thinks screen space is. -// -//========================================================================== - -void D3DFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) -{ - RECT rect; - - if (GetClientRect(Window, &rect)) - { - x = SWORD(x * Width / (rect.right - rect.left)); - y = SWORD(y * TrueHeight / (rect.bottom - rect.top)); - } - // Subtract letterboxing borders - y -= (TrueHeight - Height) / 2; -} - //========================================================================== // // D3DFB :: Lock diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index ecf570ff8..2aa694f3b 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -806,19 +806,6 @@ bool DDrawFB::Is8BitMode() return vid_displaybits == 8; } -void DDrawFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) -{ - RECT rect; - - if (GetClientRect(Window, &rect)) - { - x = SWORD(x * Width / (rect.right - rect.left)); - y = SWORD(y * TrueHeight / (rect.bottom - rect.top)); - } - // Subtract letterboxing borders - y -= (TrueHeight - Height) / 2; -} - bool DDrawFB::IsValid () { return PrimarySurf != NULL; diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 9699157cd..934931ea0 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -127,10 +127,12 @@ public: virtual void Blank () = 0; virtual bool PaintToWindow () = 0; virtual HRESULT GetHR () = 0; + virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y); protected: virtual bool CreateResources () = 0; virtual void ReleaseResources () = 0; + virtual int GetTrueHeight() { return GetHeight(); } bool Windowed; @@ -165,7 +167,7 @@ public: void NewRefreshRate(); HRESULT GetHR (); bool Is8BitMode(); - void ScaleCoordsFromWindow(SWORD &x, SWORD &y); + virtual int GetTrueHeight() { return TrueHeight; } void Blank (); bool PaintToWindow (); @@ -270,7 +272,7 @@ public: void WipeCleanup(); HRESULT GetHR (); bool Is8BitMode() { return false; } - void ScaleCoordsFromWindow(SWORD &x, SWORD &y); + virtual int GetTrueHeight() { return TrueHeight; } private: friend class D3DTex; diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 3071ae8e7..8aa74bfb5 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -736,6 +736,29 @@ void Win32Video::SetWindowedScale (float scale) // FIXME } +//========================================================================== +// +// BaseWinFB :: ScaleCoordsFromWindow +// +// Given coordinates in window space, return coordinates in what the game +// thinks screen space is. +// +//========================================================================== + +void BaseWinFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y) +{ + RECT rect; + + int TrueHeight = GetTrueHeight(); + if (GetClientRect(Window, &rect)) + { + x = SWORD(x * Width / (rect.right - rect.left)); + y = SWORD(y * TrueHeight / (rect.bottom - rect.top)); + } + // Subtract letterboxing borders + y -= (TrueHeight - Height) / 2; +} + //========================================================================== // // SetFPSLimit From b3c7b9679a8bf1eadba047ac15e59916b4edd674 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 18 Apr 2015 22:51:28 -0500 Subject: [PATCH 57/58] Fixed: writeopl broke when the OPL3 cores were added - When the OPL3 cores were added, DiskWriterIO was never updated to take into account things like more than two OPL2 chips can be configured. - DiskWriterIO no longer does any file writing directly. That function has been split off into an OPLDump class, which has two specializations: one for RDOS Play, and the other for DOSBox. If one chip is configured, it dumps for a single OPL2, otherwise it dumps for an OPL3 (effectively dual OPL2). - TODO: Figure out why playback of raw OPL files doesn't sound nearly as good as playing MIDI with the OPL emulation. It's probably something simple I overlooked. --- src/oplsynth/music_opldumper_mididevice.cpp | 408 ++++++++++---------- src/oplsynth/muslib.h | 16 +- 2 files changed, 212 insertions(+), 212 deletions(-) diff --git a/src/oplsynth/music_opldumper_mididevice.cpp b/src/oplsynth/music_opldumper_mididevice.cpp index 74bef0677..33e026c07 100644 --- a/src/oplsynth/music_opldumper_mididevice.cpp +++ b/src/oplsynth/music_opldumper_mididevice.cpp @@ -45,6 +45,35 @@ // TYPES ------------------------------------------------------------------- +class OPLDump : public OPLEmul +{ +public: + OPLDump(FILE *file) : File(file), TimePerTick(0), CurTime(0), + CurIntTime(0), TickMul(1), CurChip(0) {} + + // If we're doing things right, these should never be reset. + virtual void Reset() { assert(0); } + + // Update() is only used for getting waveform data, which dumps don't do. + virtual void Update(float *buffer, int length) { assert(0); } + + // OPL dumps don't pan beyond what OPL3 is capable of (which is + // already written using registers from the original data). + virtual void SetPanning(int c, float left, float right) {} + + // Only for the OPL dumpers, not the emulators + virtual void SetClockRate(double samples_per_tick) {} + virtual void WriteDelay(int ticks) = 0; + +protected: + FILE *File; + double TimePerTick; // in milliseconds + double CurTime; + int CurIntTime; + int TickMul; + BYTE CurChip; +}; + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -59,6 +88,173 @@ // CODE -------------------------------------------------------------------- +class OPL_RDOSdump : public OPLDump +{ +public: + OPL_RDOSdump(FILE *file) : OPLDump(file) + { + assert(File != NULL); + fwrite("RAWADATA\0", 1, 10, File); + NeedClockRate = true; + } + virtual ~OPL_RDOSdump() + { + if (File != NULL) + { + WORD endmark = 0xFFFF; + fwrite(&endmark, 2, 1, File); + fclose(File); + } + } + + virtual void WriteReg(int reg, int v) + { + assert(File != NULL); + BYTE chipnum = reg >> 8; + if (chipnum != CurChip) + { + BYTE switcher[2] = { chipnum + 1, 2 }; + fwrite(switcher, 1, 2, File); + } + reg &= 255; + if (reg != 0 && reg != 2 && (reg != 255 || v != 255)) + { + BYTE cmd[2] = { BYTE(v), BYTE(reg) }; + fwrite(cmd, 1, 2, File); + } + } + + virtual void SetClockRate(double samples_per_tick) + { + TimePerTick = samples_per_tick / OPL_SAMPLE_RATE * 1000.0; + + double clock_rate; + int clock_mul; + WORD clock_word; + + clock_rate = samples_per_tick * ADLIB_CLOCK_MUL; + clock_mul = 1; + + // The RDos raw format's clock rate is stored in a word. Therefore, + // the longest tick that can be stored is only ~55 ms. + while (clock_rate / clock_mul + 0.5 > 65535.0) + { + clock_mul++; + } + clock_word = WORD(clock_rate / clock_mul + 0.5); + + if (NeedClockRate) + { // Set the initial clock rate. + clock_word = LittleShort(clock_word); + fseek(File, 8, SEEK_SET); + fwrite(&clock_word, 2, 1, File); + fseek(File, 0, SEEK_END); + NeedClockRate = false; + } + else + { // Change the clock rate in the middle of the song. + BYTE clock_change[4] = { 0, 2, BYTE(clock_word & 255), BYTE(clock_word >> 8) }; + fwrite(clock_change, 1, 4, File); + } + } + virtual void WriteDelay(int ticks) + { + if (ticks > 0) + { // RDos raw has very precise delays but isn't very efficient at + // storing long delays. + BYTE delay[2]; + + ticks *= TickMul; + delay[1] = 0; + while (ticks > 255) + { + ticks -= 255; + delay[0] = 255; + fwrite(delay, 1, 2, File); + } + delay[0] = BYTE(ticks); + fwrite(delay, 1, 2, File); + } + } +protected: + bool NeedClockRate; +}; + +class OPL_DOSBOXdump : public OPLDump +{ +public: + OPL_DOSBOXdump(FILE *file, bool dual) : OPLDump(file), Dual(dual) + { + assert(File != NULL); + fwrite("DBRAWOPL" + "\0\0" // Minor version number + "\1\0" // Major version number + "\0\0\0\0" // Total milliseconds + "\0\0\0", // Total data + 1, 20, File); + char type[4] = { Dual * 2, 0, 0, 0 }; // Single or dual OPL-2 + fwrite(type, 1, 4, File); + } + virtual ~OPL_DOSBOXdump() + { + if (File != NULL) + { + long where_am_i = ftell(File); + DWORD len[2]; + + fseek(File, 12, SEEK_SET); + len[0] = LittleLong(CurIntTime); + len[1] = LittleLong(DWORD(where_am_i - 24)); + fwrite(len, 4, 2, File); + fclose(File); + } + } + virtual void WriteReg(int reg, int v) + { + assert(File != NULL); + BYTE chipnum = reg >> 8; + if (chipnum != CurChip) + { + CurChip = chipnum; + fputc(chipnum + 2, File); + } + reg &= 255; + BYTE cmd[3] = { 4, BYTE(reg), BYTE(v) }; + fwrite (cmd + (reg > 4), 1, 3 - (reg > 4), File); + } + virtual void WriteDelay(int ticks) + { + if (ticks > 0) + { // DosBox only has millisecond-precise delays. + int delay; + + CurTime += TimePerTick * ticks; + delay = int(CurTime + 0.5) - CurIntTime; + CurIntTime += delay; + while (delay > 65536) + { + BYTE cmd[3] = { 1, 255, 255 }; + fwrite(cmd, 1, 2, File); + delay -= 65536; + } + delay--; + if (delay <= 255) + { + BYTE cmd[2] = { 0, BYTE(delay) }; + fwrite(cmd, 1, 2, File); + } + else + { + assert(delay <= 65535); + BYTE cmd[3] = { 1, BYTE(delay & 255), BYTE(delay >> 8) }; + fwrite(cmd, 1, 3, File); + } + } + } +protected: + bool Dual; +}; + //========================================================================== // // OPLDumperMIDIDevice Constructor @@ -139,139 +335,34 @@ DiskWriterIO::~DiskWriterIO() // //========================================================================== -int DiskWriterIO::OPLinit(uint numchips, bool, bool) +int DiskWriterIO::OPLinit(uint numchips, bool, bool initopl3) { - // If the file extension is unknown or not present, the default format - // is RAW. Otherwise, you can use DRO. - if (Filename.Len() < 5 || stricmp(&Filename[Filename.Len() - 4], ".dro") != 0) - { - Format = FMT_RDOS; - } - else - { - Format = FMT_DOSBOX; - } - File = fopen(Filename, "wb"); - if (File == NULL) + FILE *file = fopen(Filename, "wb"); + if (file == NULL) { Printf("Could not open %s for writing.\n", Filename.GetChars()); return 0; } - if (Format == FMT_RDOS) + numchips = clamp(numchips, 1u, 2u); + memset(chips, 0, sizeof(chips)); + // If the file extension is unknown or not present, the default format + // is RAW. Otherwise, you can use DRO. + if (Filename.Len() < 5 || stricmp(&Filename[Filename.Len() - 4], ".dro") != 0) { - fwrite("RAWADATA\0", 1, 10, File); - NeedClockRate = true; + chips[0] = new OPL_RDOSdump(file); } else { - fwrite("DBRAWOPL" - "\0\0" // Minor version number - "\1\0" // Major version number - "\0\0\0\0" // Total milliseconds - "\0\0\0", // Total data - 1, 20, File); - if (numchips == 1) - { - fwrite("\0\0\0", 1, 4, File); // Single OPL-2 - } - else - { - fwrite("\2\0\0", 1, 4, File); // Dual OPL-2 - } - NeedClockRate = false; + chips[0] = new OPL_DOSBOXdump(file, numchips > 1); } - - TimePerTick = 0; - TickMul = 1; - CurTime = 0; - CurIntTime = 0; - CurChip = 0; OPLchannels = OPL2CHANNELS * numchips; - OPLwriteInitState(false); + NumChips = numchips; + IsOPL3 = numchips > 1; + OPLwriteInitState(initopl3); return numchips; } -//========================================================================== -// -// DiskWriterIO :: OPLdeinit -// -//========================================================================== - -void DiskWriterIO::OPLdeinit() -{ - if (File != NULL) - { - if (Format == FMT_RDOS) - { - WORD endmark = 65535; - fwrite(&endmark, 2, 1, File); - } - else - { - long where_am_i = ftell(File); - DWORD len[2]; - - fseek(File, 12, SEEK_SET); - len[0] = LittleLong(CurIntTime); - len[1] = LittleLong(DWORD(where_am_i - 24)); - fwrite(len, 4, 2, File); - } - fclose(File); - File = NULL; - } -} - -//========================================================================== -// -// DiskWriterIO :: OPLwriteReg -// -//========================================================================== - -void DiskWriterIO::OPLwriteReg(int which, uint reg, uchar data) -{ - SetChip(which); - if (Format == FMT_RDOS) - { - if (reg != 0 && reg != 2 && (reg != 255 || data != 255)) - { - BYTE cmd[2] = { data, BYTE(reg) }; - fwrite(cmd, 1, 2, File); - } - } - else - { - BYTE cmd[3] = { 4, BYTE(reg), data }; - fwrite (cmd + (reg > 4), 1, 3 - (reg > 4), File); - } -} - -//========================================================================== -// -// DiskWriterIO :: SetChip -// -//========================================================================== - -void DiskWriterIO :: SetChip(int chipnum) -{ - assert(chipnum == 0 || chipnum == 1); - - if (chipnum != CurChip) - { - CurChip = chipnum; - if (Format == FMT_RDOS) - { - BYTE switcher[2] = { BYTE(chipnum + 1), 2 }; - fwrite(switcher, 1, 2, File); - } - else - { - BYTE switcher = chipnum + 2; - fwrite(&switcher, 1, 1, File); - } - } -} - //========================================================================== // // DiskWriterIO :: SetClockRate @@ -280,39 +371,7 @@ void DiskWriterIO :: SetChip(int chipnum) void DiskWriterIO::SetClockRate(double samples_per_tick) { - TimePerTick = samples_per_tick / OPL_SAMPLE_RATE * 1000.0; - - if (Format == FMT_RDOS) - { - double clock_rate; - int clock_mul; - WORD clock_word; - - clock_rate = samples_per_tick * ADLIB_CLOCK_MUL; - clock_mul = 1; - - // The RDos raw format's clock rate is stored in a word. Therefore, - // the longest tick that can be stored is only ~55 ms. - while (clock_rate / clock_mul + 0.5 > 65535.0) - { - clock_mul++; - } - clock_word = WORD(clock_rate / clock_mul + 0.5); - - if (NeedClockRate) - { // Set the initial clock rate. - clock_word = LittleShort(clock_word); - fseek(File, 8, SEEK_SET); - fwrite(&clock_word, 2, 1, File); - fseek(File, 0, SEEK_END); - NeedClockRate = false; - } - else - { // Change the clock rate in the middle of the song. - BYTE clock_change[4] = { 0, 2, BYTE(clock_word & 255), BYTE(clock_word >> 8) }; - fwrite(clock_change, 1, 4, File); - } - } + static_cast(chips[0])->SetClockRate(samples_per_tick); } //========================================================================== @@ -323,50 +382,5 @@ void DiskWriterIO::SetClockRate(double samples_per_tick) void DiskWriterIO :: WriteDelay(int ticks) { - if (ticks <= 0) - { - return; - } - if (Format == FMT_RDOS) - { // RDos raw has very precise delays but isn't very efficient at - // storing long delays. - BYTE delay[2]; - - ticks *= TickMul; - delay[1] = 0; - while (ticks > 255) - { - ticks -= 255; - delay[0] = 255; - fwrite(delay, 1, 2, File); - } - delay[0] = BYTE(ticks); - fwrite(delay, 1, 2, File); - } - else - { // DosBox only has millisecond-precise delays. - int delay; - - CurTime += TimePerTick * ticks; - delay = int(CurTime + 0.5) - CurIntTime; - CurIntTime += delay; - while (delay > 65536) - { - BYTE cmd[3] = { 1, 255, 255 }; - fwrite(cmd, 1, 2, File); - delay -= 65536; - } - delay--; - if (delay <= 255) - { - BYTE cmd[2] = { 0, BYTE(delay) }; - fwrite(cmd, 1, 2, File); - } - else - { - assert(delay <= 65535); - BYTE cmd[3] = { 1, BYTE(delay & 255), BYTE(delay >> 8) }; - fwrite(cmd, 1, 3, File); - } - } + static_cast(chips[0])->WriteDelay(ticks); } diff --git a/src/oplsynth/muslib.h b/src/oplsynth/muslib.h index 6cfb5bd55..8499a6bed 100644 --- a/src/oplsynth/muslib.h +++ b/src/oplsynth/muslib.h @@ -195,25 +195,11 @@ struct DiskWriterIO : public OPLio DiskWriterIO(const char *filename); ~DiskWriterIO(); - int OPLinit(uint numchips, bool notused=false, bool notused2=false); - void OPLdeinit(); - void OPLwriteReg(int which, uint reg, uchar data); + int OPLinit(uint numchips, bool notused, bool initopl3); void SetClockRate(double samples_per_tick); void WriteDelay(int ticks); - void SetChip(int chipnum); - - FILE *File; FString Filename; - int Format; - bool NeedClockRate; - double TimePerTick; // In milliseconds - double CurTime; - int CurIntTime; - int TickMul; - int CurChip; - - enum { FMT_RDOS, FMT_DOSBOX }; }; struct musicBlock { From f65a07c952d6ed3da49abb06ca8cd7375bd467e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Apr 2015 08:48:20 +0200 Subject: [PATCH 58/58] - minor bit of cleanup of tags code. --- src/p_sectors.cpp | 10 +++++----- src/p_udmf.cpp | 6 ++++-- src/p_xlat.cpp | 2 +- src/r_defs.h | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 7061af788..49d8db9f1 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -830,6 +830,11 @@ bool sector_t::HasTag(int checktag) const return tag == checktag; } +bool sector_t::HasTags() const +{ + return tag != 0; +} + void sector_t::SetMainTag(int tagnum) { tag = tagnum; @@ -864,11 +869,6 @@ void line_t::SetMainId(int newid) id = newid; } -int line_t::GetMainId() const -{ - return id; -} - void line_t::ClearIds() { id = -1; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 09cee8441..657281a11 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -778,6 +778,7 @@ public: bool strifetrans = false; bool strifetrans2 = false; FString arg0str, arg1str; + int lineid; // forZDoomTranslated namespace memset(ld, 0, sizeof(*ld)); ld->Alpha = FRACUNIT; @@ -814,7 +815,8 @@ public: continue; case NAME_Id: - ld->SetMainId(CheckInt(key)); + lineid = CheckInt(key); + ld->SetMainId(lineid); continue; case NAME_Sidefront: @@ -1067,7 +1069,7 @@ public: maplinedef_t mld; memset(&mld, 0, sizeof(mld)); mld.special = ld->special; - mld.tag = ld->GetMainId(); + mld.tag = lineid; P_TranslateLineDef(ld, &mld, false); ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY)); } diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 4b1373817..76d0cb811 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -307,7 +307,7 @@ void P_TranslateTeleportThings () while ( (dest = iterator.Next()) ) { - if (dest->Sector->GetMainTag() == 0) + if (!dest->Sector->HasTags()) { dest->tid = 1; dest->AddToHash (); diff --git a/src/r_defs.h b/src/r_defs.h index 1865777d3..3cf25573c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -634,6 +634,7 @@ struct sector_t } bool HasTag(int checktag) const; + bool HasTags() const; void SetMainTag(int tagnum); int GetMainTag() const; void ClearTags(); @@ -908,7 +909,6 @@ struct line_t void SetMainId(int newid); - int GetMainId() const; void ClearIds(); bool HasId(int id) const; static void HashIds();