diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1eb5ab037..8610691ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/b_game.cpp b/src/b_game.cpp index 1cb91ddf4..661d09c6e 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -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; -} \ No newline at end of file +} diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index 3c2e7e280..e58b3569f 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -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 &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; diff --git a/src/cmdlib.h b/src/cmdlib.h index e2119ed8a..76a2798da 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -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; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 87f1d589e..f68fd1d63 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -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(); } diff --git a/src/d_main.cpp b/src/d_main.cpp index 301be20f8..9d8055b0d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1946,13 +1946,11 @@ static FString CheckGameInfo(TArray & 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) { diff --git a/src/files.cpp b/src/files.cpp index 0de13e8ea..8ad4d6329 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -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, ...) { diff --git a/src/files.h b/src/files.h index 4c73273a1..808f24d94 100644 --- a/src/files.h +++ b/src/files.h @@ -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: diff --git a/src/g_game.cpp b/src/g_game.cpp index ec1a7be50..0adfa2fc9 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -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; diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.cpp b/src/gl/hqnx_asm/hqnx_asm_Image.cpp index 7af120173..31adda874 100644 --- a/src/gl/hqnx_asm/hqnx_asm_Image.cpp +++ b/src/gl/hqnx_asm/hqnx_asm_Image.cpp @@ -106,1078 +106,6 @@ int DLL CImage::Convert32To17( void ) return nRes; } -int DLL CImage::ConvertTo32( void ) -{ - int nRes = eConvUnknownFormat; - if ( m_pBitmap == NULL ) - return eConvSourceMemory; - - switch ( m_BitPerPixel ) - { - case 8: - { - nRes = 0; - m_BitPerPixel = 32; - unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*4); - if ( pNewBitmap != NULL ) - { - unsigned char * pTemp8 = m_pBitmap; - unsigned char * pTemp32 = pNewBitmap; - unsigned char c; - for ( int i=0; i> 3); - *(pTemp24++) = ((rgb & 0xF800) >> 8); - } - free(m_pBitmap); - m_pBitmap = pNewBitmap; - } - else - nRes = eConvDestMemory; - - break; - } - case 32: - { - nRes = 0; - m_BitPerPixel = 24; - unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*3); - if ( pNewBitmap != NULL ) - { - unsigned char * pTemp32 = m_pBitmap; - unsigned char * pTemp24 = pNewBitmap; - for ( int i=0; i> 3; - g = m_Pal[c].g >> 2; - b = m_Pal[c].b >> 3; - *(pTemp16++) = (r << 11) + (g << 5) + b; - } - free(m_pBitmap); - m_pBitmap = pNewBitmap; - } - else - nRes = eConvDestMemory; - - break; - } - case 24: - { - nRes = 0; - m_BitPerPixel = 16; - unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*2); - if ( pNewBitmap != NULL ) - { - unsigned char * pTemp24 = m_pBitmap; - unsigned short * pTemp16 = (unsigned short *)pNewBitmap; - unsigned short r, g, b; - for ( int i=0; i> 3; - g = (*(pTemp24++)) >> 2; - r = (*(pTemp24++)) >> 3; - *(pTemp16++) = (r << 11) + (g << 5) + b; - } - free(m_pBitmap); - m_pBitmap = pNewBitmap; - } - else - nRes = eConvDestMemory; - - break; - } - case 32: - { - nRes = 0; - m_BitPerPixel = 16; - unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*2); - if ( pNewBitmap != NULL ) - { - unsigned char * pTemp32 = m_pBitmap; - unsigned short * pTemp16 = (unsigned short *)pNewBitmap; - unsigned short r, g, b; - for ( int i=0; i> 3; - g = (*(pTemp32++)) >> 2; - r = (*(pTemp32++)) >> 3; - pTemp32++; - *(pTemp16++) = (r << 11) + (g << 5) + b; - } - free(m_pBitmap); - m_pBitmap = pNewBitmap; - } - else - nRes = eConvDestMemory; - - break; - } - } - - return nRes; -} - -int CImage::Convert8To17( int transindex ) -{ - int nRes = eConvUnknownFormat; - - if ( m_BitPerPixel == 8 ) - { - m_BitPerPixel = 32; - unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*4); - if ( pNewBitmap != NULL ) - { - unsigned char * pTemp8 = m_pBitmap; - unsigned int * pTemp32 = (unsigned int *)pNewBitmap; - unsigned int r, g, b; - unsigned char c; - for ( int i=0; i> 3; - g = m_Pal[c].g >> 2; - b = m_Pal[c].b >> 3; - *(pTemp32++) = (r << 11) + (g << 5) + b + (transindex != c ? 0x10000 : 0); - } - free(m_pBitmap); - m_pBitmap = pNewBitmap; - } - else - nRes = eConvDestMemory; - - nRes = 0; - } - - return nRes; -} - -int CImage::SaveBmp(char *szFilename) -{ - _BMPFILEHEADER fh; - _BMPIMAGEHEADER ih; - unsigned char BmpPal[256][4]; - long int SuffLen; - long int Dummy = 0; - unsigned char * pBuf; - short i; - - if (!(f = fopen(szFilename, "wb"))) return eSaveBmpFileOpen; - if ( m_pBitmap == NULL ) return eSaveBmpSourceMemory; - - fh.bfType=0x4D42; - if (m_BitPerPixel==8) - { - SuffLen=((m_Xres+3)/4)*4-m_Xres; - ih.biSize=0x28; - ih.biWidth=m_Xres; - ih.biHeight=m_Yres; - ih.biPlanes=1; - ih.biBitCount=8; - ih.biCompression=0; - ih.biSizeImage=(m_Xres+SuffLen)*m_Yres; - ih.biXPelsPerMeter=ih.biYPelsPerMeter=0x2E23; // 300dpi (pixels per meter) - ih.biClrUsed=ih.biClrImportant=0; - fh.bfSize=(ih.biSizeImage)+0x0436; - fh.bfRes1=0; - fh.bfOffBits=0x0436; - if (fwrite(&fh, 14, 1, f) != 1) return eSaveBmpFileWrite; - if (fwrite(&ih, 40, 1, f) != 1) return eSaveBmpFileWrite; - for (i=0; i<256; i++) - { - BmpPal[i][0]=m_Pal[i].b; - BmpPal[i][1]=m_Pal[i].g; - BmpPal[i][2]=m_Pal[i].r; - BmpPal[i][3]=0; - } - if (fwrite(&BmpPal, 1024, 1, f) != 1) return eSaveBmpFileWrite; - pBuf=m_pBitmap; - pBuf+=m_NumPixel; - for (i=0; i0) - { - if (fwrite(&Dummy, SuffLen, 1, f) != 1) return eSaveBmpFileWrite; - } - } - } - else - if (m_BitPerPixel==24) - { - SuffLen=((m_Xres*3+3)/4)*4-m_Xres*3; - ih.biSize=0x28; - ih.biWidth=m_Xres; - ih.biHeight=m_Yres; - ih.biPlanes=1; - ih.biBitCount=24; - ih.biCompression=0; - ih.biSizeImage=(m_Xres*3+SuffLen)*m_Yres; - ih.biXPelsPerMeter=ih.biYPelsPerMeter=0x2E23; // 300dpi (pixels per meter) - ih.biClrUsed=ih.biClrImportant=0; - fh.bfSize=(ih.biSizeImage)+0x0036; - fh.bfRes1=0; - fh.bfOffBits=0x0036; - if (fwrite(&fh, 14, 1, f) != 1) return eSaveBmpFileWrite; - if (fwrite(&ih, 40, 1, f) != 1) return eSaveBmpFileWrite; - pBuf=m_pBitmap; - pBuf+=m_NumPixel*3; - for (i=0; i0) - { - if (fwrite(&Dummy, SuffLen, 1, f) != 1) return eSaveBmpFileWrite; - } - } - } - else - return eSaveBmpColorDepth; - - fclose(f); - - return 0; -} - -int CImage::LoadBmp(char *szFilename) -{ - _BMPFILEHEADER fh; - _BMPIMAGEHEADEROLD ih_old; - _BMPIMAGEHEADER ih; - unsigned char BmpPal[256][4]; - long int biSize; - long int SuffLen; - long int Dummy = 0; - unsigned char * pBuf; - short i; - long int xres, yres; - unsigned short bits; - - if (!(f = fopen(szFilename, "rb"))) return eLoadBmpFileOpen; - if (fread(&fh, 14, 1, f) != 1) return eLoadBmpFileRead; - if (fh.bfType != 0x4D42) return eLoadBmpBadFormat; - if (fread(&biSize, 4, 1, f) != 1) return eLoadBmpFileRead; - if (biSize > 12) - { - fseek( f, -4, SEEK_CUR ); - if (fread(&ih, biSize, 1, f) != 1) return eLoadBmpFileRead; - xres = ih.biWidth; - yres = ih.biHeight; - bits = ih.biBitCount; - } - else - { - fseek( f, -4, SEEK_CUR ); - if (fread(&ih_old, biSize, 1, f) != 1) return eLoadBmpFileRead; - xres = ih_old.biWidth; - yres = ih_old.biHeight; - bits = ih_old.biBitCount; - } - - if ( Init( xres, yres, bits ) != 0 ) return eLoadBmpInit; - if (m_BitPerPixel==8) - { - SuffLen=((m_Xres+3)/4)*4-m_Xres; - if (fread(&BmpPal, 1024, 1, f) != 1) return eLoadBmpFileRead; - for (i=0; i<256; i++) - { - m_Pal[i].b=BmpPal[i][0]; - m_Pal[i].g=BmpPal[i][1]; - m_Pal[i].r=BmpPal[i][2]; - } - pBuf=m_pBitmap; - pBuf+=m_NumPixel; - for (i=0; i0) - { - if (fread(&Dummy, SuffLen, 1, f) != 1) return eLoadBmpFileRead; - } - } - } - else - if (m_BitPerPixel==24) - { - SuffLen=((m_Xres*3+3)/4)*4-(m_Xres*3); - pBuf=m_pBitmap; - pBuf+=m_NumPixel*3; - for (i=0; i0) - { - if (fread(&Dummy, SuffLen, 1, f) != 1) return eLoadBmpFileRead; - } - } - } - else - return eLoadBmpColorDepth; - - fclose(f); - - return 0; -} - -void CImage::Output( void ) -{ - fwrite(m_cBuf, m_nCount, 1, f); - m_nCount=0; -} - -void CImage::Output( char c ) -{ - if ( m_nCount == sizeof(m_cBuf) ) - { - fwrite(m_cBuf, m_nCount, 1, f); - m_nCount=0; - } - m_cBuf[m_nCount++] = c; -} - -void CImage::Output( char * pcData, int nSize ) -{ - for ( int i=0; i 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+i-nDif-nRep), nDif ); - } - nDif = 1; - } - } - else - { - if ( bEqual && (nRep<127) ) - nRep++; - else - { - Output( nRep+128 ); - Output( (char*)&colOld, 1 ); - nRep = 0; - nDif = 1; - } - } - } - - if ( nRep == 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+m_Xres-nDif), nDif ); - } - else - { - Output( nRep+128 ); - Output( (char*)&colOld, 1 ); - } - Output(); - } - } - } - else - if (m_BitPerPixel==24) - { - fh.tiImageType = bCompressed ? 10 : 2; - if (fwrite(&fh, sizeof(fh), 1, f) != 1) return eSaveTgaFileWrite; - - _BGR * pcolBuf = (_BGR *)m_pBitmap; - pcolBuf += m_NumPixel; - - if ( !bCompressed ) - { - for (j=0; j 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+i-nDif-nRep), sizeof(_BGR)*nDif ); - } - nDif = 1; - } - } - else - { - if ( bEqual && (nRep<127) ) - nRep++; - else - { - Output( nRep+128 ); - Output( (char*)&colOld, sizeof(_BGR) ); - nRep = 0; - nDif = 1; - } - } - } - - if ( nRep == 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+m_Xres-nDif), sizeof(_BGR)*nDif ); - } - else - { - Output( nRep+128 ); - Output( (char*)&colOld, sizeof(_BGR) ); - } - Output(); - } - } - } - else - if (m_BitPerPixel==32) - { - fh.tiImageType = bCompressed ? 10 : 2; - fh.tiAttrBits = 8; - if (fwrite(&fh, sizeof(fh), 1, f) != 1) return eSaveTgaFileWrite; - - _BGRA * pcolBuf = (_BGRA *)m_pBitmap; - pcolBuf += m_NumPixel; - - if ( !bCompressed ) - { - for (j=0; j 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+i-nDif-nRep), sizeof(_BGRA)*nDif ); - } - nDif = 1; - } - } - else - { - if ( bEqual && (nRep<127) ) - nRep++; - else - { - Output( nRep+128 ); - Output( (char*)&colOld, sizeof(_BGRA) ); - nRep = 0; - nDif = 1; - } - } - } - - if ( nRep == 0 ) - { - Output( nDif-1 ); - Output( (char*)(pcolBuf+m_Xres-nDif), sizeof(_BGRA)*nDif ); - } - else - { - Output( nRep+128 ); - Output( (char*)&colOld, sizeof(_BGRA) ); - } - Output(); - } - } - } - else - return eSaveTgaColorDepth; - - fclose(f); - - return 0; -} - -int CImage::LoadTga(char *szFilename) -{ - _TGAHEADER fh; - int i, j, k; - unsigned char nCount; - - if (!(f = fopen(szFilename, "rb"))) return eLoadTgaFileOpen; - if (fread(&fh, sizeof(fh), 1, f) != 1) return eLoadTgaFileRead; - bool bCompressed = (( fh.tiImageType & 8 ) != 0); - if ((fh.tiBitPerPixel<=0) || (fh.tiBitPerPixel>32)) - return eLoadTgaBadFormat; - - if ( Init( fh.tiXres, fh.tiYres, fh.tiBitPerPixel ) != 0 ) - return eLoadTgaInit; - - if ( m_BitPerPixel == 8 ) - { - if ( fh.tiPaletteIncluded == 1 ) - { - if ( fh.tiPaletteBpp == 24) - { - if (fread(&m_Pal, 3, fh.tiPaletteSize, f) != fh.tiPaletteSize) - return eLoadTgaFileRead; - } - else - if ( fh.tiPaletteBpp == 32) - { - unsigned char BmpPal[256][4]; - - if (fread(&BmpPal, 4, fh.tiPaletteSize, f) != fh.tiPaletteSize) - return eLoadTgaFileRead; - - for (i=0; i= m_pBitmap ) - { - nCount = Input(); - if ((nCount & 128)==0) - { - for (k=0; k<=nCount; k++) - { - colCur = Input(); - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - else - { - colCur = Input(); - for (k=0; k<=nCount-128; k++) - { - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - } - } - } - else - if ( m_BitPerPixel == 24 ) - { - _BGR * pcolBuf = (_BGR *)m_pBitmap; - pcolBuf += m_NumPixel; - - if ( !bCompressed ) - { - for (j=0; j= (_BGR *)m_pBitmap ) - { - nCount = Input(); - if ((nCount & 128)==0) - { - for (k=0; k<=nCount; k++) - { - colCur.b = Input(); - colCur.g = Input(); - colCur.r = Input(); - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - else - { - colCur.b = Input(); - colCur.g = Input(); - colCur.r = Input(); - for (k=0; k<=nCount-128; k++) - { - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - } - } - } - else - if ( m_BitPerPixel == 32 ) - { - _BGRA * pcolBuf = (_BGRA *)m_pBitmap; - pcolBuf += m_NumPixel; - - if ( !bCompressed ) - { - for (j=0; j= (_BGRA *)m_pBitmap ) - { - nCount = Input(); - if ((nCount & 128)==0) - { - for (k=0; k<=nCount; k++) - { - colCur.b = Input(); - colCur.g = Input(); - colCur.r = Input(); - colCur.a = Input(); - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - else - { - colCur.b = Input(); - colCur.g = Input(); - colCur.r = Input(); - colCur.a = Input(); - for (k=0; k<=nCount-128; k++) - { - *(pcolBuf+i) = colCur; - if ( (++i) == m_Xres ) - { - i=0; - pcolBuf -= m_Xres; - break; - } - } - } - } - } - } - else - return eLoadTgaColorDepth; - - fclose(f); - - return 0; -} - -int DLL CImage::Load(char *szFilename) -{ - int nRes = 0; - - if ( szFilename != NULL ) - { - char * szExt = strrchr( szFilename, '.' ); - int nNotTGA = 1; - - if ( szExt != NULL ) - nNotTGA = _stricmp( szExt, ".tga" ); - - if ( nNotTGA != 0 ) - nRes = LoadBmp( szFilename ); - else - nRes = LoadTga( szFilename ); - } - else - nRes = eLoadFilename; - - return nRes; -} - -int DLL CImage::Save(char *szFilename) -{ - int nRes = 0; - int nNotTGA = 1; - - if ( szFilename != NULL ) - { - char * szExt = strrchr( szFilename, '.' ); - - if ( szExt != NULL ) - nNotTGA = _stricmp( szExt, ".tga" ); - - if ( nNotTGA != 0 ) - { - if (( m_BitPerPixel == 16 ) || ( m_BitPerPixel == 32 )) - nRes = ConvertTo24(); - - if (nRes == 0) - nRes = SaveBmp( szFilename ); - } - else - { - if ( m_BitPerPixel == 16 ) - nRes = ConvertTo24(); - - if (nRes == 0) - nRes = SaveTga( szFilename, true ); - } - } - else - nRes = eSaveFilename; - - return nRes; -} } \ No newline at end of file diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.h b/src/gl/hqnx_asm/hqnx_asm_Image.h index 38f0f1d6a..918b904fe 100644 --- a/src/gl/hqnx_asm/hqnx_asm_Image.h +++ b/src/gl/hqnx_asm/hqnx_asm_Image.h @@ -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; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 329ac6484..af03af86e 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -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.; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index bda8dcb80..c2fa021f6 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -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); } } diff --git a/src/m_misc.h b/src/m_misc.h index 660eb7a58..f3773659d 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -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 diff --git a/src/m_png.cpp b/src/m_png.cpp index 28f015e7b..08cac8d54 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -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 diff --git a/src/m_png.h b/src/m_png.h index 70c45b710..4182440fb 100644 --- a/src/m_png.h +++ b/src/m_png.h @@ -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 diff --git a/src/md5.cpp b/src/md5.cpp index aa4b506da..d345e00d6 100644 --- a/src/md5.cpp +++ b/src/md5.cpp @@ -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); } } } diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index bec3082b1..c9fb7aeba 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -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); } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2dfbec49b..3d93e7a0a 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1365,6 +1365,8 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key) } } } + + FindFirstFreeEntry(FirstFreeEntry); } //============================================================================ diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index e1510145e..977426e57 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -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; } diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 017396ffb..3c17941ba 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -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; diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 9ea184c35..f3ce12a5e 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -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])) diff --git a/src/posix/cocoa/i_system.mm b/src/posix/cocoa/i_system.mm index bb1ea2e1b..3be9a067c 100644 --- a/src/posix/cocoa/i_system.mm +++ b/src/posix/cocoa/i_system.mm @@ -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; diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index 9819bc09e..f233f4ce8 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -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 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 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); } } diff --git a/src/posix/osx/i_specialpaths.mm b/src/posix/osx/i_specialpaths.mm index 843fb82d6..540aaf4b0 100644 --- a/src/posix/osx/i_specialpaths.mm +++ b/src/posix/osx/i_specialpaths.mm @@ -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; +} diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index 7bf23af11..b71acb8f8 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -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; } diff --git a/src/posix/unix/i_specialpaths.cpp b/src/posix/unix/i_specialpaths.cpp index 5dedba057..01320548d 100644 --- a/src/posix/unix/i_specialpaths.cpp +++ b/src/posix/unix/i_specialpaths.cpp @@ -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); +} \ No newline at end of file diff --git a/src/r_data/models/models_md3.cpp b/src/r_data/models/models_md3.cpp index e504b252a..8a649f713 100644 --- a/src/r_data/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -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()) diff --git a/src/resourcefiles/file_directory.cpp b/src/resourcefiles/file_directory.cpp index 77e5d0141..2e5630169 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -35,27 +35,13 @@ #include -#include #ifdef _WIN32 #include -#define stat _stat #else -#include -#ifndef __sun #include #endif -#endif -#include -#include -#include -#include -#include -#include -#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 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); diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 02e350998..3d842131d 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -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 &filenames, TArray &filenames, TArrayTell(); 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 &filenames, TArrayTell() - 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; diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index 7c9c957e3..96bd50e0f 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -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 { diff --git a/src/s_playlist.cpp b/src/s_playlist.cpp index e1b0fd5b6..315a2ac76 100644 --- a/src/s_playlist.cpp +++ b/src/s_playlist.cpp @@ -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++) diff --git a/src/s_playlist.h b/src/s_playlist.h index 74c06f857..859f0bce4 100644 --- a/src/s_playlist.h +++ b/src/s_playlist.h @@ -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 Songs; diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 2a515d91b..277604d68 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -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; } //========================================================================== diff --git a/src/sc_man.h b/src/sc_man.h index 44dd9370a..9962cbde0 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -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); diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index a0af21c14..cb927bb50 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -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; } } diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 19db0161d..28f839c6c 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -803,18 +803,17 @@ CCMD (writemidi) } TArray midi; - FILE *f; bool success; static_cast(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) { diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 7bc5a31e5..4c796ead5 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -239,7 +239,7 @@ public: void Stop(); protected: - FILE *File; + FileWriter *File; }; // WildMidi implementation of a MIDI device --------------------------------- diff --git a/src/sound/mididevices/music_opldumper_mididevice.cpp b/src/sound/mididevices/music_opldumper_mididevice.cpp index e301a3054..3519103e8 100644 --- a/src/sound/mididevices/music_opldumper_mididevice.cpp +++ b/src/sound/mididevices/music_opldumper_mididevice.cpp @@ -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()); diff --git a/src/sound/mididevices/music_timidity_mididevice.cpp b/src/sound/mididevices/music_timidity_mididevice.cpp index cacddf542..474c0efa9 100644 --- a/src/sound/mididevices/music_timidity_mididevice.cpp +++ b/src/sound/mididevices/music_timidity_mididevice.cpp @@ -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; diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index d4c03534d..42733ce38 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -43,6 +43,7 @@ #include "templates.h" #include "version.h" #include "tmpfileplus.h" +#include "m_misc.h" #ifndef _WIN32 #include @@ -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; diff --git a/src/statistics.cpp b/src/statistics.cpp index 2abd0bf12..865ba0411 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -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 &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 &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) 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;jinfo[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 &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;kPrintf("\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; } diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index cb7786200..d23e5e6f2 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -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); } } diff --git a/src/tmpfileplus.c b/src/tmpfileplus.cpp similarity index 53% rename from src/tmpfileplus.c rename to src/tmpfileplus.cpp index ddb71de09..2c14e1563 100644 --- a/src/tmpfileplus.c +++ b/src/tmpfileplus.cpp @@ -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 @@ -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; -} - - diff --git a/src/tmpfileplus.h b/src/tmpfileplus.h index e32ff5042..06219edd6 100644 --- a/src/tmpfileplus.h +++ b/src/tmpfileplus.h @@ -23,9 +23,7 @@ #include -#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_ */ diff --git a/src/v_font.cpp b/src/v_font.cpp index b475fb558..9716f2744 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -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; } } diff --git a/src/v_text.cpp b/src/v_text.cpp index cf8ce8cc7..f4829ec18 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -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) { diff --git a/src/v_text.h b/src/v_text.h index b76024fa5..cd7d3e6ad 100644 --- a/src/v_text.h +++ b/src/v_text.h @@ -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__ diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 412450d0a..1e1de76f0 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -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; diff --git a/src/win32/i_specialpaths.cpp b/src/win32/i_specialpaths.cpp index 58c87a8ca..375f301dd 100644 --- a/src/win32/i_specialpaths.cpp +++ b/src/win32/i_specialpaths.cpp @@ -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; +} diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h index 59101c602..657b120a3 100644 --- a/src/win32/win32swiface.h +++ b/src/win32/win32swiface.h @@ -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); }