diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 7bbff7322..dca0d3485 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -541,7 +541,7 @@ CCMD (mapchecksum) } for (int i = 1; i < argv.argc(); ++i) { - map = P_OpenMapData(argv[i]); + map = P_OpenMapData(argv[i], true); if (map == NULL) { Printf("Cannot load %s as a map\n", argv[i]); diff --git a/src/g_level.cpp b/src/g_level.cpp index 7e56d8843..0b07ae2b5 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1923,7 +1923,7 @@ CCMD(listmaps) for(unsigned i = 0; i < wadlevelinfos.Size(); i++) { level_info_t *info = &wadlevelinfos[i]; - MapData *map = P_OpenMapData(info->mapname); + MapData *map = P_OpenMapData(info->mapname, true); if (map != NULL) { diff --git a/src/m_argv.cpp b/src/m_argv.cpp index 54d9ffda4..816a2d54c 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -35,6 +35,7 @@ #include #include "m_argv.h" #include "cmdlib.h" +#include "i_system.h" IMPLEMENT_CLASS (DArgs) @@ -391,6 +392,14 @@ void DArgs::CollectFiles(const char *param, const char *extension) } } + // Optional: Replace short path names with long path names +#ifdef _WIN32 + for (i = 0; i < work.Size(); ++i) + { + work[i] = I_GetLongPathName(work[i]); + } +#endif + // Step 3: Add work back to Argv, as long as it's non-empty. if (work.Size() > 0) { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index aa6a8ca87..21e0d5c0b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -575,11 +575,7 @@ int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucke } else { // Scan for the next free entry - unsigned int i; - for (i = FirstFreeEntry + 1; i < Pool.Size() && Pool[i].Next != FREE_ENTRY; ++i) - { - } - FirstFreeEntry = i; + FindFirstFreeEntry(FirstFreeEntry + 1); } PoolEntry *entry = &Pool[index]; entry->Str = str; @@ -590,6 +586,23 @@ int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucke return index | STRPOOL_LIBRARYID_OR; } +//============================================================================ +// +// ACSStringPool :: FindFirstFreeEntry +// +// Finds the first free entry, starting at base. +// +//============================================================================ + +void ACSStringPool::FindFirstFreeEntry(unsigned base) +{ + while (base < Pool.Size() && Pool[base].Next != FREE_ENTRY) + { + base++; + } + FirstFreeEntry = base; +} + //============================================================================ // // ACSStringPool :: ReadStrings @@ -638,6 +651,7 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id) { delete[] str; } + FindFirstFreeEntry(0); } } @@ -690,6 +704,7 @@ void ACSStringPool::Dump() const Printf("%4u. (%2d) \"%s\"\n", i, Pool[i].LockCount, Pool[i].Str.GetChars()); } } + Printf("First free %u\n", FirstFreeEntry); } //============================================================================ @@ -8405,7 +8420,7 @@ scriptwait: { int playernum = STACK(1); - if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL) + if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL || players[playernum].camera->player != NULL) { STACK(1) = -1; } diff --git a/src/p_acs.h b/src/p_acs.h index 1a0fb3f60..ec41ab886 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -100,6 +100,7 @@ public: private: int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum); int InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth); + void FindFirstFreeEntry(unsigned int base); enum { NUM_BUCKETS = 251 }; enum { FREE_ENTRY = 0xFFFFFFFE }; // Stored in PoolEntry's Next field diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 784e6946f..3693e9f7e 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -250,7 +250,7 @@ static int GetMapIndex(const char *mapname, int lastindex, const char *lumpname, // //=========================================================================== -MapData *P_OpenMapData(const char * mapname) +MapData *P_OpenMapData(const char * mapname, bool justcheck) { MapData * map = new MapData; FileReader * wadReader = NULL; @@ -331,13 +331,18 @@ MapData *P_OpenMapData(const char * mapname) const char * lumpname = Wads.GetLumpFullName(lump_name + i); try { - index = GetMapIndex(mapname, index, lumpname, true); + index = GetMapIndex(mapname, index, lumpname, !justcheck); } catch(...) { delete map; throw; } + if (index == -2) + { + delete map; + return NULL; + } if (index == ML_BEHAVIOR) map->HasBehavior = true; // The next lump is not part of this map anymore @@ -471,13 +476,18 @@ MapData *P_OpenMapData(const char * mapname) { try { - index = GetMapIndex(maplabel, index, lumpname, true); + index = GetMapIndex(maplabel, index, lumpname, !justcheck); } catch(...) { delete map; throw; } + if (index == -2) + { + delete map; + return NULL; + } if (index == ML_BEHAVIOR) map->HasBehavior = true; // The next lump is not part of this map anymore @@ -508,7 +518,7 @@ MapData *P_OpenMapData(const char * mapname) bool P_CheckMapData(const char *mapname) { - MapData *mapd = P_OpenMapData(mapname); + MapData *mapd = P_OpenMapData(mapname, true); if (mapd == NULL) return false; delete mapd; return true; @@ -3610,7 +3620,7 @@ void P_SetupLevel (char *lumpname, int position) P_FreeLevelData (); interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. - MapData *map = P_OpenMapData(lumpname); + MapData *map = P_OpenMapData(lumpname, true); if (map == NULL) { I_Error("Unable to open map '%s'\n", lumpname); diff --git a/src/p_setup.h b/src/p_setup.h index 6e0a90a1d..4a41a76f9 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -94,7 +94,7 @@ struct MapData void GetChecksum(BYTE cksum[16]); }; -MapData * P_OpenMapData(const char * mapname); +MapData * P_OpenMapData(const char * mapname, bool justcheck); bool P_CheckMapData(const char * mapname); diff --git a/src/statistics.cpp b/src/statistics.cpp index aa8d9afc1..81cd88983 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -463,7 +463,7 @@ void STAT_ChangeLevel(const char *newl) { // we reached the end of this episode int wad = 0; - MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap); + MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap, false); if (map != NULL) { wad = Wads.GetLumpFile(map->lumpnum); diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 3083735a9..fd2b59fb1 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -233,13 +233,13 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl NumParts = SAFESHORT(mtexture.d->patchcount); } - if (NumParts <= 0) + if (NumParts < 0) { I_FatalError ("Bad texture directory"); } UseType = FTexture::TEX_Wall; - Parts = new TexPart[NumParts]; + Parts = NumParts > 0 ? new TexPart[NumParts] : NULL; Width = SAFESHORT(mtexture.d->width); Height = SAFESHORT(mtexture.d->height); strncpy (Name, (const char *)mtexture.d->name, 8); @@ -906,7 +906,7 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int d // There is bizzarely a Doom editing tool that writes to the // first two elements of columndirectory, so I can't check those. - if (SAFESHORT(tex->patchcount) <= 0 || + if (SAFESHORT(tex->patchcount) < 0 || tex->columndirectory[2] != 0 || tex->columndirectory[3] != 0) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 7964c422b..510370ba1 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4913,6 +4913,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics) ACTION_PARAM_START(1); ACTION_PARAM_INT(tics_to_set, 0); + if (stateowner != self && self->player != NULL && stateowner->IsKindOf(RUNTIME_CLASS(AWeapon))) + { // Is this a weapon? Need to check psp states for a match, then. Blah. + for (int i = 0; i < NUMPSPRITES; ++i) + { + if (self->player->psprites[i].state == CallingState) + { + self->player->psprites[i].tics = tics_to_set; + return; + } + } + } + // Just set tics for self. self->tics = tics_to_set; } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index b5843ec7a..a82cb65f9 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -1569,3 +1569,31 @@ unsigned int I_MakeRNGSeed() CryptReleaseContext(prov, 0); return seed; } + +//========================================================================== +// +// I_GetLongPathName +// +// Returns the long version of the path, or the original if there isn't +// anything worth changing. +// +//========================================================================== + +FString I_GetLongPathName(FString shortpath) +{ + DWORD buffsize = GetLongPathName(shortpath.GetChars(), NULL, 0); + if (buffsize == 0) + { // nothing to change (it doesn't exist, maybe?) + return shortpath; + } + TCHAR *buff = new TCHAR[buffsize]; + DWORD buffsize2 = GetLongPathName(shortpath.GetChars(), buff, buffsize); + if (buffsize2 >= buffsize) + { // Failure! Just return the short path + delete[] buff; + return shortpath; + } + FString longpath(buff, buffsize2); + delete[] buff; + return longpath; +} diff --git a/src/win32/i_system.h b/src/win32/i_system.h index 6bafdc01c..9fbf2db5c 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -155,6 +155,9 @@ typedef _W64 long WLONG_PTR; typedef long WLONG_PTR; #endif +// Wrapper for GetLongPathName +FString I_GetLongPathName(FString shortpath); + // Directory searching routines // Mirror WIN32_FIND_DATAA in