This commit is contained in:
Rachael Alexanderson 2017-12-04 02:19:40 -05:00
commit 230ef14290
51 changed files with 563 additions and 1750 deletions

View file

@ -1168,6 +1168,7 @@ set (PCH_SOURCES
events.cpp
GuillotineBinPack.cpp
SkylineBinPack.cpp
tmpfileplus.cpp
)
enable_precompiled_headers( g_pch.h PCH_SOURCES )
@ -1182,7 +1183,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
${PCH_SOURCES}
x86.cpp
strnatcmp.c
tmpfileplus.c
zstring.cpp
math/asin.c
math/atan.c

View file

@ -532,13 +532,9 @@ bool FCajunMaster::LoadBots ()
DPrintf (DMSG_ERROR, "No " BOTFILENAME ", so no bots\n");
return false;
}
try
if (!sc.OpenFile(tmp))
{
sc.OpenFile(tmp);
}
catch (CRecoverableError &err)
{
Printf("%s. So no bots\n", err.GetMessage());
Printf("Unable to open %s. So no bots\n", tmp.GetChars());
return false;
}
@ -669,4 +665,4 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, RemoveAllBots)
PARAM_BOOL(fromlist);
bglobal.RemoveAllBots(fromlist);
return 0;
}
}

View file

@ -145,26 +145,6 @@ void ReplaceString (char **ptr, const char *str)
*/
//==========================================================================
//
// Q_filelength
//
//==========================================================================
int Q_filelength (FILE *f)
{
int pos;
int end;
pos = ftell (f);
fseek (f, 0, SEEK_END);
end = ftell (f);
fseek (f, pos, SEEK_SET);
return end;
}
//==========================================================================
//
// FileExists
@ -175,13 +155,9 @@ int Q_filelength (FILE *f)
bool FileExists (const char *filename)
{
struct stat buff;
// [RH] Empty filenames are never there
if (filename == NULL || *filename == 0)
return false;
return stat(filename, &buff) == 0 && !(buff.st_mode & S_IFDIR);
bool isdir;
bool res = DirEntryExists(filename, &isdir);
return res && !isdir;
}
//==========================================================================
@ -194,13 +170,9 @@ bool FileExists (const char *filename)
bool DirExists(const char *filename)
{
struct stat buff;
// [RH] Empty filenames are never there
if (filename == NULL || *filename == 0)
return false;
return stat(filename, &buff) == 0 && (buff.st_mode & S_IFDIR);
bool isdir;
bool res = DirEntryExists(filename, &isdir);
return res && isdir;
}
//==========================================================================
@ -211,13 +183,16 @@ bool DirExists(const char *filename)
//
//==========================================================================
bool DirEntryExists(const char *pathname)
bool DirEntryExists(const char *pathname, bool *isdir)
{
if (isdir) *isdir = false;
if (pathname == NULL || *pathname == 0)
return false;
struct stat info;
return stat(pathname, &info) == 0;
bool res = stat(pathname, &info) == 0;
if (isdir) *isdir = !!(info.st_mode & S_IFDIR);
return res;
}
//==========================================================================
@ -569,18 +544,13 @@ void CreatePath(const char *fn)
{
*p = '\0';
}
struct stat info;
if (stat(copy, &info) == 0)
if (!DirEntryExists(copy) && mkdir(copy, 0755) == -1)
{
if (info.st_mode & S_IFDIR)
goto exists;
}
if (mkdir(copy, 0755) == -1)
{ // failed
// failed
free(copy);
return;
}
exists: if (p != NULL)
if (p != NULL)
{
*p = '/';
}
@ -1029,10 +999,7 @@ void ScanDirectory(TArray<FFileList> &list, const char *dirpath)
FFileList *fl = &list[list.Reserve(1)];
fl->Filename << dirpath << file->d_name;
struct stat fileStat;
stat(fl->Filename, &fileStat);
fl->isDirectory = S_ISDIR(fileStat.st_mode);
fl->isDirectory = DirExists(fl->Filename);
if(fl->isDirectory)
{
FString newdir = fl->Filename;

View file

@ -18,10 +18,9 @@
// the dec offsetof macro doesnt work very well...
#define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type))
int Q_filelength (FILE *f);
bool FileExists (const char *filename);
bool DirExists(const char *filename);
bool DirEntryExists (const char *pathname);
bool DirEntryExists (const char *pathname, bool *isdir = nullptr);
extern FString progdir;

View file

@ -2488,17 +2488,16 @@ bool D_LoadDehLump(int lumpnum)
bool D_LoadDehFile(const char *patchfile)
{
FILE *deh;
FileReader fr;
deh = fopen(patchfile, "rb");
if (deh != NULL)
if (!fr.Open(patchfile))
{
PatchSize = Q_filelength(deh);
PatchSize = fr.GetLength();
PatchName = copystring(patchfile);
PatchFile = new char[PatchSize + 1];
fread(PatchFile, 1, PatchSize, deh);
fclose(deh);
fr.Read(PatchFile, PatchSize);
fr.Close();
PatchFile[PatchSize] = '\0'; // terminate with a '\0' character
return DoDehPatch();
}

View file

@ -1946,13 +1946,11 @@ static FString CheckGameInfo(TArray<FString> & pwads)
const char *filename = pwads[i];
// Does this exist? If so, is it a directory?
struct stat info;
if (stat(pwads[i], &info) != 0)
if (!DirEntryExists(pwads[i], &isdir))
{
Printf(TEXTCOLOR_RED "Could not stat %s\n", filename);
continue;
}
isdir = (info.st_mode & S_IFDIR) != 0;
if (!isdir)
{

View file

@ -50,6 +50,11 @@
//
//==========================================================================
FILE *FileReader::openfd(const char *filename)
{
return fopen(filename, "rb");
}
FileReader::FileReader ()
: File(NULL), Length(0), StartPos(0), FilePos(0), CloseOnDestruct(false)
{
@ -82,18 +87,23 @@ FileReader::FileReader (FILE *file, long length)
FilePos = StartPos = ftell (file);
}
FileReader::~FileReader ()
FileReader::~FileReader()
{
Close();
}
void FileReader::Close()
{
if (CloseOnDestruct && File != NULL)
{
fclose (File);
File = NULL;
}
File = NULL;
}
bool FileReader::Open (const char *filename)
{
File = fopen (filename, "rb");
File = openfd (filename);
if (File == NULL) return false;
FilePos = 0;
StartPos = 0;
@ -634,6 +644,30 @@ size_t FileWriter::Write(const void *buffer, size_t len)
}
}
long FileWriter::Tell()
{
if (File != NULL)
{
return ftell(File);
}
else
{
return 0;
}
}
long FileWriter::Seek(long offset, int mode)
{
if (File != NULL)
{
return fseek(File, offset, mode);
}
else
{
return 0;
}
}
size_t FileWriter::Printf(const char *fmt, ...)
{

View file

@ -93,12 +93,15 @@ public:
class FileReader : public FileReaderBase
{
protected:
FILE *openfd(const char *filename);
public:
FileReader ();
FileReader (const char *filename);
FileReader (FILE *file);
FileReader (FILE *file, long length);
bool Open (const char *filename);
void Close();
virtual ~FileReader ();
virtual long Tell () const;
@ -409,6 +412,8 @@ public:
static FileWriter *Open(const char *filename);
virtual size_t Write(const void *buffer, size_t len);
virtual long Tell();
virtual long Seek(long offset, int mode);
size_t Printf(const char *fmt, ...) GCCPRINTF(2,3);
protected:

View file

@ -2798,7 +2798,17 @@ void G_DoPlayDemo (void)
{
FixPathSeperator (defdemoname);
DefaultExtension (defdemoname, ".lmp");
M_ReadFileMalloc (defdemoname, &demobuffer);
FileReader fr;
if (!fr.Open(defdemoname))
{
I_Error("Unable to open demo '%s'", defdemoname.GetChars());
}
auto len = fr.GetLength();
demobuffer = (uint8_t*)M_Malloc(len);
if (fr.Read(demobuffer, len) != len)
{
I_Error("Unable to read demo '%s'", defdemoname.GetChars());
}
}
demo_p = demobuffer;
@ -2964,7 +2974,15 @@ bool G_CheckDemoStatus (void)
formlen = demobuffer + 4;
WriteLong (int(demo_p - demobuffer - 8), &formlen);
bool saved = M_WriteFile (demoname, demobuffer, int(demo_p - demobuffer));
auto fw = FileWriter::Open(demoname);
bool saved = false;
if (fw != nullptr)
{
const size_t size = demo_p - demobuffer;
saved = fw->Write(demobuffer, size) == size;
delete fw;
if (!saved) remove(demoname);
}
M_Free (demobuffer);
demorecording = false;
stoprecording = false;

File diff suppressed because it is too large Load diff

View file

@ -47,91 +47,16 @@ class CImage
eConvSourceMemory = 11,
eConvDestMemory = 12,
eSaveBmpFileOpen = 20,
eSaveBmpFileWrite = 21,
eSaveBmpSourceMemory = 22,
eSaveBmpColorDepth = 23,
eLoadBmpFileOpen = 30,
eLoadBmpFileRead = 31,
eLoadBmpBadFormat = 32,
eLoadBmpInit = 33,
eLoadBmpColorDepth = 34,
eSaveTgaFileOpen = 40,
eSaveTgaFileWrite = 41,
eSaveTgaSourceMemory = 42,
eSaveTgaColorDepth = 43,
eLoadTgaFileOpen = 50,
eLoadTgaFileRead = 51,
eLoadTgaBadFormat = 52,
eLoadTgaInit = 53,
eLoadTgaColorDepth = 54,
eLoadFilename = 60,
eSaveFilename = 61,
};
struct _BMPFILEHEADER
{
unsigned short bfType;
long int bfSize, bfRes1, bfOffBits;
};
struct _BMPIMAGEHEADEROLD
{
long int biSize;
unsigned short biWidth, biHeight;
unsigned short biPlanes, biBitCount;
};
struct _BMPIMAGEHEADER
{
long int biSize, biWidth, biHeight;
unsigned short biPlanes, biBitCount;
long int biCompression, biSizeImage;
long int biXPelsPerMeter, biYPelsPerMeter;
long int biClrUsed, biClrImportant;
};
struct _TGAHEADER
{
unsigned char tiIdentSize;
unsigned char tiPaletteIncluded;
unsigned char tiImageType;
unsigned short tiPaletteStart;
unsigned short tiPaletteSize;
unsigned char tiPaletteBpp;
unsigned short tiX0;
unsigned short tiY0;
unsigned short tiXres;
unsigned short tiYres;
unsigned char tiBitPerPixel;
unsigned char tiAttrBits;
};
public:
int DLL Init( int Xres, int Yres, unsigned short BitPerPixel );
int DLL SetImage(unsigned char *img, int width, int height, int bpp);
int DLL Destroy();
int DLL ConvertTo32( void );
int DLL ConvertTo24( void );
int DLL ConvertTo16( void );
int DLL Convert8To17( int transindex );
int DLL Convert32To17( void );
int SaveBmp(char *szFilename);
int LoadBmp(char *szFilename);
int SaveTga(char *szFilename, bool bCompressed );
int LoadTga(char *szFilename);
int DLL Load(char *szFilename);
int DLL Save(char *szFilename);
private:
void Output( char * pcData, int nSize );
void Output( char c );
void Output( void );
unsigned char Input( void );
public:
int m_Xres, m_Yres;

View file

@ -800,8 +800,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
GLRenderer->mAngles.Roll.Degrees = r_viewpoint.Angles.Roll.Degrees;
// Scroll the sky
GLRenderer->mSky1Pos = (double)fmod(screen->FrameTime * level.skyspeed1, 1024.f) * 90./256.;
GLRenderer->mSky2Pos = (double)fmod(screen->FrameTime * level.skyspeed2, 1024.f) * 90./256.;
GLRenderer->mSky1Pos = (double)fmod((double)screen->FrameTime * (double)level.skyspeed1, 1024.f) * 90./256.;
GLRenderer->mSky2Pos = (double)fmod((double)screen->FrameTime * (double)level.skyspeed2, 1024.f) * 90./256.;

View file

@ -88,86 +88,6 @@ EXTERN_CVAR(Bool, longsavemessages);
static long ParseCommandLine (const char *args, int *argc, char **argv);
//
// M_WriteFile
//
#ifndef O_BINARY
#define O_BINARY 0
#endif
bool M_WriteFile (char const *name, void *source, int length)
{
int handle;
int count;
handle = open ( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
if (handle == -1)
return false;
count = write (handle, source, length);
close (handle);
if (count < length)
return false;
return true;
}
//
// M_ReadFile
//
int M_ReadFile (char const *name, uint8_t **buffer)
{
int handle, count, length;
struct stat fileinfo;
uint8_t *buf;
handle = open (name, O_RDONLY | O_BINARY, 0666);
if (handle == -1)
I_Error ("Couldn't read file %s", name);
// [BL] Use stat instead of fstat for v140_xp hack
if (stat (name,&fileinfo) == -1)
I_Error ("Couldn't read file %s", name);
length = fileinfo.st_size;
buf = new uint8_t[length];
count = read (handle, buf, length);
close (handle);
if (count < length)
I_Error ("Couldn't read file %s", name);
*buffer = buf;
return length;
}
//
// M_ReadFile (same as above but use malloc instead of new to allocate the buffer.)
//
int M_ReadFileMalloc (char const *name, uint8_t **buffer)
{
int handle, count, length;
struct stat fileinfo;
uint8_t *buf;
handle = open (name, O_RDONLY | O_BINARY, 0666);
if (handle == -1)
I_Error ("Couldn't read file %s", name);
// [BL] Use stat instead of fstat for v140_xp hack
if (stat (name,&fileinfo) == -1)
I_Error ("Couldn't read file %s", name);
length = fileinfo.st_size;
buf = (uint8_t*)M_Malloc(length);
count = read (handle, buf, length);
close (handle);
if (count < length)
I_Error ("Couldn't read file %s", name);
*buffer = buf;
return length;
}
//---------------------------------------------------------------------------
//
@ -192,7 +112,6 @@ void M_FindResponseFile (void)
char **argv;
char *file = NULL;
int argc = 0;
FILE *handle;
int size;
long argsize = 0;
int index;
@ -202,22 +121,18 @@ void M_FindResponseFile (void)
if (added_stuff < limit)
{
// READ THE RESPONSE FILE INTO MEMORY
handle = fopen (Args->GetArg(i) + 1,"rb");
if (!handle)
FileReader fr;
if (!fr.Open(Args->GetArg(i) + 1))
{ // [RH] Make this a warning, not an error.
Printf ("No such response file (%s)!\n", Args->GetArg(i) + 1);
}
else
{
Printf ("Found response file %s!\n", Args->GetArg(i) + 1);
fseek (handle, 0, SEEK_END);
size = ftell (handle);
fseek (handle, 0, SEEK_SET);
size = fr.GetLength();
file = new char[size+1];
fread (file, size, 1, handle);
fr.Read (file, size);
file[size] = 0;
fclose (handle);
argsize = ParseCommandLine (file, &argc, NULL);
}
}

View file

@ -33,9 +33,6 @@ class FIWadManager;
extern FGameConfigFile *GameConfig;
bool M_WriteFile (char const *name, void *source, int length);
int M_ReadFile (char const *name, uint8_t **buffer);
int M_ReadFileMalloc (char const *name, uint8_t **buffer);
void M_FindResponseFile (void);
// [RH] M_ScreenShot now accepts a filename parameter.
@ -56,11 +53,13 @@ FString M_ZLibError(int zerrnum);
#ifdef __unix__
FString GetUserFile (const char *path); // Prepends ~/.zdoom to path
#endif
FString M_GetAppDataPath(bool create);
FString M_GetCachePath(bool create);
FString M_GetAutoexecPath();
FString M_GetCajunPath(const char *filename);
FString M_GetConfigPath(bool for_reading);
FString M_GetScreenshotsPath();
FString M_GetSavegamesPath();
FString M_GetDocumentsPath();
#endif

View file

@ -383,18 +383,22 @@ PNGHandle *M_VerifyPNG (FileReader *filer, bool takereader)
if (filer->Read(&data, 8) != 8)
{
if (takereader) delete filer;
return NULL;
}
if (data[0] != MAKE_ID(137,'P','N','G') || data[1] != MAKE_ID(13,10,26,10))
{ // Does not have PNG signature
if (takereader) delete filer;
return NULL;
}
if (filer->Read (&data, 8) != 8)
{
if (takereader) delete filer;
return NULL;
}
if (data[1] != MAKE_ID('I','H','D','R'))
{ // IHDR must be the first chunk
if (takereader) delete filer;
return NULL;
}
@ -452,12 +456,6 @@ PNGHandle *M_VerifyPNG (FileReader *filer, bool takereader)
return NULL;
}
PNGHandle *M_VerifyPNG(FILE *file)
{
FileReader *fr = new FileReader(file);
return M_VerifyPNG(fr, true);
}
//==========================================================================
//
// M_FreePNG

View file

@ -90,7 +90,6 @@ struct PNGHandle
// each chunk is not done. If it is valid, you get a PNGHandle to pass to
// the following functions.
PNGHandle *M_VerifyPNG (FileReader *file, bool takereader = false);
PNGHandle *M_VerifyPNG (FILE *file);
// Finds a chunk in a PNG file. The file pointer will be positioned at the
// beginning of the chunk data, and its length will be returned. A return

View file

@ -269,8 +269,8 @@ CCMD (md5sum)
}
for (int i = 1; i < argv.argc(); ++i)
{
FILE *file = fopen(argv[i], "rb");
if (file == NULL)
FileReader fr;
if (!fr.Open(argv[i]))
{
Printf("%s: %s\n", argv[i], strerror(errno));
}
@ -280,7 +280,7 @@ CCMD (md5sum)
uint8_t readbuf[8192];
size_t len;
while ((len = fread(readbuf, 1, sizeof(readbuf), file)) > 0)
while ((len = fr.Read(readbuf, sizeof(readbuf))) > 0)
{
md5.Update(readbuf, (unsigned int)len);
}
@ -290,7 +290,6 @@ CCMD (md5sum)
Printf("%02x", readbuf[j]);
}
Printf(" *%s\n", argv[i]);
fclose (file);
}
}
}

View file

@ -236,8 +236,8 @@ void FSavegameManager::ReadSaveStrings()
}
else // check for old formats.
{
FILE *file = fopen(filepath, "rb");
if (file != nullptr)
FileReader file;
if (file.Open(filepath))
{
PNGHandle *png;
char sig[16];
@ -255,8 +255,7 @@ void FSavegameManager::ReadSaveStrings()
title[OLDSAVESTRINGSIZE] = 0;
if (nullptr != (png = M_VerifyPNG(file)))
if (nullptr != (png = M_VerifyPNG(&file, false)))
{
char *ver = M_GetPNGText(png, "ZDoom Save Version");
if (ver != nullptr)
@ -273,13 +272,13 @@ void FSavegameManager::ReadSaveStrings()
}
else
{
fseek(file, 0, SEEK_SET);
if (fread(sig, 1, 16, file) == 16)
file.Seek(0, SEEK_SET);
if (file.Read(sig, 16) == 16)
{
if (strncmp(sig, "ZDOOMSAVE", 9) == 0)
{
if (fread(title, 1, OLDSAVESTRINGSIZE, file) == OLDSAVESTRINGSIZE)
if (file.Read(title, OLDSAVESTRINGSIZE) == OLDSAVESTRINGSIZE)
{
addIt = true;
}
@ -287,8 +286,8 @@ void FSavegameManager::ReadSaveStrings()
else
{
memcpy(title, sig, 16);
if (fread(title + 16, 1, OLDSAVESTRINGSIZE - 16, file) == OLDSAVESTRINGSIZE - 16 &&
fread(sig, 1, 16, file) == 16 &&
if (file.Read(title + 16, OLDSAVESTRINGSIZE - 16) == OLDSAVESTRINGSIZE - 16 &&
file.Read(sig, 16) == 16 &&
strncmp(sig, "ZDOOMSAVE", 9) == 0)
{
addIt = true;
@ -306,7 +305,6 @@ void FSavegameManager::ReadSaveStrings()
node->SaveTitle = title;
InsertSaveNode(node);
}
fclose(file);
}
}
} while (I_FindNext(filefirst, &c_file) == 0);
@ -418,17 +416,14 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring)
// Find an unused filename and save as that
FString filename;
int i;
FILE *test;
for (i = 0;; ++i)
{
filename = G_BuildSaveName("save", i);
test = fopen(filename, "rb");
if (test == nullptr)
if (!FileExists(filename))
{
break;
}
fclose(test);
}
G_SaveGame(filename, savegamestring);
}

View file

@ -1365,6 +1365,8 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key)
}
}
}
FindFirstFreeEntry(FirstFreeEntry);
}
//============================================================================

View file

@ -1133,16 +1133,15 @@ static void CreateCachedNodes(MapData *map)
memcpy(compressed + offset - 4, "ZGL3", 4);
FString path = CreateCacheName(map, true);
FILE *f = fopen(path, "wb");
FileWriter *fw = FileWriter::Open(path);
if (f != NULL)
if (fw != nullptr)
{
if (fwrite(compressed, outlen+offset, 1, f) != 1)
if (fw->Write(compressed, outlen+offset) != 1)
{
Printf("Error saving nodes to file %s\n", path.GetChars());
}
fclose(f);
delete fw;
}
else
{
@ -1162,32 +1161,30 @@ static bool CheckCachedNodes(MapData *map)
uint32_t *verts = NULL;
FString path = CreateCacheName(map, false);
FILE *f = fopen(path, "rb");
if (f == NULL) return false;
FileReader fr;
if (fread(magic, 1, 4, f) != 4) goto errorout;
if (!fr.Open(path)) return false;
if (fr.Read(magic, 4) != 4) goto errorout;
if (memcmp(magic, "CACH", 4)) goto errorout;
if (fread(&numlin, 4, 1, f) != 1) goto errorout;
if (fr.Read(&numlin, 4) != 4) goto errorout;
numlin = LittleLong(numlin);
if (numlin != level.lines.Size()) goto errorout;
if (fread(md5, 1, 16, f) != 16) goto errorout;
if (fr.Read(md5, 16) != 16) goto errorout;
map->GetChecksum(md5map);
if (memcmp(md5, md5map, 16)) goto errorout;
verts = new uint32_t[numlin * 8];
if (fread(verts, 8, numlin, f) != numlin) goto errorout;
if (fr.Read(verts, 8 * numlin) != 8 * numlin) goto errorout;
if (fread(magic, 1, 4, f) != 4) goto errorout;
if (fr.Read(magic, 4) != 4) goto errorout;
if (memcmp(magic, "ZGL2", 4) && memcmp(magic, "ZGL3", 4)) goto errorout;
try
{
long pos = ftell(f);
FileReader fr(f);
fr.Seek(pos, SEEK_SET);
P_LoadZNodes (fr, MAKE_ID(magic[0],magic[1],magic[2],magic[3]));
}
catch (CRecoverableError &error)
@ -1208,7 +1205,6 @@ static bool CheckCachedNodes(MapData *map)
}
delete [] verts;
fclose(f);
return true;
errorout:
@ -1216,7 +1212,6 @@ errorout:
{
delete[] verts;
}
fclose(f);
return false;
}

View file

@ -43,7 +43,7 @@ void RenderPolyPlayerSprites::Render(PolyRenderThread *thread)
//
// We also can't move it because the model render code relies on it
renderHUDModel = gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
//renderHUDModel = gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;

View file

@ -74,7 +74,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
void RenderPolySprite::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t stencilValue, float t1, float t2)
{
int spritenum = thing->sprite;
/*int spritenum = thing->sprite;
bool isPicnumOverride = thing->picnum.isValid();
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
if (modelframe)
@ -83,7 +83,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, const TriMatrix &worldTo
DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac);
PolyRenderModel(thread, worldToClip, clipPlane, stencilValue, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing);
return;
}
}*/
DVector2 line[2];
if (!GetLine(thing, line[0], line[1]))

View file

@ -49,6 +49,7 @@
#include "st_console.h"
#include "v_text.h"
#include "x86.h"
#include "cmdlib.h"
EXTERN_CVAR(String, language)
@ -336,11 +337,11 @@ int I_FindClose(void* const handle)
int I_FindAttr(findstate_t* const fileinfo)
{
dirent* const ent = fileinfo->namelist[fileinfo->current];
struct stat buf;
bool isdir;
if (stat(ent->d_name, &buf) == 0)
if (DirEntryExists(ent->d_name, &isdir))
{
return S_ISDIR(buf.st_mode) ? FA_DIREC : 0;
return isdir ? FA_DIREC : 0;
}
return 0;

View file

@ -42,6 +42,7 @@
#include "d_main.h"
#include "zstring.h"
#include "sc_man.h"
#include "cmdlib.h"
static void PSR_FindEndBlock(FScanner &sc)
{
@ -122,27 +123,28 @@ static TArray<FString> ParseSteamRegistry(const char* path)
// Read registry data
FScanner sc;
sc.OpenFile(path);
sc.SetCMode(true);
// Find the SteamApps listing
if(PSR_FindAndEnterBlock(sc, "InstallConfigStore"))
if (sc.OpenFile(path))
{
if(PSR_FindAndEnterBlock(sc, "Software"))
sc.SetCMode(true);
// Find the SteamApps listing
if (PSR_FindAndEnterBlock(sc, "InstallConfigStore"))
{
if(PSR_FindAndEnterBlock(sc, "Valve"))
if (PSR_FindAndEnterBlock(sc, "Software"))
{
if(PSR_FindAndEnterBlock(sc, "Steam"))
if (PSR_FindAndEnterBlock(sc, "Valve"))
{
dirs = PSR_ReadBaseInstalls(sc);
if (PSR_FindAndEnterBlock(sc, "Steam"))
{
dirs = PSR_ReadBaseInstalls(sc);
}
PSR_FindEndBlock(sc);
}
PSR_FindEndBlock(sc);
}
PSR_FindEndBlock(sc);
}
PSR_FindEndBlock(sc);
}
return dirs;
}
@ -223,7 +225,7 @@ TArray<FString> I_GetSteamPath()
{
struct stat st;
FString candidate(SteamInstallFolders[i] + "/" + AppInfo[app].BasePath);
if(stat(candidate, &st) == 0 && S_ISDIR(st.st_mode))
if(DirExists(candidate))
result.Push(candidate);
}
}

View file

@ -39,6 +39,35 @@
#include "m_misc.h"
#include "version.h" // for GAMENAME
//===========================================================================
//
// M_GetAppDataPath macOS
//
// Returns the path for the AppData folder.
//
//===========================================================================
FString M_GetAppDataPath(bool create)
{
FString path;
char pathstr[PATH_MAX];
FSRef folder;
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, create ? kCreateFolder : 0, &folder) &&
noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX))
{
path = pathstr;
}
else
{
path = progdir;
}
path += "/" GAMENAMELOWERCASE;
if (create) CreatePath(path);
return path;
}
//===========================================================================
//
// M_GetCachePath macOS
@ -64,6 +93,7 @@ FString M_GetCachePath(bool create)
path = progdir;
}
path += "/zdoom/cache";
if (create) CreatePath(path);
return path;
}
@ -185,3 +215,24 @@ FString M_GetSavegamesPath()
return path;
}
//===========================================================================
//
// M_GetDocumentsPath Unix
//
// Returns the path to the default documents directory.
//
//===========================================================================
FString M_GetDocumentsPath()
{
FString path;
char cpath[PATH_MAX];
FSRef folder;
if (noErr == FSFindFolder(kUserDomain, kDocumentsFolderType, kCreateFolder, &folder) &&
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
{
path << cpath << "/" GAME_DIR "/";
}
return path;
}

View file

@ -397,15 +397,16 @@ int I_FindClose (void *handle)
return 0;
}
int I_FindAttr (findstate_t *fileinfo)
int I_FindAttr(findstate_t* const fileinfo)
{
dirent *ent = fileinfo->namelist[fileinfo->current];
struct stat buf;
dirent* const ent = fileinfo->namelist[fileinfo->current];
bool isdir;
if (stat(ent->d_name, &buf) == 0)
if (DirEntryExists(ent->d_name, &isdir))
{
return S_ISDIR(buf.st_mode) ? FA_DIREC : 0;
return isdir ? FA_DIREC : 0;
}
return 0;
}

View file

@ -98,6 +98,26 @@ FString GetUserFile (const char *file)
return path;
}
//===========================================================================
//
// M_GetAppDataPath Unix
//
// Returns the path for the AppData folder.
//
//===========================================================================
FString M_GetAppDataPath(bool create)
{
// Don't use GAME_DIR and such so that ZDoom and its child ports can
// share the node cache.
FString path = NicePath("~/.config/" GAMENAMELOWERCASE);
if (create)
{
CreatePath(path);
}
return path;
}
//===========================================================================
//
// M_GetCachePath Unix
@ -198,3 +218,16 @@ FString M_GetSavegamesPath()
{
return NicePath("~/" GAME_DIR);
}
//===========================================================================
//
// M_GetDocumentsPath Unix
//
// Returns the path to the default documents directory.
//
//===========================================================================
FString M_GetDocumentsPath()
{
return NicePath("~/" GAME_DIR);
}

View file

@ -166,6 +166,8 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le
for (int i = 0; i < s->numSkins; i++)
{
// [BB] According to the MD3 spec, Name is supposed to include the full path.
// ... and since some tools seem to output backslashes, these need to be replaced with forward slashes to work.
FixPathSeperator(shader[i].Name);
s->skins[i] = LoadSkin("", shader[i].Name);
// [BB] Fall back and check if Name is relative.
if (!s->skins[i].isValid())

View file

@ -35,27 +35,13 @@
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _WIN32
#include <io.h>
#define stat _stat
#else
#include <dirent.h>
#ifndef __sun
#include <fts.h>
#endif
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include "doomtype.h"
#include "tarray.h"
#include "resourcefile.h"
#include "zstring.h"
#include "cmdlib.h"
#include "doomerrors.h"
@ -185,46 +171,6 @@ int FDirectory::AddDirectory(const char *dirpath)
return count;
}
#elif defined(__sun) || defined(__APPLE__)
int FDirectory::AddDirectory(const char *dirpath)
{
int count = 0;
TArray<FString> scanDirectories;
scanDirectories.Push(dirpath);
for(unsigned int i = 0;i < scanDirectories.Size();i++)
{
DIR* directory = opendir(scanDirectories[i].GetChars());
if (directory == NULL)
{
Printf("Could not read directory: %s\n", strerror(errno));
return 0;
}
struct dirent *file;
while((file = readdir(directory)) != NULL)
{
if(file->d_name[0] == '.') //File is hidden or ./.. directory so ignore it.
continue;
FString fullFileName = scanDirectories[i] + file->d_name;
struct stat fileStat;
stat(fullFileName.GetChars(), &fileStat);
if(S_ISDIR(fileStat.st_mode))
{
scanDirectories.Push(scanDirectories[i] + file->d_name + "/");
continue;
}
AddEntry(scanDirectories[i] + file->d_name, fileStat.st_size);
count++;
}
closedir(directory);
}
return count;
}
#else
//==========================================================================
@ -249,6 +195,10 @@ int FDirectory::AddDirectory(const char *dirpath)
Printf("Failed to start directory traversal: %s\n", strerror(errno));
return 0;
}
const size_t namepos = strlen(Filename);
FString pathfix;
while ((ent = fts_read(fts)) != NULL)
{
if (ent->fts_info == FTS_D && ent->fts_name[0] == '.')
@ -266,7 +216,22 @@ int FDirectory::AddDirectory(const char *dirpath)
// We're only interested in remembering files.
continue;
}
AddEntry(ent->fts_path, ent->fts_statp->st_size);
// Some implementations add an extra separator between
// root of the hierarchy and entity's path.
// It needs to be removed in order to resolve
// lumps' relative paths properly.
const char* path = ent->fts_path;
if ('/' == path[namepos])
{
pathfix = FString(path, namepos);
pathfix.AppendCStrPart(&path[namepos + 1], ent->fts_pathlen - namepos - 1);
path = pathfix.GetChars();
}
AddEntry(path, ent->fts_statp->st_size);
count++;
}
fts_close(fts);

View file

@ -542,7 +542,7 @@ static void time_to_dos(struct tm *time, unsigned short *dosdate, unsigned short
//
//==========================================================================
int AppendToZip(FILE *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time)
int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time)
{
FZipLocalFileHeader local;
int position;
@ -562,12 +562,12 @@ int AppendToZip(FILE *zip_file, const char *filename, FCompressedBuffer &content
// Fill in local directory header.
position = (int)ftell(zip_file);
position = (int)zip_file->Tell();
// Write out the header, file name, and file data.
if (fwrite(&local, sizeof(local), 1, zip_file) != 1 ||
fwrite(filename, strlen(filename), 1, zip_file) != 1 ||
fwrite(content.mBuffer, 1, content.mCompressedSize, zip_file) != content.mCompressedSize)
if (zip_file->Write(&local, sizeof(local)) != sizeof(local) ||
zip_file->Write(filename, strlen(filename)) != strlen(filename) ||
zip_file->Write(content.mBuffer, content.mCompressedSize) != content.mCompressedSize)
{
return -1;
}
@ -583,7 +583,7 @@ int AppendToZip(FILE *zip_file, const char *filename, FCompressedBuffer &content
//
//==========================================================================
int AppendCentralDirectory(FILE *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time, int position)
int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, uint16_t date, uint16_t time, int position)
{
FZipCentralDirectoryInfo dir;
@ -607,8 +607,8 @@ int AppendCentralDirectory(FILE *zip_file, const char *filename, FCompressedBuff
dir.ExternalAttributes = 0;
dir.LocalHeaderOffset = LittleLong(position);
if (fwrite(&dir, sizeof(dir), 1, zip_file) != 1 ||
fwrite(filename, strlen(filename), 1, zip_file) != 1)
if (zip_file->Write(&dir, sizeof(dir)) != sizeof(dir) ||
zip_file->Write(filename, strlen(filename)) != strlen(filename))
{
return -1;
}
@ -629,7 +629,7 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
if (filenames.Size() != content.Size()) return false;
FILE *f = fopen(filename, "wb");
auto f = FileWriter::Open(filename);
if (f != nullptr)
{
for (unsigned i = 0; i < filenames.Size(); i++)
@ -637,19 +637,19 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
int pos = AppendToZip(f, filenames[i], content[i], mydate, mytime);
if (pos == -1)
{
fclose(f);
delete f;
remove(filename);
return false;
}
positions.Push(pos);
}
int dirofs = (int)ftell(f);
int dirofs = (int)f->Tell();
for (unsigned i = 0; i < filenames.Size(); i++)
{
if (AppendCentralDirectory(f, filenames[i], content[i], mydate, mytime, positions[i]) < 0)
{
fclose(f);
delete f;
remove(filename);
return false;
}
@ -662,15 +662,15 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
dirend.FirstDisk = 0;
dirend.NumEntriesOnAllDisks = dirend.NumEntries = LittleShort(filenames.Size());
dirend.DirectoryOffset = LittleLong(dirofs);
dirend.DirectorySize = LittleLong(ftell(f) - dirofs);
dirend.DirectorySize = LittleLong(f->Tell() - dirofs);
dirend.ZipCommentLength = 0;
if (fwrite(&dirend, sizeof(dirend), 1, f) != 1)
if (f->Write(&dirend, sizeof(dirend)) != sizeof(dirend))
{
fclose(f);
delete f;
remove(filename);
return false;
}
fclose(f);
delete f;
return true;
}
return false;

View file

@ -669,12 +669,11 @@ FExternalLump::FExternalLump(const char *_filename, int filesize)
if (filesize == -1)
{
FILE *f = fopen(_filename,"rb");
if (f != NULL)
FileReader f;
if (f.Open(_filename))
{
fseek(f, 0, SEEK_END);
LumpSize = ftell(f);
fclose(f);
LumpSize = f.GetLength();
}
else
{
@ -703,11 +702,11 @@ FExternalLump::~FExternalLump()
int FExternalLump::FillCache()
{
Cache = new char[LumpSize];
FILE *f = fopen(filename, "rb");
if (f != NULL)
FileReader f;
if (f.Open(filename))
{
fread(Cache, 1, LumpSize, f);
fclose(f);
f.Read(Cache, LumpSize);
}
else
{

View file

@ -39,6 +39,7 @@
#include "s_playlist.h"
#include "templates.h"
#include "v_text.h"
#include "files.h"
FPlayList::FPlayList (const char *path)
{
@ -53,7 +54,7 @@ bool FPlayList::ChangeList (const char *path)
{
FString playlistdir;
FString song;
FILE *file;
FileReader fr;
bool first;
bool pls;
int i;
@ -61,7 +62,7 @@ bool FPlayList::ChangeList (const char *path)
Songs.Clear();
Position = 0;
if ( (file = fopen (path, "rb")) == NULL)
if (!fr.Open(path))
{
Printf ("Could not open " TEXTCOLOR_BOLD "%s" TEXTCOLOR_NORMAL ": %s\n", path, strerror(errno));
return false;
@ -70,7 +71,7 @@ bool FPlayList::ChangeList (const char *path)
first = true;
pls = false;
playlistdir = ExtractFilePath(path);
while ((song = NextLine(file)).IsNotEmpty())
while ((song = NextLine(&fr)).IsNotEmpty())
{
if (first)
{
@ -129,19 +130,17 @@ bool FPlayList::ChangeList (const char *path)
Songs.Push(song);
}
}
fclose (file);
return Songs.Size() != 0;
}
FString FPlayList::NextLine (FILE *file)
FString FPlayList::NextLine (FileReader *file)
{
char buffer[512];
char *skipper;
do
{
if (NULL == fgets (buffer, countof(buffer), file))
if (NULL == file->Gets (buffer, countof(buffer)))
return "";
for (skipper = buffer; *skipper != 0 && *skipper <= ' '; skipper++)

View file

@ -34,6 +34,8 @@
#ifndef __S_PLAYLIST_H__
#define __S_PLAYLIST_H__
class FileReader;
class FPlayList
{
public:
@ -51,7 +53,7 @@ public:
const char *GetSong (int position) const;
private:
static FString NextLine (FILE *file);
static FString NextLine (FileReader *file);
unsigned int Position;
TArray<FString> Songs;

View file

@ -244,18 +244,25 @@ void FScanner::Open (const char *name)
//
//==========================================================================
void FScanner::OpenFile (const char *name)
bool FScanner::OpenFile (const char *name)
{
uint8_t *filebuf;
int filesize;
Close ();
filesize = M_ReadFile (name, &filebuf);
FileReader fr(name);
if (!fr.Open(name)) return false;
auto filesize = fr.GetLength();
auto filebuf = new uint8_t[filesize];
if (fr.Read(filebuf, filesize) != filesize)
{
delete[] filebuf;
return false;
}
ScriptBuffer = FString((const char *)filebuf, filesize);
delete[] filebuf;
ScriptName = name; // This is used for error messages so the full file name is preferable
LumpNum = -1;
PrepareScript ();
return true;
}
//==========================================================================

View file

@ -19,7 +19,7 @@ public:
FScanner &operator=(const FScanner &other);
void Open(const char *lumpname);
void OpenFile(const char *filename);
bool OpenFile(const char *filename);
void OpenMem(const char *name, const char *buffer, int size);
void OpenString(const char *name, FString buffer);
void OpenLumpNum(int lump);

View file

@ -462,11 +462,11 @@ static void DoParse(int lumpnum)
FString filename = Wads.GetLumpFullPath(lumpnum);
filename.ReplaceChars(":\\/?|", '.');
filename << ".ast";
FILE *ff = fopen(filename, "w");
FileWriter *ff = FileWriter::Open(filename);
if (ff != NULL)
{
fputs(ast.GetChars(), ff);
fclose(ff);
ff->Write(ast.GetChars(), ast.Len());
delete ff;
}
}

View file

@ -803,18 +803,17 @@ CCMD (writemidi)
}
TArray<uint8_t> midi;
FILE *f;
bool success;
static_cast<MIDIStreamer *>(currSong)->CreateSMF(midi, 1);
f = fopen(argv[1], "wb");
auto f = FileWriter::Open(argv[1]);
if (f == NULL)
{
Printf("Could not open %s.\n", argv[1]);
return;
}
success = (fwrite(&midi[0], 1, midi.Size(), f) == (size_t)midi.Size());
fclose (f);
success = (f->Write(&midi[0], midi.Size()) == (size_t)midi.Size());
delete f;
if (!success)
{

View file

@ -239,7 +239,7 @@ public:
void Stop();
protected:
FILE *File;
FileWriter *File;
};
// WildMidi implementation of a MIDI device ---------------------------------

View file

@ -40,6 +40,7 @@
#include "m_swap.h"
#include "w_wad.h"
#include "opl.h"
#include "files.h"
// MACROS ------------------------------------------------------------------
@ -48,7 +49,7 @@
class OPLDump : public OPLEmul
{
public:
OPLDump(FILE *file) : File(file), TimePerTick(0), CurTime(0),
OPLDump(FileWriter *file) : File(file), TimePerTick(0), CurTime(0),
CurIntTime(0), TickMul(1), CurChip(0) {}
// If we're doing things right, these should never be reset.
@ -66,7 +67,7 @@ public:
virtual void WriteDelay(int ticks) = 0;
protected:
FILE *File;
FileWriter *File;
double TimePerTick; // in milliseconds
double CurTime;
int CurIntTime;
@ -91,10 +92,10 @@ protected:
class OPL_RDOSdump : public OPLDump
{
public:
OPL_RDOSdump(FILE *file) : OPLDump(file)
OPL_RDOSdump(FileWriter *file) : OPLDump(file)
{
assert(File != NULL);
fwrite("RAWADATA\0", 1, 10, File);
file->Write("RAWADATA\0", 10);
NeedClockRate = true;
}
virtual ~OPL_RDOSdump()
@ -102,8 +103,8 @@ public:
if (File != NULL)
{
uint16_t endmark = 0xFFFF;
fwrite(&endmark, 2, 1, File);
fclose(File);
File->Write(&endmark, 2);
delete File;
}
}
@ -114,13 +115,13 @@ public:
if (chipnum != CurChip)
{
uint8_t switcher[2] = { (uint8_t)(chipnum + 1), 2 };
fwrite(switcher, 1, 2, File);
File->Write(switcher, 2);
}
reg &= 255;
if (reg != 0 && reg != 2 && (reg != 255 || v != 255))
{
uint8_t cmd[2] = { uint8_t(v), uint8_t(reg) };
fwrite(cmd, 1, 2, File);
File->Write(cmd, 2);
}
}
@ -146,15 +147,15 @@ public:
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);
File->Seek(8, SEEK_SET);
File->Write(&clock_word, 2);
File->Seek(0, SEEK_END);
NeedClockRate = false;
}
else
{ // Change the clock rate in the middle of the song.
uint8_t clock_change[4] = { 0, 2, uint8_t(clock_word & 255), uint8_t(clock_word >> 8) };
fwrite(clock_change, 1, 4, File);
File->Write(clock_change, 4);
}
}
virtual void WriteDelay(int ticks)
@ -170,10 +171,10 @@ public:
{
ticks -= 255;
delay[0] = 255;
fwrite(delay, 1, 2, File);
File->Write(delay, 2);
}
delay[0] = uint8_t(ticks);
fwrite(delay, 1, 2, File);
File->Write(delay, 2);
}
}
protected:
@ -183,30 +184,30 @@ protected:
class OPL_DOSBOXdump : public OPLDump
{
public:
OPL_DOSBOXdump(FILE *file, bool dual) : OPLDump(file), Dual(dual)
OPL_DOSBOXdump(FileWriter *file, bool dual) : OPLDump(file), Dual(dual)
{
assert(File != NULL);
fwrite("DBRAWOPL"
File->Write("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);
20);
char type[4] = { (char)(Dual * 2), 0, 0, 0 }; // Single or dual OPL-2
fwrite(type, 1, 4, File);
File->Write(type, 4);
}
virtual ~OPL_DOSBOXdump()
{
if (File != NULL)
{
long where_am_i = ftell(File);
long where_am_i =File->Tell();
uint32_t len[2];
fseek(File, 12, SEEK_SET);
File->Seek(12, SEEK_SET);
len[0] = LittleLong(CurIntTime);
len[1] = LittleLong(uint32_t(where_am_i - 24));
fwrite(len, 4, 2, File);
fclose(File);
File->Write(len, 8);
delete File;
}
}
virtual void WriteReg(int reg, int v)
@ -216,11 +217,12 @@ public:
if (chipnum != CurChip)
{
CurChip = chipnum;
fputc(chipnum + 2, File);
chipnum += 2;
File->Write(&chipnum, 1);
}
reg &= 255;
uint8_t cmd[3] = { 4, uint8_t(reg), uint8_t(v) };
fwrite (cmd + (reg > 4), 1, 3 - (reg > 4), File);
File->Write(cmd + (reg > 4), 3 - (reg > 4));
}
virtual void WriteDelay(int ticks)
{
@ -234,20 +236,20 @@ public:
while (delay > 65536)
{
uint8_t cmd[3] = { 1, 255, 255 };
fwrite(cmd, 1, 2, File);
File->Write(cmd, 2);
delay -= 65536;
}
delay--;
if (delay <= 255)
{
uint8_t cmd[2] = { 0, uint8_t(delay) };
fwrite(cmd, 1, 2, File);
File->Write(cmd, 2);
}
else
{
assert(delay <= 65535);
uint8_t cmd[3] = { 1, uint8_t(delay & 255), uint8_t(delay >> 8) };
fwrite(cmd, 1, 3, File);
File->Write(cmd, 3);
}
}
}
@ -338,7 +340,7 @@ DiskWriterIO::~DiskWriterIO()
int DiskWriterIO::Init(uint32_t numchips, bool, bool initopl3)
{
FILE *file = fopen(Filename, "wb");
FileWriter *file = FileWriter::Open(Filename);
if (file == NULL)
{
Printf("Could not open %s for writing.\n", Filename.GetChars());

View file

@ -89,7 +89,7 @@ struct FmtChunk
TimidityMIDIDevice::TimidityMIDIDevice(const char *args)
{
Renderer = NULL;
Renderer = nullptr;
Renderer = new Timidity::Renderer((float)SampleRate, args);
}
@ -102,7 +102,7 @@ TimidityMIDIDevice::TimidityMIDIDevice(const char *args)
TimidityMIDIDevice::~TimidityMIDIDevice()
{
Close();
if (Renderer != NULL)
if (Renderer != nullptr)
{
delete Renderer;
}
@ -246,10 +246,10 @@ FString TimidityMIDIDevice::GetStats()
//==========================================================================
TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename, int rate)
:TimidityMIDIDevice(NULL)
:TimidityMIDIDevice(nullptr)
{
File = fopen(filename, "wb");
if (File != NULL)
File = FileWriter::Open(filename);
if (File != nullptr)
{ // Write wave header
uint32_t work[3];
FmtChunk fmt;
@ -257,7 +257,7 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename,
work[0] = MAKE_ID('R','I','F','F');
work[1] = 0; // filled in later
work[2] = MAKE_ID('W','A','V','E');
if (3 != fwrite(work, 4, 3, File)) goto fail;
if (4*3 != File->Write(work, 4 * 3)) goto fail;
fmt.ChunkID = MAKE_ID('f','m','t',' ');
fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8));
@ -281,17 +281,17 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename,
fmt.SubFormatD[5] = 0x38;
fmt.SubFormatD[6] = 0x9b;
fmt.SubFormatD[7] = 0x71;
if (1 != fwrite(&fmt, sizeof(fmt), 1, File)) goto fail;
if (sizeof(fmt) != File->Write(&fmt, sizeof(fmt))) goto fail;
work[0] = MAKE_ID('d','a','t','a');
work[1] = 0; // filled in later
if (2 != fwrite(work, 4, 2, File)) goto fail;
if (8 !=File->Write(work, 8)) goto fail;
return;
fail:
Printf("Failed to write %s: %s\n", filename, strerror(errno));
fclose(File);
File = NULL;
delete File;
File = nullptr;
}
}
@ -303,30 +303,30 @@ fail:
TimidityWaveWriterMIDIDevice::~TimidityWaveWriterMIDIDevice()
{
if (File != NULL)
if (File != nullptr)
{
long pos = ftell(File);
long pos = File->Tell();
uint32_t size;
// data chunk size
size = LittleLong(uint32_t(pos - 8));
if (0 == fseek(File, 4, SEEK_SET))
if (0 == File->Seek(4, SEEK_SET))
{
if (1 == fwrite(&size, 4, 1, File))
if (4 == File->Write(&size, 4))
{
size = LittleLong(uint32_t(pos - 12 - sizeof(FmtChunk) - 8));
if (0 == fseek(File, 4 + sizeof(FmtChunk) + 4, SEEK_CUR))
if (0 == File->Seek(4 + sizeof(FmtChunk) + 4, SEEK_CUR))
{
if (1 == fwrite(&size, 4, 1, File))
if (1 == File->Write(&size, 4))
{
fclose(File);
delete File;
return;
}
}
}
}
Printf("Could not finish writing wave file: %s\n", strerror(errno));
fclose(File);
delete File;
}
}
@ -342,7 +342,7 @@ int TimidityWaveWriterMIDIDevice::Resume()
while (ServiceStream(writebuffer, sizeof(writebuffer)))
{
if (fwrite(writebuffer, sizeof(writebuffer), 1, File) != 1)
if (File->Write(writebuffer, sizeof(writebuffer)) != sizeof(writebuffer))
{
Printf("Could not write entire wave file: %s\n", strerror(errno));
return 1;

View file

@ -43,6 +43,7 @@
#include "templates.h"
#include "version.h"
#include "tmpfileplus.h"
#include "m_misc.h"
#ifndef _WIN32
#include <unistd.h>
@ -82,7 +83,7 @@ public:
protected:
bool LaunchTimidity();
char* DiskName;
FString DiskName;
#ifdef _WIN32
HANDLE ReadWavePipe;
HANDLE WriteWavePipe;
@ -165,8 +166,7 @@ CUSTOM_CVAR (Int, timidity_frequency, 44100, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//
//==========================================================================
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
: DiskName(nullptr),
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args) :
#ifdef _WIN32
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
ChildProcess(INVALID_HANDLE_VALUE),
@ -204,10 +204,9 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
TimidityPPMIDIDevice::~TimidityPPMIDIDevice ()
{
if (nullptr != DiskName)
if (DiskName.IsNotEmpty())
{
remove(DiskName);
free(DiskName);
}
#if _WIN32
@ -257,7 +256,10 @@ bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
// Write MIDI song to temporary file
song->CreateSMF(midi, looping ? 0 : 1);
f = tmpfileplus(nullptr, "zmid", &DiskName, 1);
FString path = M_GetAppDataPath(false);
path += "/tmp";
CreatePath(path);
f = tmpfileplus(path, "zmid", &DiskName, 1);
if (f == NULL)
{
Printf(PRINT_BOLD, "Could not open temp music file\n");
@ -454,7 +456,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity()
bool TimidityPPMIDIDevice::LaunchTimidity ()
{
if (ExeName.IsEmpty() || nullptr == DiskName)
if (ExeName.IsEmpty() || DiskName.IsEmpty())
{
return false;
}
@ -565,7 +567,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
arglist.push_back("-");
arglist.push_back(outmodearg.c_str());
arglist.push_back(ifacearg.c_str());
arglist.push_back(DiskName);
arglist.push_back(DiskName.GetChars());
DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", exename);
int i = 1;

View file

@ -72,6 +72,7 @@
#include "m_crc32.h"
#include "serializer.h"
#include "g_levellocals.h"
#include "files.h"
CVAR(Int, savestatistics, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(String, statfile, "zdoomstat.txt", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -136,7 +137,7 @@ static void ParseStatistics(const char *fn, TArray<FStatistics> &statlist)
try
{
FScanner sc;
sc.OpenFile(fn);
if (!sc.OpenFile(fn)) return;
while (sc.GetString())
{
@ -260,8 +261,8 @@ static void SaveStatistics(const char *fn, TArray<FStatistics> &statlist)
{
unsigned int j;
FILE * f = fopen(fn, "wt");
if (f==NULL) return;
FileWriter *fw = FileWriter::Open(fn);
if (fw == nullptr) return;
qsort(&statlist[0], statlist.Size(), sizeof(statlist[0]), compare_episode_names);
for(unsigned i=0;i<statlist.Size ();i++)
@ -270,34 +271,34 @@ static void SaveStatistics(const char *fn, TArray<FStatistics> &statlist)
qsort(&ep_stats.stats[0], ep_stats.stats.Size(), sizeof(ep_stats.stats[0]), compare_dates);
fprintf(f, "%s \"%s\"\n{\n", ep_stats.epi_header.GetChars(), ep_stats.epi_name.GetChars());
fw->Printf("%s \"%s\"\n{\n", ep_stats.epi_header.GetChars(), ep_stats.epi_name.GetChars());
for(j=0;j<ep_stats.stats.Size();j++)
{
FSessionStatistics *sst = &ep_stats.stats[j];
if (sst->info[0]>0)
{
fprintf(f,"\t%2i. %10s \"%-22s\" %02d:%02d:%02d %i\n", j+1, sst->name, sst->info,
fw->Printf("\t%2i. %10s \"%-22s\" %02d:%02d:%02d %i\n", j+1, sst->name, sst->info,
hours(sst->timeneeded), minutes(sst->timeneeded), seconds(sst->timeneeded), sst->skill);
TArray<FLevelStatistics> &ls = sst->levelstats;
if (ls.Size() > 0)
{
fprintf(f,"\t{\n");
fw->Printf("\t{\n");
qsort(&ls[0], ls.Size(), sizeof(ls[0]), compare_level_names);
for(unsigned k=0;k<ls.Size ();k++)
{
fprintf(f, "\t\t%-8s \"%-22s\" %02d:%02d:%02d\n", ls[k].name, ls[k].info,
fw->Printf("\t\t%-8s \"%-22s\" %02d:%02d:%02d\n", ls[k].name, ls[k].info,
hours(ls[k].timeneeded), minutes(ls[k].timeneeded), seconds(ls[k].timeneeded));
}
fprintf(f,"\t}\n");
fw->Printf("\t}\n");
}
}
}
fprintf(f,"}\n\n");
fw->Printf("}\n\n");
}
fclose(f);
delete fw;
}

View file

@ -306,15 +306,16 @@ int FTextureManager::CountBuildTiles ()
FString artpath = rffpath;
artpath += artfile;
FILE *f = fopen (artpath, "rb");
if (f == NULL)
FileReader fr;
if (!fr.Open(artpath))
{
break;
}
size_t len = Q_filelength (f);
long len = fr.GetLength();
uint8_t *art = new uint8_t[len];
if (fread (art, 1, len, f) != len || (numtiles = CountTiles(art)) == 0)
if (fr.Read (art, len) != len || (numtiles = CountTiles(art)) == 0)
{
delete[] art;
}
@ -323,7 +324,6 @@ int FTextureManager::CountBuildTiles ()
BuildTileFiles.Push (art);
totaltiles += numtiles;
}
fclose (f);
}
}

View file

@ -67,23 +67,6 @@
*
*/
/* ADDED IN v2.0 */
/*
* NAME
* tmpfileplus_f - create a unique temporary file with filename stored in a fixed-length buffer
*
* SYNOPSIS
* FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
*
* DESCRIPTION
* Same as tmpfileplus() except receives filename in a fixed-length buffer. No allocated memory to free.
* ERRORS
* E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
*/
#include "tmpfileplus.h"
#include <stdio.h>
@ -112,75 +95,38 @@
#define FDOPEN_ fdopen
#endif
#include "m_random.h"
#include "cmdlib.h"
#include "zstring.h"
/* DEBUGGING STUFF */
#if defined(_DEBUG) && defined(SHOW_DPRINTF)
#define DPRINTF1(s, a1) printf(s, a1)
#else
#define DPRINTF1(s, a1)
#endif
#ifdef _WIN32
#define FILE_SEPARATOR "\\"
#else
#define FILE_SEPARATOR "/"
#endif
#define RANDCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define NRANDCHARS (sizeof(RANDCHARS) - 1)
static FRandom pr_tmpfile;
/** Replace each byte in string s with a random character from TEMPCHARS */
static char *set_randpart(char *s)
{
size_t i;
unsigned int r;
static unsigned int seed; /* NB static */
if (seed == 0)
{ /* First time set our seed using current time and clock */
seed = ((unsigned)time(NULL)<<8) ^ (unsigned)clock();
}
srand(seed++);
for (i = 0; i < strlen(s); i++)
{
r = rand() % NRANDCHARS;
r = pr_tmpfile() % NRANDCHARS;
s[i] = (RANDCHARS)[r];
}
return s;
}
/** Return 1 if path is a valid directory otherwise 0 */
static int is_valid_dir(const char *path)
{
struct stat st;
if ((stat(path, &st) == 0) && (st.st_mode & S_IFDIR))
return 1;
return 0;
}
/** Call getenv and save a copy in buf */
static char *getenv_save(const char *varname, char *buf, size_t bufsize)
{
char *ptr = getenv(varname);
buf[0] = '\0';
if (ptr)
{
strncpy(buf, ptr, bufsize);
buf[bufsize-1] = '\0';
return buf;
}
return NULL;
}
/**
* Try and create a randomly-named file in directory `tmpdir`.
* If successful, allocate memory and set `tmpname_ptr` to full filepath, and return file pointer;
* otherwise return NULL.
* If `keep` is zero then create the file as temporary and it should not exist once closed.
*/
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmpname_ptr, int keep)
static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, FString *tmpname_ptr, int keep)
/* PRE:
* pfx is not NULL and points to a valid null-terminated string
* tmpname_ptr is not NULL.
@ -189,14 +135,12 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
FILE *fp;
int fd;
char randpart[] = "1234567890";
size_t lentempname;
int i;
char *tmpname = NULL;
int oflag, pmode;
/* In Windows, we use the _O_TEMPORARY flag with `open` to ensure the file is deleted when closed.
* In Unix, we use the unlink function after opening the file. (This does not work in Windows,
* which does not allow an open file to be unlinked.)
* In Unix, we use the remove function after opening the file. (This does not work in Windows,
* which does not allow an open file to be deleted.)
*/
#ifdef _WIN32
/* MSVC flags */
@ -210,28 +154,20 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
pmode = S_IRUSR|S_IWUSR;
#endif
if (!tmpdir || !is_valid_dir(tmpdir)) {
if (!tmpdir || !DirExists(tmpdir)) {
errno = ENOENT;
return NULL;
}
lentempname = strlen(tmpdir) + strlen(FILE_SEPARATOR) + strlen(pfx) + strlen(randpart);
DPRINTF1("lentempname=%d\n", lentempname);
tmpname = malloc(lentempname + 1);
if (!tmpname)
{
errno = ENOMEM;
return NULL;
}
FString tempname;
/* If we don't manage to create a file after 10 goes, there is something wrong... */
for (i = 0; i < 10; i++)
{
sprintf(tmpname, "%s%s%s%s", tmpdir, FILE_SEPARATOR, pfx, set_randpart(randpart));
DPRINTF1("[%s]\n", tmpname);
fd = OPEN_(tmpname, oflag, pmode);
tempname.Format("%s/%s%s", tmpdir, pfx, set_randpart(randpart));
fd = OPEN_(tempname, oflag, pmode);
if (fd != -1) break;
}
DPRINTF1("strlen(tmpname)=%d\n", strlen(tmpname));
if (fd != -1)
{ /* Success, so return user a proper ANSI C file pointer */
fp = FDOPEN_(fd, "w+b");
@ -239,7 +175,7 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
#ifndef _WIN32
/* [Unix only] And make sure the file will be deleted once closed */
if (!keep) remove(tmpname);
if (!keep) remove(tempname);
#endif
}
@ -247,13 +183,8 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
{ /* We failed */
fp = NULL;
}
if (!fp)
{
free(tmpname);
tmpname = NULL;
}
*tmpname_ptr = tmpname;
if (tmpname_ptr) *tmpname_ptr = tempname;
return fp;
}
@ -261,77 +192,10 @@ static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmp
/* EXPORTED FUNCTIONS */
/**********************/
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep)
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep)
{
FILE *fp = NULL;
char *tmpname = NULL;
char *tmpdir = NULL;
const char *pfx = (prefix ? prefix : "tmp.");
char *tempdirs[12] = { 0 };
char env1[FILENAME_MAX+1] = { 0 };
char env2[FILENAME_MAX+1] = { 0 };
char env3[FILENAME_MAX+1] = { 0 };
int ntempdirs = 0;
int i;
/* Set up a list of temp directories we will try in order */
i = 0;
tempdirs[i++] = (char *)dir;
#ifdef _WIN32
tempdirs[i++] = getenv_save("TMP", env1, sizeof(env1));
tempdirs[i++] = getenv_save("TEMP", env2, sizeof(env2));
#else
tempdirs[i++] = getenv_save("TMPDIR", env3, sizeof(env3));
tempdirs[i++] = P_tmpdir;
#endif
tempdirs[i++] = ".";
ntempdirs = i;
errno = 0;
/* Work through list we set up before, and break once we are successful */
for (i = 0; i < ntempdirs; i++)
{
tmpdir = tempdirs[i];
DPRINTF1("Trying tmpdir=[%s]\n", tmpdir);
fp = mktempfile_internal(tmpdir, pfx, &tmpname, keep);
if (fp) break;
}
/* If we succeeded and the user passed a pointer, set it to the alloc'd pathname: the user must free this */
if (fp && pathname)
*pathname = tmpname;
else /* Otherwise, free the alloc'd memory */
free(tmpname);
FILE *fp = mktempfile_internal(dir, (prefix ? prefix : "tmp."), pathname, keep);
if (!fp && pathname) *pathname = "";
return fp;
}
/* Same as tmpfileplus() but with fixed length buffer for output filename and no memory allocation */
FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep)
{
char *tmpbuf = NULL;
FILE *fp;
/* If no buffer provided, do the normal way */
if (!pathnamebuf || (int)pathsize <= 0) {
return tmpfileplus(dir, prefix, NULL, keep);
}
/* Call with a temporary buffer */
fp = tmpfileplus(dir, prefix, &tmpbuf, keep);
if (fp && strlen(tmpbuf) > pathsize - 1) {
/* Succeeded but not enough room in output buffer, so clean up and return an error */
pathnamebuf[0] = 0;
fclose(fp);
if (keep) remove(tmpbuf);
free(tmpbuf);
errno = E2BIG;
return NULL;
}
/* Copy name into buffer */
strcpy(pathnamebuf, tmpbuf);
free(tmpbuf);
return fp;
}

View file

@ -23,9 +23,7 @@
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
class FString;
/** Create a unique temporary file.
@param dir (optional) directory to create file. If NULL use default TMP directory.
@ -37,25 +35,9 @@ extern "C" {
@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
@exception ENOMEM Not enough memory to allocate filename.
*/
FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
FILE *tmpfileplus(const char *dir, const char *prefix, FString *pathname, int keep);
/** Create a unique temporary file with filename stored in a fixed-length buffer.
@param dir (optional) directory to create file. If NULL use default directory.
@param prefix (optional) prefix for file name. If NULL use "tmp.".
@param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL.
@param pathsize Size of buffer to receive filename and its terminating null character.
@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
Otherwise file is automatically deleted when closed.
@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
@exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
*/
FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
#define TMPFILE_KEEP 1
#ifdef __cplusplus
}
#endif
#endif /* end TMPFILEPLUS_H_ */

View file

@ -890,9 +890,10 @@ int FFont::StringWidth(const uint8_t *string) const
while (*string)
{
if (*string == TEXTCOLOR_ESCAPE)
auto chr = GetCharFromString(string);
if (chr == TEXTCOLOR_ESCAPE)
{
++string;
// We do not need to check for UTF-8 in here.
if (*string == '[')
{
while (*string != '\0' && *string != ']')
@ -906,16 +907,15 @@ int FFont::StringWidth(const uint8_t *string) const
}
continue;
}
else if (*string == '\n')
else if (chr == '\n')
{
if (w > maxw)
maxw = w;
w = 0;
++string;
}
else
{
w += GetCharWidth(*string++) + GlobalKerning;
w += GetCharWidth(chr) + GlobalKerning;
}
}

View file

@ -51,6 +51,78 @@
int ListGetInt(VMVa_List &tags);
//==========================================================================
//
// reads one character from the string.
// This can handle both ISO 8859-1 and UTF-8, as well as mixed strings
// between both encodings, which may happen if inconsistent encoding is
// used between different files in a mod.
//
//==========================================================================
int GetCharFromString(const uint8_t *&string)
{
int z, y, x;
z = *string++;
if (z < 192)
{
return z;
}
else if (z <= 223)
{
y = *string++;
if (y < 128 || y >= 192)
{
// not an UTF-8 sequence so return the first byte unchanged
string--;
}
else
{
z = (z - 192) * 64 + (y - 128);
}
}
else if (z >= 224 && z <= 239)
{
y = *string++;
if (y < 128 || y >= 192)
{
// not an UTF-8 sequence so return the first byte unchanged
string--;
}
else
{
x = *string++;
if (x < 128 || x >= 192)
{
// not an UTF-8 sequence so return the first byte unchanged
string -= 2;
}
else
{
z = (z - 224) * 4096 + (y - 128) * 64 + (x - 128);
}
}
}
else if (z >= 240)
{
y = *string++;
if (y < 128 || y >= 192)
{
// not an UTF-8 sequence so return the first byte unchanged
string--;
}
else
{
// we do not support 4-Byte UTF-8 here
string += 2;
return '?';
}
}
return z;
}
//==========================================================================
//
// DrawChar
@ -170,7 +242,7 @@ void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, c
while ((const char *)ch - string < parms.maxstrlen)
{
c = *ch++;
c = GetCharFromString(ch);
if (!c)
break;
@ -288,7 +360,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
w = 0;
while ( (c = *string++) )
while ( (c = GetCharFromString(string)) )
{
if (c == TEXTCOLOR_ESCAPE)
{

View file

@ -86,4 +86,6 @@ inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, b
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr)
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor, count); }
int GetCharFromString(const uint8_t *&string);
#endif //__V_TEXT_H__

View file

@ -233,14 +233,12 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
if (wadinfo == NULL)
{
// Does this exist? If so, is it a directory?
struct stat info;
if (stat(filename, &info) != 0)
if (!DirEntryExists(filename, &isdir))
{
Printf(TEXTCOLOR_RED "Could not stat %s\n", filename);
Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename);
PrintLastError();
return;
}
isdir = (info.st_mode & S_IFDIR) != 0;
if (!isdir)
{
@ -1554,7 +1552,7 @@ FWadLump::FWadLump(int lumpnum, FResourceLump *lump)
// Uncompressed lump in a file. For this we will have to open a new FILE, since we need it for streaming
int fileno = Wads.GetLumpFile(lumpnum);
const char *filename = Wads.GetWadFullName(fileno);
File = fopen(filename, "rb");
File = openfd(filename);
if (File != NULL)
{
Length = lump->LumpSize;

View file

@ -153,6 +153,33 @@ bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create
}
}
//===========================================================================
//
// M_GetAppDataPath Windows
//
// Returns the path for the AppData folder.
//
//===========================================================================
FString M_GetAppDataPath(bool create)
{
FString path;
if (!GetKnownFolder(CSIDL_LOCAL_APPDATA, FOLDERID_LocalAppData, create, path))
{ // Failed (e.g. On Win9x): use program directory
path = progdir;
}
// Don't use GAME_DIR and such so that ZDoom and its child ports can
// share the node cache.
path += "/" GAMENAMELOWERCASE;
path.Substitute("//", "/"); // needed because progdir ends with a slash.
if (create)
{
CreatePath(path);
}
return path;
}
//===========================================================================
//
// M_GetCachePath Windows
@ -173,6 +200,10 @@ FString M_GetCachePath(bool create)
// share the node cache.
path += "/zdoom/cache";
path.Substitute("//", "/"); // needed because progdir ends with a slash.
if (create)
{
CreatePath(path);
}
return path;
}
@ -349,3 +380,41 @@ FString M_GetSavegamesPath()
}
return path;
}
//===========================================================================
//
// M_GetDocumentsPath Windows
//
// Returns the path to the default documents directory.
//
//===========================================================================
FString M_GetDocumentsPath()
{
FString path;
// A portable INI means that this storage location should also be portable.
path.Format("%s" GAMENAME "_portable.ini", progdir.GetChars());
if (FileExists(path))
{
return progdir;
}
if (!UseKnownFolders())
{
return progdir;
}
// Try defacto My Documents/My Games folder
else if (GetKnownFolder(CSIDL_PERSONAL, FOLDERID_Documents, true, path))
{
// I assume since this isn't a standard folder, it doesn't have
// a localized name either.
path << "/My Games/" GAMENAME;
CreatePath(path);
}
else
{
path = progdir;
}
return path;
}

View file

@ -380,18 +380,7 @@ enum
BQS_InGameColormap,
};
#if 0
#define STARTLOG do { if (!dbg) dbg = fopen ("e:/vid.log", "w"); } while(0)
#define STOPLOG do { if (dbg) { fclose (dbg); dbg=NULL; } } while(0)
#define LOG(x) do { if (dbg) { fprintf (dbg, x); fflush (dbg); } } while(0)
#define LOG1(x,y) do { if (dbg) { fprintf (dbg, x, y); fflush (dbg); } } while(0)
#define LOG2(x,y,z) do { if (dbg) { fprintf (dbg, x, y, z); fflush (dbg); } } while(0)
#define LOG3(x,y,z,zz) do { if (dbg) { fprintf (dbg, x, y, z, zz); fflush (dbg); } } while(0)
#define LOG4(x,y,z,a,b) do { if (dbg) { fprintf (dbg, x, y, z, a, b); fflush (dbg); } } while(0)
#define LOG5(x,y,z,a,b,c) do { if (dbg) { fprintf (dbg, x, y, z, a, b, c); fflush (dbg); } } while(0)
extern FILE *dbg;
#define VID_FILE_DEBUG 1
#elif _DEBUG && 0
#if _DEBUG && 0
#define STARTLOG
#define STOPLOG
#define LOG(x) { OutputDebugString(x); }