From 70717cd2fab2183ce27e7eedfc03e77806d76d24 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 18 Jan 2014 02:21:49 +0100 Subject: [PATCH 01/14] - Cover the ASM_SOURCES fix for NO_ASM users too --- src/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b83b6dae62..badd2c3b1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -586,12 +586,13 @@ else( WIN32 ) endif( APPLE ) endif( WIN32 ) +if( NOT ASM_SOURCES ) + set( ASM_SOURCES "" ) +endif( NOT ASM_SOURCES ) + if( NO_ASM ) add_definitions( -DNOASM ) else( NO_ASM ) - if( NOT ASM_SOURCES ) - set( ASM_SOURCES "" ) - endif( NOT ASM_SOURCES ) if( X64 ) ADD_ASM_FILE( asm_x86_64 tmap3 ) else( X64 ) From dd5f2731282a27f811f1c8a5989028dd7922d52b Mon Sep 17 00:00:00 2001 From: Alex Qyoun-ae Date: Fri, 14 Feb 2014 05:10:48 +0400 Subject: [PATCH 02/14] Added possibly missing brackets --- src/g_strife/a_entityboss.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 58a88121e7..fafb3b8622 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) fixed_t SpawnX = spot->x; fixed_t SpawnY = spot->y; - fixed_t SpawnZ = spot->z + self->tracer? 70*FRACUNIT : 0; + fixed_t SpawnZ = spot->z + (self->tracer? 70*FRACUNIT : 0); an = self->angle >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), From 02cd6eebf443579bd9ade2e1396400ab49bd398d Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 16 Feb 2014 18:29:01 +0100 Subject: [PATCH 03/14] A_Log formatted text Make DECORATE version of Log consistent with ACS version. --- src/thingdef/thingdef_codeptr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d48b18a2aa..f2c738fb9e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2205,7 +2205,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log) ACTION_PARAM_STRING(text, 0); if (text[0] == '$') text = GStrings(text+1); - Printf("%s\n", text); + FString formatted = strbin1(text); + Printf("%s\n", formatted.GetChars()); ACTION_SET_RESULT(false); // Prints should never set the result for inventory state chains! } From d7478bcd683d609404ae664342de6e6b7ed94ac2 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Tue, 18 Feb 2014 00:40:14 +0100 Subject: [PATCH 04/14] New Freedoom names - Added freedoom2.wad as valid alias name (freedoom1.wad already existed). - Renamed titles to Freedoom: Phase 1 and Freedoom: Phase 2. - Reordered to put Phase 1 above Phase 2 in the IWAD picker. --- wadsrc/static/iwadinfo.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index e47951d316..a2f8ef6c0b 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -189,7 +189,7 @@ IWad IWad { - Name = "Freedoom" + Name = "Freedoom: Phase 2" Autoname = "Freedoom" Game = "Doom" Config = "Doom" @@ -200,7 +200,7 @@ IWad IWad { - Name = "Ultimate Freedoom" + Name = "Freedoom: Phase 1" Autoname = "Freedoom1" Game = "Doom" Config = "Doom" @@ -348,9 +348,10 @@ Names "strife1.wad" "strife0.wad" "strife.wad" - "freedoom.wad" "freedoom1.wad" + "freedoom2.wad" "freedoomu.wad" + "freedoom.wad" "freedm.wad" "blasphem.wad" "blasphemer.wad" From 732ee11da1a539fdf68074c2e748d84873728a83 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 23 Feb 2014 23:07:10 +0100 Subject: [PATCH 05/14] Some DOSBox Raw OPL v2 indices were off by one. This caused access violation errors on perfectly fine DRO files. For reference, scoredata[20] is the hardware type (OPL2, dual OPL2, or OPL3). --- src/oplsynth/opl_mus_player.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 335e6d66e1..43a129b149 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -104,16 +104,19 @@ fail: delete[] scoredata; } else if (((DWORD *)scoredata)[2] == MAKE_ID(2,0,0,0)) { - if (scoredata[20] != 0) - { - Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); - goto fail; - } + bool okay = true; if (scoredata[21] != 0) { - Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); - goto fail; + Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); + okay = false; } + if (scoredata[22] != 0) + { + Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); + okay = false; + } + if (!okay) + goto fail; RawPlayer = DosBox2; SamplesPerTick = OPL_SAMPLE_RATE / 1000; int headersize = 0x1A + scoredata[0x19]; From 9dacc9cc8d466e53d3f946dffc1e3601d1cac120 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Mon, 24 Feb 2014 05:07:37 +0100 Subject: [PATCH 06/14] The wrong value was used here. This caused crashes on some files (notably MBELLS from Cosmo and NUBC from Body Count) in my port of this code to SLADE 3. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 43a129b149..319eb8319b 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -267,7 +267,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { for (i = 0; i < io->NumChips; ++i) { - io->chips[i]->Update(samples1, samplesleft); + io->chips[i]->Update(samples1, numsamples); } OffsetSamples(samples1, numsamples << stereoshift); } From c7301a0fbbb738b84f4281308bdb06380ab256b8 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Sun, 23 Feb 2014 23:07:10 +0100 Subject: [PATCH 07/14] Some DOSBox Raw OPL v2 indices were off by one. This caused access violation errors on perfectly fine DRO files. For reference, scoredata[20] is the hardware type (OPL2, dual OPL2, or OPL3). --- src/oplsynth/opl_mus_player.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 335e6d66e1..43a129b149 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -104,16 +104,19 @@ fail: delete[] scoredata; } else if (((DWORD *)scoredata)[2] == MAKE_ID(2,0,0,0)) { - if (scoredata[20] != 0) - { - Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); - goto fail; - } + bool okay = true; if (scoredata[21] != 0) { - Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); - goto fail; + Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]); + okay = false; } + if (scoredata[22] != 0) + { + Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]); + okay = false; + } + if (!okay) + goto fail; RawPlayer = DosBox2; SamplesPerTick = OPL_SAMPLE_RATE / 1000; int headersize = 0x1A + scoredata[0x19]; From d430c18574fd6d72c751f869c4b3cd3312990b46 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Mon, 24 Feb 2014 05:07:37 +0100 Subject: [PATCH 08/14] The wrong value was used here. This caused crashes on some files (notably MBELLS from Cosmo and NUBC from Body Count) in my port of this code to SLADE 3. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 43a129b149..319eb8319b 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -267,7 +267,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { for (i = 0; i < io->NumChips; ++i) { - io->chips[i]->Update(samples1, samplesleft); + io->chips[i]->Update(samples1, numsamples); } OffsetSamples(samples1, numsamples << stereoshift); } From 0f7ad00d9a0ab45b75840f98df059712b48ac394 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 15:48:41 -0600 Subject: [PATCH 09/14] Ignore the minor version number when checking for DRO v1 files - There exist files where the first word of the version number for DRO v1 files is not 0 but something else completely. (Maybe it's not actually a version number?) Assume they are valid v1 files as long as the second word is a 1. --- src/oplsynth/opl_mus_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 319eb8319b..a528c10e2b 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -96,7 +96,7 @@ fail: delete[] scoredata; else if (((DWORD *)scoredata)[0] == MAKE_ID('D','B','R','A') && ((DWORD *)scoredata)[1] == MAKE_ID('W','O','P','L')) { - if (((DWORD *)scoredata)[2] == MAKE_ID(0,0,1,0)) + if (LittleShort(((WORD *)scoredata)[5]) == 1) { RawPlayer = DosBox1; SamplesPerTick = OPL_SAMPLE_RATE / 1000; From 7052d4e14e31328b5f14803b3aca20860f9a7e45 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 16:18:10 -0600 Subject: [PATCH 10/14] Fixed: userinfo_t::SkinChanged() was unaware of player classes --- src/d_netinfo.cpp | 10 +++++----- src/d_player.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index d2dbc862de..41ad683fe1 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -387,7 +387,7 @@ void D_SetupUserInfo () { // Some cvars don't copy their original value directly. case NAME_Team: coninfo->TeamChanged(team); break; - case NAME_Skin: coninfo->SkinChanged(skin); break; + case NAME_Skin: coninfo->SkinChanged(skin, players[consoleplayer].CurrentPlayerClass); break; case NAME_Gender: coninfo->GenderChanged(gender); break; case NAME_PlayerClass: coninfo->PlayerClassChanged(playerclass); break; // The rest do. @@ -447,9 +447,9 @@ int userinfo_t::TeamChanged(int team) return team; } -int userinfo_t::SkinChanged(const char *skinname) +int userinfo_t::SkinChanged(const char *skinname, int playerclass) { - int skinnum = R_FindSkin(skinname, 0); + int skinnum = R_FindSkin(skinname, playerclass); *static_cast((*this)[NAME_Skin]) = skinnum; return skinnum; } @@ -821,7 +821,7 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update) break; case NAME_Skin: - info->SkinChanged(value); + info->SkinChanged(value, players[pnum].CurrentPlayerClass); if (players[pnum].mo != NULL) { if (players[pnum].cls != NULL && @@ -958,7 +958,7 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) switch (name) { case NAME_Team: info.TeamChanged(atoi(str)); break; - case NAME_Skin: info.SkinChanged(str); break; + case NAME_Skin: info.SkinChanged(str, 0); break; case NAME_PlayerClass: info.PlayerClassChanged(str); break; default: val.String = str; diff --git a/src/d_player.h b/src/d_player.h index f6f7674d77..e104a55b62 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -332,7 +332,7 @@ struct userinfo_t : TMap void Reset(); int TeamChanged(int team); - int SkinChanged(const char *skinname); + int SkinChanged(const char *skinname, int playerclass); int SkinNumChanged(int skinnum); int GenderChanged(const char *gendername); int PlayerClassChanged(const char *classname); From db4763b14a0bfa0196ce41a96e96f5e724927291 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 16:27:57 -0600 Subject: [PATCH 11/14] Delay skin setting on save load until player class is known. - Fixed: Loading players from savegames set the skin before their current class was retrieved, so they could not validate their skins with the correct class. --- src/d_netinfo.cpp | 28 +++++++++------------------- src/d_player.h | 4 ++-- src/p_user.cpp | 18 +++++++++++++++--- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 41ad683fe1..ae2da80188 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -941,14 +941,21 @@ void WriteUserInfo(FArchive &arc, userinfo_t &info) arc << name; } -void ReadUserInfo(FArchive &arc, userinfo_t &info) +void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin) { FName name; FBaseCVar **cvar; char *str = NULL; UCVarValue val; + if (SaveVersion < 4253) + { + ReadCompatibleUserInfo(arc, info); + return; + } + info.Reset(); + skin = NULL; for (arc << name; name != NAME_None; arc << name) { cvar = info.CheckKey(name); @@ -958,7 +965,7 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) switch (name) { case NAME_Team: info.TeamChanged(atoi(str)); break; - case NAME_Skin: info.SkinChanged(str, 0); break; + case NAME_Skin: skin = str; break; // Caller must call SkinChanged() once current calss is known case NAME_PlayerClass: info.PlayerClassChanged(str); break; default: val.String = str; @@ -973,23 +980,6 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info) } } -FArchive &operator<< (FArchive &arc, userinfo_t &info) -{ - if (SaveVersion < 4253) - { - ReadCompatibleUserInfo(arc, info); - } - else if (arc.IsStoring()) - { - WriteUserInfo(arc, info); - } - else - { - ReadUserInfo(arc, info); - } - return arc; -} - CCMD (playerinfo) { if (argv.argc() < 2) diff --git a/src/d_player.h b/src/d_player.h index e104a55b62..122ab20f08 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -342,8 +342,8 @@ struct userinfo_t : TMap int ColorSetChanged(int setnum); }; -FArchive &operator<< (FArchive &arc, userinfo_t &info); - +void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin); +void WriteUserInfo(FArchive &arc, userinfo_t &info); // // Extended player object info: player_t diff --git a/src/p_user.cpp b/src/p_user.cpp index 901f6cfaab..80b175802d 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2742,14 +2742,22 @@ void P_UnPredictPlayer () void player_t::Serialize (FArchive &arc) { int i; + FString skinname; arc << cls << mo << camera << playerstate - << cmd - << userinfo - << DesiredFOV << FOV + << cmd; + if (arc.IsLoading()) + { + ReadUserInfo(arc, userinfo, skinname); + } + else + { + WriteUserInfo(arc, userinfo); + } + arc << DesiredFOV << FOV << viewz << viewheight << deltaviewheight @@ -2900,6 +2908,10 @@ void player_t::Serialize (FArchive &arc) oldbuttons = ~0; original_oldbuttons = ~0; } + if (skinname.IsNotEmpty()) + { + userinfo.SkinChanged(skinname, CurrentPlayerClass); + } } From a60918f601aa6bd094568340b26906f0f03772ae Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 17:43:28 -0600 Subject: [PATCH 12/14] Add NoPushWindowCheck compatibility flag - For maps like xtheateriii that expect non-blocking push lines to activate when you are standing on them and run into a completely different line, there is now this compatiblity.txt-only flag. --- src/compatibility.cpp | 1 + src/doomdef.h | 1 + src/p_map.cpp | 2 +- wadsrc/static/compatibility.txt | 7 ++++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index dca0d34851..7339a0f197 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -106,6 +106,7 @@ static FCompatOption Options[] = { "ignoreteleporttags", BCOMPATF_BADTELEPORTERS, SLOT_BCOMPAT }, { "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT }, { "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT }, + { "disablepushwindowcheck", BCOMPATF_NOWINDOWCHECK, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, diff --git a/src/doomdef.h b/src/doomdef.h index e08c3044d6..6ef9fcd041 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -351,6 +351,7 @@ enum BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other + BCOMPATF_NOWINDOWCHECK = 1 << 7, // Disable the window check in CheckForPushSpecial() }; // phares 3/20/98: diff --git a/src/p_map.cpp b/src/p_map.cpp index 8b0b605c63..02ab1a1ab6 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1640,7 +1640,7 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj, bool wind { if (line->special && !(mobj->flags6 & MF6_NOTRIGGER)) { - if (windowcheck && line->backsector != NULL) + if (windowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) { // Make sure this line actually blocks us and is not a window // or similar construct we are standing inside of. fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(mobj->x, mobj->y); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 4b75dfaba3..e2516a30d6 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -375,4 +375,9 @@ D62DCA9EC226DE49108D5DD9271F7631 // Cheogsh 2 map04 setthingz 1647 528 setthingz 1648 528 setthingz 1649 528 -} \ No newline at end of file +} + +B9DFF13207EACAC675C71D82624D0007 // XtheaterIII map01 +{ + DisablePushWindowCheck +} From 5a5fb9b3d19372d9323ba31fa5689fc95f94250b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 18:16:18 -0600 Subject: [PATCH 13/14] Clamp xy angle range in P_SetSlope() - This function just assumed that every xy angle passed to it was within the range [0,360). This is obviously bad, since anything outside that range can result in accessing data outside the range of the finecosine and finesine tables. --- src/p_slopes.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 07ddf2e0d7..af0ad7a205 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -178,6 +178,12 @@ void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi, } zang >>= ANGLETOFINESHIFT; + // Sanitize xyangi to [0,360) range + xyangi = xyangi % 360; + if (xyangi < 0) + { + xyangi = 360 + xyangi; + } xyang = (angle_t)Scale (xyangi, ANGLE_90, 90 << ANGLETOFINESHIFT); FVector3 norm; @@ -446,11 +452,11 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); } else if (mt->type <= THING_SlopeCeilingPointLine) - { + { // THING_SlopeFloorPointLine and THING_SlopCeilingPointLine P_SlopeLineToPoint (mt->args[0], x, y, z, mt->type & 1); } else - { + { // THING_SetFloorSlope and THING_SetCeilingSlope P_SetSlope (refplane, mt->type & 1, mt->angle, mt->args[0], x, y, z); } mt->type = 0; From 1d4f4b25d74fccc8f4c5e42811707e0606ce7adb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 24 Feb 2014 19:01:36 -0600 Subject: [PATCH 14/14] Don't free replaced textures that are used as patches. - Fixed: If a part of a multipatch texture is replaced by a HIRESTEX version, the original patch must not be deleted, since the multipatch texture still needs it for compositing. --- src/textures/multipatchtexture.cpp | 6 ++++-- src/textures/texture.cpp | 2 +- src/textures/texturemanager.cpp | 2 +- src/textures/textures.h | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index fd2b59fb16..4f327309dd 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -244,7 +244,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl Height = SAFESHORT(mtexture.d->height); strncpy (Name, (const char *)mtexture.d->name, 8); Name[8] = 0; - CalcBitSize (); xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; @@ -280,6 +279,10 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl NumParts--; i--; } + else + { + Parts[i].Texture->bKeepAround = true; + } if (strife) mpatch.s++; else @@ -859,7 +862,6 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d { pnames.Read (patchlookup[i].Name, 8); patchlookup[i].Name[8] = 0; - FTextureID j = CheckForTexture (patchlookup[i].Name, FTexture::TEX_WallPatch); if (j.isValid()) { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 093bf303b5..0434aaaa4e 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -146,7 +146,7 @@ FTexture::FTexture (const char *name, int lumpnum) : LeftOffset(0), TopOffset(0), WidthBits(0), HeightBits(0), xScale(FRACUNIT), yScale(FRACUNIT), SourceLump(lumpnum), UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), - bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), + bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0), Native(NULL) { id.SetInvalid(); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index f28026f193..48f3ff9e02 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -428,7 +428,7 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b Textures[index].Texture = newtexture; newtexture->id = oldtexture->id; - if (free) + if (free && !oldtexture->bKeepAround) { delete oldtexture; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 100ba31e9e..837c62689c 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -177,6 +177,7 @@ public: // fully composited before subjected to any kind of postprocessing instead of // doing it per patch. BYTE bMultiPatch:1; // This is a multipatch texture (we really could use real type info for textures...) + BYTE bKeepAround:1; // This texture was used as part of a multi-patch texture. Do not free it. WORD Rotations; SWORD SkyOffset;