diff --git a/tools/quake3/common/cmdlib.cpp b/tools/quake3/common/cmdlib.cpp index 8a957fb4..57f1a654 100644 --- a/tools/quake3/common/cmdlib.cpp +++ b/tools/quake3/common/cmdlib.cpp @@ -174,12 +174,9 @@ void Q_mkdir( const char *path ){ ================ */ int Q_filelength( FILE *f ){ - int pos; - int end; - - pos = ftell( f ); + const int pos = ftell( f ); fseek( f, 0, SEEK_END ); - end = ftell( f ); + const int end = ftell( f ); fseek( f, pos, SEEK_SET ); return end; @@ -207,8 +204,8 @@ FILE *SafeOpenRead( const char *filename, const char *mode ){ } -void SafeRead( FILE *f, void *buffer, int count ){ - if ( fread( buffer, 1, count, f ) != (size_t)count ) { +void SafeRead( FILE *f, MemBuffer& buffer ){ + if ( fread( buffer.data(), 1, buffer.size(), f ) != buffer.size() ) { Error( "File read failure" ); } } @@ -227,14 +224,7 @@ void SafeWrite( FILE *f, const void *buffer, int count ){ ============== */ bool FileExists( const char *filename ){ - FILE *f; - - f = fopen( filename, "r" ); - if ( !f ) { - return false; - } - fclose( f ); - return true; + return access( filename, R_OK ) == 0; } /* @@ -242,49 +232,13 @@ bool FileExists( const char *filename ){ LoadFile ============== */ -int LoadFile( const char *filename, void **bufferptr ){ - FILE *f; - int length; - void *buffer; - - f = SafeOpenRead( filename ); - length = Q_filelength( f ); - buffer = safe_malloc( length + 1 ); - ( (char *)buffer )[length] = 0; - SafeRead( f, buffer, length ); +MemBuffer LoadFile( const char *filename ){ + FILE *f = SafeOpenRead( filename ); + MemBuffer buffer( Q_filelength( f ) ); + SafeRead( f, buffer ); fclose( f ); - *bufferptr = buffer; - return length; -} - - -/* - ============== - TryLoadFile - - Allows failure - ============== - */ -int TryLoadFile( const char *filename, void **bufferptr ){ - FILE *f; - int length; - void *buffer; - - *bufferptr = NULL; - - f = fopen( filename, "rb" ); - if ( !f ) { - return -1; - } - length = Q_filelength( f ); - buffer = safe_malloc( length + 1 ); - ( (char *)buffer )[length] = 0; - SafeRead( f, buffer, length ); - fclose( f ); - - *bufferptr = buffer; - return length; + return buffer; } @@ -294,9 +248,7 @@ int TryLoadFile( const char *filename, void **bufferptr ){ ============== */ void SaveFile( const char *filename, const void *buffer, int count ){ - FILE *f; - - f = SafeOpenWrite( filename ); + FILE *f = SafeOpenWrite( filename ); SafeWrite( f, buffer, count ); fclose( f ); } diff --git a/tools/quake3/common/cmdlib.h b/tools/quake3/common/cmdlib.h index bd685a4a..4f3d05d3 100644 --- a/tools/quake3/common/cmdlib.h +++ b/tools/quake3/common/cmdlib.h @@ -27,6 +27,7 @@ #include #include +#include class void_ptr @@ -40,6 +41,42 @@ public: } }; + +class MemBuffer +{ + byte *m_data; + size_t m_size; +public: + MemBuffer() : m_data( nullptr ), m_size( 0 ) {} + explicit MemBuffer( size_t size ) : m_data( new byte[ size + 1 ] ), m_size( size ) { + m_data[m_size] = '\0'; // NOTE: when loading a file, you have to allocate one extra byte and set it to \0 + } + MemBuffer( MemBuffer&& other ) noexcept : m_data( std::exchange( other.m_data, nullptr ) ), m_size( other.m_size ) {} + MemBuffer& operator=( MemBuffer&& other ) noexcept { + std::swap( m_data, other.m_data ); + std::swap( m_size, other.m_size ); + return *this; + } + ~MemBuffer(){ + delete[] m_data; + } + void_ptr data() const { + return m_data; + } + /// \return correct buffer size in bytes, if it's not empty. May be not used for validity check! + size_t size() const { + return m_size; + } + /// \return true, if there is managed buffer + operator bool() const { + return m_data != nullptr; + } + /// \brief Delegates the ownership. Obtained buffer must be deallocated by \c delete[] + void_ptr release(){ + return std::exchange( m_data, nullptr ); + } +}; + void_ptr safe_malloc( size_t size ); void_ptr safe_calloc( size_t size ); @@ -58,11 +95,11 @@ double I_FloatTime( void ); FILE *SafeOpenWrite( const char *filename, const char *mode = "wb" ); FILE *SafeOpenRead( const char *filename, const char *mode = "rb" ); -void SafeRead( FILE *f, void *buffer, int count ); +void SafeRead( FILE *f, MemBuffer& buffer ); void SafeWrite( FILE *f, const void *buffer, int count ); -int LoadFile( const char *filename, void **bufferptr ); -int TryLoadFile( const char *filename, void **bufferptr ); +/// \brief loads file from absolute \p filename path or emits \c Error +MemBuffer LoadFile( const char *filename ); void SaveFile( const char *filename, const void *buffer, int count ); bool FileExists( const char *filename ); diff --git a/tools/quake3/common/imagelib.cpp b/tools/quake3/common/imagelib.cpp index 42de748d..c116ae99 100644 --- a/tools/quake3/common/imagelib.cpp +++ b/tools/quake3/common/imagelib.cpp @@ -194,7 +194,7 @@ byte *LBMRLEDecompress( byte *source,byte *unpacked, int bpwidth ){ ================= */ void LoadLBM( const char *filename, byte **picture, byte **palette ){ - byte *LBMbuffer, *picbuffer, *cmapbuffer; + byte *picbuffer, *cmapbuffer; int y; byte *LBM_P, *LBMEND_P; byte *pic_p; @@ -210,13 +210,13 @@ void LoadLBM( const char *filename, byte **picture, byte **palette ){ // // load the LBM // - LoadFile( filename, (void **)&LBMbuffer ); + MemBuffer file = LoadFile( filename ); // // parse the LBM header // - LBM_P = LBMbuffer; - if ( *(int *)LBMbuffer != LittleLong( FORMID ) ) { + LBM_P = file.data(); + if ( *(int *)LBM_P != LittleLong( FORMID ) ) { Error( "No FORM ID at start of file!\n" ); } @@ -296,8 +296,6 @@ void LoadLBM( const char *filename, byte **picture, byte **palette ){ LBM_P += Align( chunklength ); } - free( LBMbuffer ); - *picture = picbuffer; if ( palette ) { @@ -469,20 +467,19 @@ void LoadPCX( const char *filename, byte **pic, byte **palette, int *width, int byte *raw; pcx_t *pcx; int x, y, lsize; - int len; int dataByte, runLength; byte *out, *pix; /* load the file */ - len = vfsLoadFile( filename, (void **)&raw, 0 ); - if ( len == -1 ) { + MemBuffer buffer = vfsLoadFile( filename ); + if ( !buffer ) { Error( "LoadPCX: Couldn't read %s", filename ); } /* parse the PCX file */ - pcx = (pcx_t *)raw; + pcx = buffer.data(); raw = &pcx->data; pcx->xmin = LittleShort( pcx->xmin ); @@ -505,7 +502,7 @@ void LoadPCX( const char *filename, byte **pic, byte **palette, int *width, int if ( palette ) { *palette = safe_malloc( 768 ); - memcpy( *palette, (byte *)pcx + len - 768, 768 ); + memcpy( *palette, (byte *)pcx + buffer.size() - 768, 768 ); } if ( width ) { @@ -551,10 +548,9 @@ void LoadPCX( const char *filename, byte **pic, byte **palette, int *width, int } /* validity check */ - if ( raw - (byte *) pcx > len ) { + if ( raw - (byte *) pcx > int( buffer.size() ) ) { Error( "PCX file %s was malformed", filename ); } - free( pcx ); } @@ -693,10 +689,12 @@ void LoadBMP( const char *filename, byte **pic, byte **palette, int *width, int byte *in; int len, pos = 0; - len = vfsLoadFile( filename, (void **)&in, 0 ); - if ( len == -1 ) { + MemBuffer buffer = vfsLoadFile( filename ); + if ( !buffer ) { Error( "Couldn't read %s", filename ); } + in = buffer.data(); + len = buffer.size(); i = bufLittleShort( in, len, &pos ); if ( i != 'B' + ( 'M' << 8 ) ) { @@ -780,7 +778,6 @@ void LoadBMP( const char *filename, byte **pic, byte **palette, int *width, int } if ( !pic ) { - free( in ); return; } @@ -798,8 +795,6 @@ void LoadBMP( const char *filename, byte **pic, byte **palette, int *width, int memcpy( out, in + pos, bcWidth * bcHeight ); pos += bcWidth * bcHeight; } - - free( in ); } @@ -890,18 +885,19 @@ void TargaError( TargaHeader *t, const char *message ){ LoadTGABuffer ============= */ -void LoadTGABuffer( const byte *f, const byte *enddata, byte **pic, int *width, int *height ){ +void LoadTGABuffer( const byte *f, const size_t dataSize, byte **pic, int *width, int *height ){ int x, y, row_inc, compressed, readpixelcount, red, green, blue, alpha, runlen, pindex, alphabits, image_width, image_height; byte *pixbuf, *image_rgba; const byte *fin; unsigned char *p; TargaHeader targa_header; unsigned char palette[256 * 4]; + const byte * const enddata = f + dataSize; *pic = NULL; // abort if it is too small to parse - if ( enddata - f < 19 ) { + if ( dataSize < 19 ) { return; } @@ -1107,18 +1103,10 @@ void LoadTGABuffer( const byte *f, const byte *enddata, byte **pic, int *width, ============= */ void LoadTGA( const char *name, byte **pixels, int *width, int *height ){ - byte *buffer; - int nLen; - // - // load the file - // - nLen = vfsLoadFile( name, (void **)&buffer, 0 ); - if ( nLen == -1 ) { + if ( MemBuffer buffer = vfsLoadFile( name ) ) + LoadTGABuffer( buffer.data(), buffer.size(), pixels, width, height ); + else Error( "Couldn't read %s", name ); - } - - LoadTGABuffer( buffer, buffer + nLen, pixels, width, height ); - } diff --git a/tools/quake3/common/imagelib.h b/tools/quake3/common/imagelib.h index c0461bbd..0169f06d 100644 --- a/tools/quake3/common/imagelib.h +++ b/tools/quake3/common/imagelib.h @@ -37,7 +37,7 @@ void Save256Image( const char *name, byte *pixels, byte *palette, void LoadTGA( const char *filename, byte **pixels, int *width, int *height ); -void LoadTGABuffer( const byte *buffer, const byte* enddata, byte **pic, int *width, int *height ); +void LoadTGABuffer( const byte *buffer, const size_t dataSize, byte **pic, int *width, int *height ); void WriteTGA( const char *filename, const byte *data, int width, int height ); void WriteTGAGray( const char *filename, byte *data, int width, int height ); int LoadJPGBuff( void *src_buffer, int src_size, unsigned char **pic, int *width, int *height ); diff --git a/tools/quake3/common/scriplib.cpp b/tools/quake3/common/scriplib.cpp index 7de0f6ef..92377bab 100644 --- a/tools/quake3/common/scriplib.cpp +++ b/tools/quake3/common/scriplib.cpp @@ -28,6 +28,7 @@ #include "scriplib.h" #include "vfs.h" #include +#include /* ============================================================================= @@ -39,22 +40,18 @@ struct script_t { - CopiedString filename; - char *buffer; + const CopiedString filename; + const MemBuffer buffer; const char *it, *end; int line; - /* buffer is optional: != nullptr == own it */ - script_t( const char *filename, char *buffer, char *start, int size ) : + script_t( const char *filename, MemBuffer&& buffer_ ) : filename( filename ), - buffer( buffer ), - it( start ), - end( start + size ), + buffer( std::move( buffer_ ) ), + it( buffer.data() ), + end( it + buffer_.size() ), line( 1 ) {} script_t( script_t&& ) noexcept = delete; - ~script_t(){ - free( buffer ); - } }; std::list scriptstack; @@ -68,15 +65,8 @@ bool tokenready; // only true if UnGetToken was just called AddScriptToStack ============== */ -static void AddScriptToStack( const char *filename, int index, bool verbose ){ - void* buffer; - const int size = vfsLoadFile( filename, &buffer, index ); - - if ( size == -1 ) { - Sys_FPrintf( SYS_WRN, "Script file %s was not found\n", filename ); - } - else - { +static bool AddScriptToStack( const char *filename, int index, bool verbose ){ + if ( MemBuffer buffer = vfsLoadFile( filename, index ) ) { if( verbose ){ if ( index > 0 ) Sys_Printf( "entering %s (%d)\n", filename, index + 1 ); @@ -84,7 +74,17 @@ static void AddScriptToStack( const char *filename, int index, bool verbose ){ Sys_Printf( "entering %s\n", filename ); } - scriptstack.emplace_back( filename, void_ptr( buffer ), void_ptr( buffer ), size ); + scriptstack.emplace_back( filename, std::move( buffer ) ); + return true; + } + else + { + if( index >= 0 ) + Sys_FPrintf( SYS_WRN, "Script file %s was not found\n", filename ); + else + Sys_FPrintf( SYS_WRN, "Script file %s was not found: %s\n", filename, strerror( errno ) ); + + return false; } } @@ -94,10 +94,10 @@ static void AddScriptToStack( const char *filename, int index, bool verbose ){ LoadScriptFile ============== */ -void LoadScriptFile( const char *filename, int index, bool verbose /* = true */ ){ +bool LoadScriptFile( const char *filename, int index /* = 0 */, bool verbose /* = true */ ){ scriptstack.clear(); - AddScriptToStack( filename, index, verbose ); tokenready = false; + return AddScriptToStack( filename, index, verbose ); } /* @@ -105,10 +105,12 @@ void LoadScriptFile( const char *filename, int index, bool verbose /* = true */ ParseFromMemory ============== */ -void ParseFromMemory( char *buffer, int size ){ +void ParseFromMemory( char *buffer, size_t size ){ scriptstack.clear(); - scriptstack.emplace_back( "memory buffer", nullptr, buffer, size ); tokenready = false; + MemBuffer bu( size ); + memcpy( bu.data(), buffer, size ); + scriptstack.emplace_back( "memory buffer", std::move( bu ) ); } diff --git a/tools/quake3/common/scriplib.h b/tools/quake3/common/scriplib.h index b2b6508f..c5876737 100644 --- a/tools/quake3/common/scriplib.h +++ b/tools/quake3/common/scriplib.h @@ -28,9 +28,11 @@ extern char token[MAXTOKEN]; extern int scriptline; - -void LoadScriptFile( const char *filename, int index, bool verbose = true ); -void ParseFromMemory( char *buffer, int size ); +/// \param[in] index -1: \p filename is absolute path +/// \param[in] index >= 0: \p filename is relative path in VSF, Nth occurrence of file +/// \return true on success +bool LoadScriptFile( const char *filename, int index = 0, bool verbose = true ); +void ParseFromMemory( char *buffer, size_t size ); /// \param[in] crossline true: write next token to \c token or return false on EOF /// \param[in] crossline false: find next token on the current line or emit \c Error diff --git a/tools/quake3/common/vfs.cpp b/tools/quake3/common/vfs.cpp index f95209e7..a4995c69 100644 --- a/tools/quake3/common/vfs.cpp +++ b/tools/quake3/common/vfs.cpp @@ -255,7 +255,7 @@ int vfsGetFileCount( const char *filename ){ for ( const auto& dir : g_strDirs ) { - if ( access( StringOutputStream( 256 )( dir, filename ), R_OK ) == 0 ) { + if ( FileExists( StringOutputStream( 256 )( dir, filename ) ) ) { ++count; } } @@ -264,33 +264,27 @@ int vfsGetFileCount( const char *filename ){ } // NOTE: when loading a file, you have to allocate one extra byte and set it to \0 -int vfsLoadFile( const char *filename, void **bufferptr, int index ){ +MemBuffer vfsLoadFile( const char *filename, int index /* = 0 */ ){ - const auto load_full_path = [bufferptr] ( const char *filename ) -> int + const auto load_full_path = [] ( const char *filename ) -> MemBuffer { strcpy( g_strLoadedFileLocation, filename ); + MemBuffer buffer; + FILE *f = fopen( filename, "rb" ); - if ( f == NULL ) { - return -1; - } + if ( f != NULL ) { + fseek( f, 0, SEEK_END ); + buffer = MemBuffer( ftell( f ) ); + rewind( f ); - fseek( f, 0, SEEK_END ); - const long len = ftell( f ); - rewind( f ); - - *bufferptr = safe_malloc( len + 1 ); - - if ( fread( *bufferptr, 1, len, f ) != (size_t) len ) { + if ( fread( buffer.data(), 1, buffer.size(), f ) != buffer.size() ) { + buffer = MemBuffer(); + } fclose( f ); - return -1; } - fclose( f ); - // we need to end the buffer with a 0 - ( (char*) ( *bufferptr ) )[len] = 0; - - return len; + return buffer; }; // filename is a full path @@ -301,7 +295,7 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){ for ( const auto& dir : g_strDirs ) { const auto fullpath = StringOutputStream( 256 )( dir, filename ); - if ( access( fullpath, R_OK ) == 0 && 0 == index-- ) { + if ( FileExists( fullpath ) && 0 == index-- ) { return load_full_path( fullpath ); } } @@ -309,6 +303,8 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){ auto fixed = StringOutputStream( 64 )( PathCleaned( filename ) ); strLower( fixed.c_str() ); + MemBuffer buffer; + for ( const VFS_PAKFILE& file : g_pakFiles ) { if ( strEqual( file.name.c_str(), fixed ) && 0 == index-- ) @@ -318,26 +314,19 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){ unzFile zipfile = file.pak.zipfile; *(unz_s*)zipfile = file.zipinfo; - if ( unzOpenCurrentFile( zipfile ) != UNZ_OK ) { - return -1; - } + if ( unzOpenCurrentFile( zipfile ) == UNZ_OK ) { + buffer = MemBuffer( file.size ); - *bufferptr = safe_malloc( file.size + 1 ); - // we need to end the buffer with a 0 - ( (char*) ( *bufferptr ) )[file.size] = 0; - - const int size = unzReadCurrentFile( zipfile, *bufferptr, file.size ); - unzCloseCurrentFile( zipfile ); - if ( size < 0 ) { - return -1; - } - else{ - return file.size; + if ( unzReadCurrentFile( zipfile, buffer.data(), file.size ) < 0 ) { + buffer = MemBuffer(); + } + unzCloseCurrentFile( zipfile ); } + return buffer; } } - return -1; + return buffer; } @@ -360,26 +349,19 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve unzFile zipfile = file.pak.zipfile; *(unz_s*)zipfile = file.zipinfo; - if ( unzOpenCurrentFile( zipfile ) != UNZ_OK ) { - return false; - } + if ( unzOpenCurrentFile( zipfile ) == UNZ_OK ) { + MemBuffer buffer( file.size ); - byte *bufferptr = safe_malloc( file.size + 1 ); - // we need to end the buffer with a 0 - bufferptr[file.size] = 0; - - const int size = unzReadCurrentFile( zipfile, bufferptr, file.size ); - unzCloseCurrentFile( zipfile ); - if ( size < 0 ) { - return false; - } - else{ - if ( !mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, size, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate ) ){ - Error( "Failed creating zip archive \"%s\"!\n", packname ); + const int size = unzReadCurrentFile( zipfile, buffer.data(), file.size ); + unzCloseCurrentFile( zipfile ); + if ( size >= 0 ) { + if ( !mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, buffer.data(), size, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate ) ){ + Error( "Failed creating zip archive \"%s\"!\n", packname ); + } + return true; } - free( bufferptr ); - return true; } + return false; } } @@ -387,8 +369,8 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve } bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel ){ - if ( access( filepath, R_OK ) == 0 ) { - if ( access( packname, R_OK ) == 0 ) { + if ( FileExists( filepath ) ) { + if ( FileExists( packname ) ) { mz_zip_archive zip; memset( &zip, 0, sizeof(zip) ); diff --git a/tools/quake3/common/vfs.h b/tools/quake3/common/vfs.h index 1387bc54..6bdd9fa6 100644 --- a/tools/quake3/common/vfs.h +++ b/tools/quake3/common/vfs.h @@ -33,7 +33,11 @@ void vfsInitDirectory( const char *path ); void vfsShutdown(); int vfsGetFileCount( const char *filename ); -int vfsLoadFile( const char *filename, void **buffer, int index ); + +/// \param[in] index -1: \p filename is absolute path +/// \param[in] index >= 0: \p filename is relative path in VSF, Nth occurrence of file +/// \return non-empty \c MemBuffer on success +MemBuffer vfsLoadFile( const char *filename, int index = 0 ); std::vector vfsListShaderFiles( const char *shaderPath ); bool vfsPackFile( const char *filename, const char *packname, const int compLevel ); bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel ); diff --git a/tools/quake3/q3map2/autopk3.cpp b/tools/quake3/q3map2/autopk3.cpp index e948b142..e4e18cd2 100644 --- a/tools/quake3/q3map2/autopk3.cpp +++ b/tools/quake3/q3map2/autopk3.cpp @@ -225,18 +225,8 @@ static inline void parseEXblock( StrList& list, const char *exName ){ } static const Exclusions parseEXfile( const char* filename ){ - Sys_Printf( "Loading %s\n", filename ); - Exclusions ex; - byte *buffer; - const int size = TryLoadFile( filename, (void**) &buffer ); - if ( size < 0 ) { - Sys_Warning( "Unable to load exclusions file %s.\n", filename ); - } - else{ - /* parse the file */ - ParseFromMemory( (char *) buffer, size ); - + if ( LoadScriptFile( filename, -1 ) ) { /* tokenize it */ while ( GetToken( true ) ) /* test for end of file */ { @@ -261,15 +251,15 @@ static const Exclusions parseEXfile( const char* filename ){ } } - /* free the buffer */ - free( buffer ); - /* prepare ex.pureTextures */ for ( const auto& s : ex.textures ){ if( !StrList_find( ex.shaders, s ) ) ex.pureTextures.emplace_back( s ); } } + else{ + Sys_Warning( "Unable to load exclusions file %s.\n", filename ); + } return ex; } @@ -731,24 +721,15 @@ int repackBSPMain( Args& args ){ /* load bsps paths list */ /* do some path mangling */ strcpy( source, ExpandArg( fileName ) ); - Sys_Printf( "Loading %s\n", source ); - byte *buffer; - const int size = TryLoadFile( source, (void**) &buffer ); - if ( size <= 0 ) { + if ( !LoadScriptFile( source, -1 ) ) { Error( "Unable to open bsps paths list file %s.\n", source ); } - /* parse the file */ - ParseFromMemory( (char *) buffer, size ); - /* tokenize it */ while ( GetToken( true ) ) { bspList.emplace_back( stream( PathExtensionless( token ), ".bsp" ) ); } - - /* free the buffer */ - free( buffer ); } /* parse bsps */ @@ -961,9 +942,7 @@ int repackBSPMain( Args& args ){ /* write shader */ stream( g_enginePath, nameOFpack, "_strippedBYrepacker.shader" ); - FILE *f = fopen( stream, "wb" ); - fwrite( allShaders.c_str(), sizeof( char ), allShaders.end() - allShaders.begin(), f ); - fclose( f ); + SaveFile( stream, allShaders.c_str(), allShaders.end() - allShaders.begin() ); Sys_Printf( "Shaders saved to %s\n", stream.c_str() ); /* make a pack */ diff --git a/tools/quake3/q3map2/bspfile_ibsp.cpp b/tools/quake3/q3map2/bspfile_ibsp.cpp index 848c41ae..7030791a 100644 --- a/tools/quake3/q3map2/bspfile_ibsp.cpp +++ b/tools/quake3/q3map2/bspfile_ibsp.cpp @@ -213,11 +213,10 @@ struct ibspGridPoint_t */ void LoadIBSPFile( const char *filename ){ - ibspHeader_t *header; + /* load the file */ + MemBuffer file = LoadFile( filename ); - - /* load the file header */ - LoadFile( filename, (void**) &header ); + ibspHeader_t *header = file.data(); /* swap the header (except the first 4 bytes) */ SwapBlock( (int*) ( (byte*) header + 4 ), sizeof( *header ) - 4 ); @@ -256,9 +255,6 @@ void LoadIBSPFile( const char *filename ){ else{ bspAds.clear(); } - - /* free the file buffer */ - free( header ); } /* @@ -267,11 +263,10 @@ void LoadIBSPFile( const char *filename ){ */ void LoadIBSPorRBSPFilePartially( const char *filename ){ - ibspHeader_t *header; + /* load the file */ + MemBuffer file = LoadFile( filename ); - - /* load the file header */ - LoadFile( filename, (void**) &header ); + ibspHeader_t *header = file.data(); /* swap the header (except the first 4 bytes) */ SwapBlock( (int*) ( (byte*) header + 4 ), sizeof( *header ) - 4 ); @@ -293,9 +288,6 @@ void LoadIBSPorRBSPFilePartially( const char *filename ){ CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs ); CopyLump( (bspHeader_t*) header, LUMP_ENTITIES, bspEntData ); - - /* free the file buffer */ - free( header ); } /* diff --git a/tools/quake3/q3map2/bspfile_rbsp.cpp b/tools/quake3/q3map2/bspfile_rbsp.cpp index fc458c27..aec4166e 100644 --- a/tools/quake3/q3map2/bspfile_rbsp.cpp +++ b/tools/quake3/q3map2/bspfile_rbsp.cpp @@ -179,11 +179,10 @@ static void AddLightGridLumps( FILE *file, rbspHeader_t& header ){ */ void LoadRBSPFile( const char *filename ){ - rbspHeader_t *header; + /* load the file */ + MemBuffer file = LoadFile( filename ); - - /* load the file header */ - LoadFile( filename, (void**) &header ); + rbspHeader_t *header = file.data(); /* swap the header (except the first 4 bytes) */ SwapBlock( (int*) ( (byte*) header + 4 ), sizeof( *header ) - 4 ); @@ -214,9 +213,6 @@ void LoadRBSPFile( const char *filename ){ CopyLump( (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes ); CopyLump( (bspHeader_t*) header, LUMP_ENTITIES, bspEntData ); CopyLightGridLumps( header ); - - /* free the file buffer */ - free( header ); } diff --git a/tools/quake3/q3map2/convert_bsp.cpp b/tools/quake3/q3map2/convert_bsp.cpp index 6ef0ec7b..8f8339ed 100644 --- a/tools/quake3/q3map2/convert_bsp.cpp +++ b/tools/quake3/q3map2/convert_bsp.cpp @@ -44,11 +44,6 @@ static void AAS_DData( unsigned char *data, int size ){ */ int FixAAS( Args& args ){ - int length, checksum; - void *buffer; - char aas[ 1024 ]; - - /* arg checking */ if ( args.empty() ) { Sys_Printf( "Usage: q3map2 -fixaas [-v] \n" ); @@ -64,17 +59,18 @@ int FixAAS( Args& args ){ /* load the bsp */ Sys_Printf( "Loading %s\n", source ); - length = LoadFile( source, &buffer ); + MemBuffer buffer = LoadFile( source ); /* create bsp checksum */ Sys_Printf( "Creating checksum...\n" ); - checksum = LittleLong( (int)Com_BlockChecksum( buffer, length ) ); // md4 checksum for a block of data + int checksum = LittleLong( (int)Com_BlockChecksum( buffer.data(), buffer.size() ) ); // md4 checksum for a block of data AAS_DData( (unsigned char *) &checksum, 4 ); /* write checksum to aas */ for( auto&& ext : { ".aas", "_b0.aas", "_b1.aas" } ) { /* mangle name */ + char aas[ 1024 ]; strcpy( aas, source ); path_set_extension( aas, ext ); Sys_Printf( "Trying %s\n", aas ); @@ -117,7 +113,7 @@ struct abspLumpTest_t int AnalyzeBSP( Args& args ){ abspHeader_t *header; - int size, i, version, offset, length, lumpInt, count; + int i, version, offset, length, lumpInt, count; char ident[ 5 ]; void *lump; float lumpFloat; @@ -160,11 +156,8 @@ int AnalyzeBSP( Args& args ){ Sys_Printf( "Loading %s\n", source ); /* load the file */ - size = LoadFile( source, (void**) &header ); - if ( size == 0 || header == NULL ) { - Sys_Printf( "Unable to load %s.\n", source ); - return -1; - } + MemBuffer file = LoadFile( source ); + header = file.data(); /* analyze ident/version */ memcpy( ident, header->ident, 4 ); @@ -238,14 +231,14 @@ int AnalyzeBSP( Args& args ){ Sys_Printf( "---------------------------------------\n" ); /* end of file */ - if ( offset + length >= size ) { + if ( offset + length >= int( file.size() ) ) { break; } } /* last stats */ Sys_Printf( "Lump count: %d\n", i + 1 ); - Sys_Printf( "File size: %d bytes\n", size ); + Sys_Printf( "File size: %zu bytes\n", file.size() ); /* return to caller */ return 0; diff --git a/tools/quake3/q3map2/convert_json.cpp b/tools/quake3/q3map2/convert_json.cpp index 2e832e1b..54405b3c 100644 --- a/tools/quake3/q3map2/convert_json.cpp +++ b/tools/quake3/q3map2/convert_json.cpp @@ -410,11 +410,8 @@ static void write_json( const char *directory ){ inline rapidjson::Document load_json( const char *fileName ){ Sys_Printf( "Loading %s\n", fileName ); - void *buffer; - LoadFile( fileName, &buffer ); rapidjson::Document doc; - doc.Parse( (const char*)buffer ); - free( buffer ); + doc.Parse( (const char*)LoadFile( fileName ).data() ); ENSURE( !doc.HasParseError() ); return doc; } diff --git a/tools/quake3/q3map2/convert_obj.cpp b/tools/quake3/q3map2/convert_obj.cpp index 75d400d5..f4979b7c 100644 --- a/tools/quake3/q3map2/convert_obj.cpp +++ b/tools/quake3/q3map2/convert_obj.cpp @@ -218,7 +218,7 @@ int Convert_CountLightmaps( const char* dirname ){ void Convert_ReferenceLightmaps( const char* base, std::vector& lmIndices ){ char shaderfile[256]; sprintf( shaderfile, "%s/q3map2_%s.shader", g_game->shaderPath, base ); - LoadScriptFile( shaderfile, 0 ); + LoadScriptFile( shaderfile ); /* tokenize it */ while ( GetToken( true ) ) /* test for end of file */ { diff --git a/tools/quake3/q3map2/image.cpp b/tools/quake3/q3map2/image.cpp index 8c710a54..fa23891b 100644 --- a/tools/quake3/q3map2/image.cpp +++ b/tools/quake3/q3map2/image.cpp @@ -279,78 +279,52 @@ const image_t *ImageLoad( const char *name ){ byte *pixels = nullptr; int width, height; char filename[ 1024 ]; - int size; - byte *buffer = nullptr; + MemBuffer buffer; bool alphaHack = false; - /* attempt to load tga */ - sprintf( filename, "%s.tga", name ); // StripExtension( name ); already - size = vfsLoadFile( filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadTGABuffer( buffer, buffer + size, &pixels, &width, &height ); - } - else + /* attempt to load various formats */ + if ( sprintf( filename, "%s.tga", name ); buffer = vfsLoadFile( filename ) ) // StripExtension( name ); already { - /* attempt to load png */ - path_set_extension( filename, ".png" ); - size = vfsLoadFile( filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadPNGBuffer( buffer, size, &pixels, &width, &height ); - } - else - { - /* attempt to load jpg */ - path_set_extension( filename, ".jpg" ); - size = vfsLoadFile( filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - if ( LoadJPGBuff( buffer, size, &pixels, &width, &height ) == -1 && pixels != nullptr ) { - // On error, LoadJPGBuff might store a pointer to the error message in pixels - Sys_Warning( "LoadJPGBuff %s %s\n", filename, (unsigned char*) pixels ); - pixels = nullptr; - } - alphaHack = true; - } - else - { - /* attempt to load dds */ - path_set_extension( filename, ".dds" ); - size = vfsLoadFile( filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadDDSBuffer( buffer, size, &pixels, &width, &height ); - - /* debug code */ - #if 0 - { - ddsPF_t pf; - DDSGetInfo( (ddsBuffer_t*) buffer, nullptr, nullptr, &pf ); - Sys_Printf( "pf = %d\n", pf ); - if ( width > 0 ) { - path_set_extension( filename, "_converted.tga" ); - WriteTGA( "C:\\games\\quake3\\baseq3\\textures\\rad\\dds_converted.tga", pixels, width, height ); - } - } - #endif - } - else - { - /* attempt to load ktx */ - path_set_extension( filename, ".ktx" ); - size = vfsLoadFile( filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadKTXBufferFirstImage( buffer, size, &pixels, &width, &height ); - } - } - } - } + LoadTGABuffer( buffer.data(), buffer.size(), &pixels, &width, &height ); + } + else if( path_set_extension( filename, ".png" ); buffer = vfsLoadFile( filename ) ) + { + LoadPNGBuffer( buffer.data(), buffer.size(), &pixels, &width, &height ); + } + else if( path_set_extension( filename, ".jpg" ); buffer = vfsLoadFile( filename ) ) + { + if ( LoadJPGBuff( buffer.data(), buffer.size(), &pixels, &width, &height ) == -1 && pixels != nullptr ) { + // On error, LoadJPGBuff might store a pointer to the error message in pixels + Sys_Warning( "LoadJPGBuff %s %s\n", filename, (unsigned char*) pixels ); + pixels = nullptr; + } + alphaHack = true; + } + else if( path_set_extension( filename, ".dds" ); buffer = vfsLoadFile( filename ) ) + { + LoadDDSBuffer( buffer.data(), buffer.size(), &pixels, &width, &height ); + /* debug code */ + #if 0 + { + ddsPF_t pf; + DDSGetInfo( (ddsBuffer_t*) buffer, nullptr, nullptr, &pf ); + Sys_Printf( "pf = %d\n", pf ); + if ( width > 0 ) { + path_set_extension( filename, "_converted.tga" ); + WriteTGA( "C:\\games\\quake3\\baseq3\\textures\\rad\\dds_converted.tga", pixels, width, height ); + } + } + #endif + } + else if( path_set_extension( filename, ".ktx" ); buffer = vfsLoadFile( filename ) ) + { + LoadKTXBufferFirstImage( buffer.data(), buffer.size(), &pixels, &width, &height ); } - - /* free file buffer */ - free( buffer ); /* make sure everything's kosher */ - if ( size <= 0 || width <= 0 || height <= 0 || pixels == nullptr ) { - //% Sys_Printf( "size = %d width = %d height = %d pixels = 0x%08x (%s)\n", - //% size, width, height, pixels, filename ); + if ( !buffer || width <= 0 || height <= 0 || pixels == nullptr ) { + //% Sys_Printf( "size = %zu width = %d height = %d pixels = 0x%08x (%s)\n", + //% buffer.size(), width, height, pixels, filename ); return nullptr; } @@ -358,10 +332,8 @@ const image_t *ImageLoad( const char *name ){ image_t& image = *images.emplace_after( images.cbegin(), name, filename, width, height, pixels ); if ( alphaHack ) { - path_set_extension( filename, "_alpha.jpg" ); - size = vfsLoadFile( (const char*) filename, (void**) &buffer, 0 ); - if ( size > 0 ) { - if ( LoadJPGBuff( buffer, size, &pixels, &width, &height ) == -1 ) { + if ( path_set_extension( filename, "_alpha.jpg" ); buffer = vfsLoadFile( filename ) ) { + if ( LoadJPGBuff( buffer.data(), buffer.size(), &pixels, &width, &height ) == -1 ) { if ( pixels ) { // On error, LoadJPGBuff might store a pointer to the error message in pixels Sys_Warning( "LoadJPGBuff %s %s\n", filename, (unsigned char*) pixels ); @@ -373,7 +345,6 @@ const image_t *ImageLoad( const char *name ){ } free( pixels ); } - free( buffer ); } } diff --git a/tools/quake3/q3map2/light_ydnar.cpp b/tools/quake3/q3map2/light_ydnar.cpp index d6ef2d06..5bf1fae3 100644 --- a/tools/quake3/q3map2/light_ydnar.cpp +++ b/tools/quake3/q3map2/light_ydnar.cpp @@ -1152,7 +1152,7 @@ void MapRawLightmap( int rawLightmapNum ){ /* divine a normal and origin from neighboring luxels */ fake.xyz.set( 0 ); fake.normal.set( 0 ); - fake.lightmap[ 0 ] = { x, y }; //% 0.0001 + x; //% 0.0001 + y; + fake.lightmap[ 0 ] = Vector2( x, y ); //% 0.0001 + x; //% 0.0001 + y; samples = 0.0f; for ( sy = ( y - 1 ); sy <= ( y + 1 ); sy++ ) { @@ -3750,7 +3750,7 @@ void SetupFloodLight( void ){ sscanf( value, "%lf %lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5, &v6 ); - floodlightRGB = { v1, v2, v3 }; + floodlightRGB = Vector3( v1, v2, v3 ); if ( vector3_length( floodlightRGB ) == 0 ) { floodlightRGB = { 0.94, 0.94, 1.0 }; diff --git a/tools/quake3/q3map2/lightmaps_ydnar.cpp b/tools/quake3/q3map2/lightmaps_ydnar.cpp index a6dc60ee..ec00a857 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.cpp +++ b/tools/quake3/q3map2/lightmaps_ydnar.cpp @@ -175,9 +175,9 @@ int ExportLightmapsMain( Args& args ){ */ int ImportLightmapsMain( Args& args ){ - int i, x, y, len, width, height; + int i, x, y, width, height; char dirname[ 1024 ], filename[ 1024 ]; - byte *lightmap, *buffer, *pixels, *in, *out; + byte *lightmap, *pixels, *in, *out; /* arg checking */ @@ -215,17 +215,15 @@ int ImportLightmapsMain( Args& args ){ /* read a tga image */ sprintf( filename, "%s/lightmap_%04d.tga", dirname, i ); Sys_Printf( "Loading %s\n", filename ); - buffer = NULL; - len = vfsLoadFile( filename, (void**) &buffer, -1 ); - if ( len < 0 ) { + MemBuffer buffer = vfsLoadFile( filename, -1 ); + if ( !buffer ) { Sys_Warning( "Unable to load image %s\n", filename ); continue; } /* parse file into an image */ pixels = NULL; - LoadTGABuffer( buffer, buffer + len, &pixels, &width, &height ); - free( buffer ); + LoadTGABuffer( buffer.data(), buffer.size(), &pixels, &width, &height ); /* sanity check it */ if ( pixels == NULL ) { diff --git a/tools/quake3/q3map2/map.cpp b/tools/quake3/q3map2/map.cpp index 6dc0f832..ed2d71d8 100644 --- a/tools/quake3/q3map2/map.cpp +++ b/tools/quake3/q3map2/map.cpp @@ -1657,20 +1657,15 @@ static bool ParseMapEntity( bool onlyLights, bool noCollapseGroups ){ */ void LoadMapFile( const char *filename, bool onlyLights, bool noCollapseGroups ){ - FILE *file; int oldNumEntities = 0; /* note it */ Sys_FPrintf( SYS_VRB, "--- LoadMapFile ---\n" ); - Sys_Printf( "Loading %s\n", filename ); - - /* hack */ - file = SafeOpenRead( filename ); - fclose( file ); /* load the map file */ - LoadScriptFile( filename, -1 ); + if( !LoadScriptFile( filename, -1 ) ) + Error( "" ); /* setup */ if ( onlyLights ) { diff --git a/tools/quake3/q3map2/model.cpp b/tools/quake3/q3map2/model.cpp index 15839afa..b0461cac 100644 --- a/tools/quake3/q3map2/model.cpp +++ b/tools/quake3/q3map2/model.cpp @@ -117,10 +117,8 @@ public: * you probably have to supply an own implementation of IOStream as well. */ Assimp::IOStream* Open( const char* pFile, const char* pMode = "rb" ) override { - const uint8_t *boo; - const int size = vfsLoadFile( pFile, (void**) &boo, 0 ); - if ( size >= 0 ) { - return new Assimp::MemoryIOStream( boo, size, true ); + if ( MemBuffer boo = vfsLoadFile( pFile ) ) { + return new Assimp::MemoryIOStream( boo.release(), boo.size(), true ); } return nullptr; } @@ -1011,19 +1009,18 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor std::list skins; { auto skinfilename = StringOutputStream(99)( PathExtensionless( name ), '_', skin, ".skin" ); - char *skinfilecontent; - int skinfilesize = vfsLoadFile( skinfilename, (void**) &skinfilecontent, 0 ); - if ( skinfilesize < 0 && skin != 0 ) { + MemBuffer skinfile = vfsLoadFile( skinfilename ); + if ( skinfile && skin != 0 ) { /* fallback to skin 0 if invalid */ skinfilename( PathExtensionless( name ), "_0.skin" ); - skinfilesize = vfsLoadFile( skinfilename, (void**) &skinfilecontent, 0 ); - if ( skinfilesize >= 0 ) { + skinfile = vfsLoadFile( skinfilename ); + if ( skinfile ) { Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name ); } } - if ( skinfilesize >= 0 ) { + if ( skinfile ) { Sys_Printf( "Using skin %d of %s\n", skin, name ); - for ( char *skinfilenextptr, *skinfileptr = skinfilecontent; !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr ) + for ( char *skinfilenextptr, *skinfileptr = skinfile.data(); !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr ) { // for fscanf char format[64]; @@ -1060,7 +1057,6 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor /* invalid input line -> discard skin struct */ Sys_Printf( "Discarding skin directive in %s: %s\n", skinfilename.c_str(), skinfileptr ); } - free( skinfilecontent ); } } diff --git a/tools/quake3/q3map2/shaders.cpp b/tools/quake3/q3map2/shaders.cpp index 3a578247..7b8fd26d 100644 --- a/tools/quake3/q3map2/shaders.cpp +++ b/tools/quake3/q3map2/shaders.cpp @@ -874,7 +874,7 @@ static void ParseShaderFile( const char *filename ){ ShaderTextCollector text; /* load the shader */ - LoadScriptFile( filename, 0 ); + LoadScriptFile( filename ); /* tokenize it */ while ( GetToken( true ) ) /* test for end of file */ @@ -1827,7 +1827,7 @@ static void ParseCustomInfoParms( void ){ } /* load it */ - LoadScriptFile( "scripts/custinfoparms.txt", 0 ); + LoadScriptFile( "scripts/custinfoparms.txt" ); /* clear the array */ memset( custSurfaceParms, 0, sizeof( custSurfaceParms ) ); diff --git a/tools/quake3/q3map2/surface_extra.cpp b/tools/quake3/q3map2/surface_extra.cpp index 1231fad1..eb7f6e89 100644 --- a/tools/quake3/q3map2/surface_extra.cpp +++ b/tools/quake3/q3map2/surface_extra.cpp @@ -280,33 +280,22 @@ void WriteSurfaceExtraFile( const char *path ){ */ void LoadSurfaceExtraFile( const char *path ){ - char srfPath[ 1024 ]; - surfaceExtra_t *se; - int surfaceNum, size; - byte *buffer; - - /* dummy check */ if ( strEmptyOrNull( path ) ) { return; } /* load the file */ - strcpy( srfPath, path ); - path_set_extension( srfPath, ".srf" ); - Sys_Printf( "Loading %s\n", srfPath ); - size = LoadFile( srfPath, (void**) &buffer ); - if ( size <= 0 ) { - Sys_Warning( "Unable to find surface file %s, using defaults.\n", srfPath ); - return; - } + auto srfPath = StringOutputStream( 256 )( PathExtensionless( path ), ".srf" ); /* parse the file */ - ParseFromMemory( (char *) buffer, size ); + if( !LoadScriptFile( srfPath, -1 ) ) + Error( "" ); /* tokenize it */ while ( GetToken( true ) ) /* test for end of file */ { + surfaceExtra_t *se; /* default? */ if ( striEqual( token, "default" ) ) { se = &seDefault; @@ -315,9 +304,9 @@ void LoadSurfaceExtraFile( const char *path ){ /* surface number */ else { - surfaceNum = atoi( token ); + const int surfaceNum = atoi( token ); if ( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS ) { - Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath, scriptline, surfaceNum ); + Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath.c_str(), scriptline, surfaceNum ); } while ( surfaceNum >= numSurfaceExtras ) se = AllocSurfaceExtra(); @@ -326,7 +315,7 @@ void LoadSurfaceExtraFile( const char *path ){ /* handle { } section */ if ( !( GetToken( true ) && strEqual( token, "{" ) ) ) { - Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath, scriptline ); + Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath.c_str(), scriptline ); } while ( GetToken( true ) && !strEqual( token, "}" ) ) { @@ -382,7 +371,4 @@ void LoadSurfaceExtraFile( const char *path ){ GetToken( false ); } } - - /* free the buffer */ - free( buffer ); }