コード例 #1
0
ファイル: files.c プロジェクト: sheuan/qvb
/*
================
FS_LoadFile
================
*/
int FS_LoadFile ( char *name, void **buffer )
{
	FILE *f;
	int length;

	if ( !name ) {
		return -1;
	}

	*buffer = NULL;

	f = fopen ( name, "rb" );
	if ( !f ) {
		return -1;
	}

	length = FS_FileLength ( f );
	if ( !buffer ) {
		return length;
	}
	if ( !length ) {
		return 0;
	}

	*buffer = malloc ( length );
	fread ( *buffer, length, 1, f );
	fclose ( f );

	return length;
}
コード例 #2
0
ファイル: filesystem.c プロジェクト: Jenco420/yquake2
/*
 * Returns file size or -1 on error.
 */
int
FS_FOpenFileAppend(fsHandle_t *handle)
{
	char path[MAX_OSPATH];

	FS_CreatePath(handle->name);

	Com_sprintf(path, sizeof(path), "%s/%s", fs_gamedir, handle->name);

	handle->file = fopen(path, "ab");

	if (handle->file)
	{
		if (fs_debug->value)
		{
			Com_Printf("FS_FOpenFileAppend: '%s'.\n", path);
		}

		return FS_FileLength(handle->file);
	}

	if (fs_debug->value)
	{
		Com_Printf("FS_FOpenFileAppend: couldn't open '%s'.\n", path);
	}

	return -1;
}
コード例 #3
0
ファイル: wolf_map.c プロジェクト: Anters/Wolf3D-iOS
/*
-----------------------------------------------------------------------------
 Function: CAL_SetupMapFile -Setup map files for decoding.
 
 Parameters: extension -[in] file extension for map data files.
 
 Returns: Non-zero on success, zero otherwise.
 
 Notes: 
-----------------------------------------------------------------------------
*/
PRIVATE W8 CAL_SetupMapFile( const char *extension )
{
	FILE *handle;
	SW32 length;
	char fname[ 13 ];
	
	
//
// load maphead.xxx (offsets and tileinfo for map file)
//
	cs_strlcpy( fname, MAPHEADNAME, sizeof( fname ) );
	cs_strlcat( fname, extension, sizeof( fname ) );

	handle = fopen( cs_strupr( fname ), "rb" );
	if( handle == NULL )
	{
		handle = fopen( cs_strlwr( fname ), "rb" );
		if( handle == NULL )
		{
			printf( "Could not open file (%s) for read!\n", fname );
			return 0;
		}
	}

	length = FS_FileLength( handle );
	

	fread( &RLEWtag, 2, 1, handle );
	
	for( TotalMaps = 0 ; TotalMaps < length ; ++TotalMaps )
	{
		fread( &headeroffsets[ TotalMaps ], 4, 1, handle );		
		if( ! headeroffsets[ TotalMaps ] )
		{
			break;
		}
	}


	fclose( handle );



	cs_strlcpy( fname, MAPNAME, sizeof( fname ) );
	cs_strlcat( fname, extension, sizeof( fname ) );
	
	maphandle = fopen( cs_strupr( fname ), "rb");
	if( NULL == maphandle )
	{
		maphandle = fopen( cs_strlwr( fname ), "rb");
		if( NULL == maphandle )
		{
			return 0;
		}
	}


	return 1;
}
コード例 #4
0
ファイル: snd_utils.c プロジェクト: Xash3DLinux/xash3dlinux
uint Sound_GetApproxWavePlayLen( const char *filepath )
{
	file_t	*f;
	wavehdr_t	wav;
	size_t	filesize;
	float	seconds;
	uint	samples;

	f = FS_Open( filepath, "rb", false );
	if( !f ) return 0;

	if( FS_Read( f, &wav, sizeof( wav )) != sizeof( wav ))
	{
		FS_Close( f );
		return 0;
	}

	filesize = FS_FileLength( f );
	filesize -= ( sizeof( wavehdr_t ) + sizeof( chunkhdr_t ));

	FS_Close( f );

	// is real wav file ?
	if( wav.riff_id != RIFFHEADER || wav.wave_id != WAVEHEADER || wav.fmt_id != FORMHEADER )
		return 0;

	if( wav.wFormatTag != 1 )
		return 0;

	if( wav.nChannels != 1 && wav.nChannels != 2 )
		return 0;

	if( wav.nBitsPerSample != 8 && wav.nBitsPerSample != 16 )
		return 0;

	// calc samplecount
	seconds = (float)filesize / wav.nAvgBytesPerSec / wav.nChannels;
	samples = (uint)(( wav.nSamplesPerSec * wav.nChannels ) * seconds );

	// g-cont. this function returns samplecount or time in milliseconds ???
	return (uint)(seconds * 1000);
}
コード例 #5
0
// well exec /home/qqshka/ezquake/config.cfg does't work, security or something, so adding this
// so this is some replacement for exec
qbool LoadCfg(FILE *f)
{
	char *fileBuffer;
    int size;

	if (!f) {
		return false;
	}

	size = FS_FileLength(f);
	fileBuffer = Q_malloc(size + 1); // +1 for null terminator
	if (fread(fileBuffer, 1, size, f) != size) {
		Com_Printf("Error reading config file\n");
		Q_free(fileBuffer);
		return false;
	}
	fileBuffer[size] = 0;

	Cbuf_AddText (fileBuffer);
	Cbuf_AddText ("\n");
	Q_free(fileBuffer);
	return true;
}
コード例 #6
0
ファイル: config_manager.c プロジェクト: jogi1/camquake
// well exec /home/qqshka/ezquake/config.cfg does't work, security or something, so adding this
// so this is some replacement for exec
void LoadHomeCfg(const char *filename)
{
	char fullname[MAX_PATH] = {0}, *fileBuffer;
    int size;
    FILE *f;

	snprintf(fullname, sizeof(fullname) - 4, "%s/%s", com_homedir, filename);
	COM_ForceExtensionEx (fullname, ".cfg", sizeof (fullname));

	if (!(f = fopen(fullname, "rb"))) {
	    Com_DPrintf("LoadHomeCfg: %s not found\n", filename); // hrm
		return;
	}

	size = FS_FileLength(f);
	fileBuffer = Q_malloc(size + 1); // +1 for null terminator
	fread(fileBuffer, 1, size, f);
	fileBuffer[size] = 0;
	fclose(f);

	Cbuf_AddText (fileBuffer);
	Cbuf_AddText ("\n");
	Q_free(fileBuffer);
}
コード例 #7
0
ファイル: wolf_aud.c プロジェクト: Anters/Wolf3D-iOS
/*
-----------------------------------------------------------------------------
 Function: CAL_SetupAudioFile() -Setup for decoding audio data.
 
 Parameters: fextension -[in] Pointer to string with file extension.
 
 Returns: Non-zero on success, otherwise zero.
 
 Notes: 
-----------------------------------------------------------------------------
*/
PRIVATE W8 CAL_SetupAudioFile( const char *fextension )
{
	FILE *handle;
	SW32 length;
	W32 count;
	char fname[ 13 ];

	if( ! fextension || ! *fextension )
	{
		printf( "NULL extension passed into CAL_SetupAudioFile!\n" );
		
		return 0;	
	}

//
// load audiohed.XXX (offsets and lengths for audio file)
//
	cs_strlcpy( fname, AHEADFNAME, sizeof( fname ) );
	cs_strlcat( fname, fextension, sizeof( fname ) );
	
    handle = fopen( cs_strupr( fname ), "rb" );
	if( handle == NULL )
	{
		handle = fopen( cs_strlwr( fname ), "rb" );
		
		if( handle == NULL )
		{
			printf( "Can not open file (%s) for read!\n", fname );
			return 0;
		}
    }

	length = FS_FileLength( handle );
	if( length < 4 )
	{
		fclose( handle );
		printf( "Incorrect audio header size on file: %s\n", fname );
		return 0;
	}

	audiostarts = (PW32) MM_MALLOC( length );
	if( audiostarts == NULL )
	{
		return 0;
	}
	
	count = fread( audiostarts, sizeof( W32 ), length >> 2, handle );
	if( count != (W32)(length >> 2) )
    {
        fclose( handle );
        printf( "[Error]: Read error on file: (%s)", fname  );
		return 0;
	}
	
	
	fclose( handle );

//
// open the Audio data file
//
	cs_strlcpy( fname, AUDIOFNAME, sizeof( fname ) );
	cs_strlcat( fname, fextension, sizeof( fname ) );
	
	audiohandle = fopen( cs_strupr( fname ), "rb" );
	if( audiohandle == NULL )
	{
		audiohandle = fopen( cs_strlwr( fname ), "rb" );
		if( audiohandle == NULL )
		{
			printf( "Could not open file (%s) for read!\n", fname ); 
			return 0;
		}
    }
    
    return 1;
}
コード例 #8
0
ファイル: filesystem.c プロジェクト: Jenco420/yquake2
/*
 * Returns file size or -1 if not found. Can open separate files as well as
 * files inside pack files (both PAK and PK3).
 */
int
FS_FOpenFileRead(fsHandle_t *handle)
{
	char path[MAX_OSPATH];
	int i;
	fsSearchPath_t *search;
	fsPack_t *pack;

	file_from_pak = 0;
#ifdef ZIP
	file_from_pk3 = 0;
#endif

	/* Search through the path, one element at a time. */
	for (search = fs_searchPaths; search; search = search->next)
	{
		/* Search inside a pack file. */
		if (search->pack)
		{
			pack = search->pack;

			for (i = 0; i < pack->numFiles; i++)
			{
				if (Q_stricmp(pack->files[i].name, handle->name) == 0)
				{
					/* Found it! */
					Com_FilePath(pack->name, fs_fileInPath,
							sizeof(fs_fileInPath));
					fs_fileInPack = true;

					if (fs_debug->value)
					{
						Com_Printf("FS_FOpenFileRead: '%s' (found in '%s').\n",
								handle->name, pack->name);
					}

					if (pack->pak)
					{
						/* PAK */
						file_from_pak = 1;
						handle->file = fopen(pack->name, "rb");

						if (handle->file)
						{
							fseek(handle->file, pack->files[i].offset, SEEK_SET);
							return pack->files[i].size;
						}
					}
#ifdef ZIP
					else if (pack->pk3)
					{
						/* PK3 */
						file_from_pk3 = 1;
						Q_strlcpy(file_from_pk3_name, strrchr(pack->name,
										'/') + 1, sizeof(file_from_pk3_name));
						handle->zip = unzOpen(pack->name);

						if (handle->zip)
						{
							if (unzLocateFile(handle->zip, handle->name,
										2) == UNZ_OK)
							{
								if (unzOpenCurrentFile(handle->zip) == UNZ_OK)
								{
									return pack->files[i].size;
								}
							}

							unzClose(handle->zip);
						}
					}
#endif

					Com_Error(ERR_FATAL, "Couldn't reopen '%s'", pack->name);
				}
			}
		}
		else
		{
			/* Search in a directory tree. */
			Com_sprintf(path, sizeof(path), "%s/%s", search->path, handle->name);

			handle->file = fopen(path, "rb");

			if (!handle->file)
			{
				Q_strlwr(path);
				handle->file = fopen(path, "rb");
			}

			if (!handle->file)
			{
				continue;
			}

			if (handle->file)
			{
				/* Found it! */
				Q_strlcpy(fs_fileInPath, search->path, sizeof(fs_fileInPath));
				fs_fileInPack = false;

				if (fs_debug->value)
				{
					Com_Printf("FS_FOpenFileRead: '%s' (found in '%s').\n",
							handle->name, search->path);
				}

				return FS_FileLength(handle->file);
			}
		}
	}

	/* Not found! */
	fs_fileInPath[0] = 0;
	fs_fileInPack = false;

	if (fs_debug->value)
	{
		Com_Printf("FS_FOpenFileRead: couldn't find '%s'.\n", handle->name);
	}

	return -1;
}
コード例 #9
0
/**
 * \brief Setup map files for decoding.
 * \param[in] headFileName Name of file with header offsets.
 * \param[in] mapFileName Name of file with map data.
 * \param[in,out] RLEWtag Run length encoded word tag.
 * \param[in,out] nTotalMaps Number of maps in file.
 * \return On success true, otherwise false.
 * \note Must call function MapFile_Shutdown() when done.
 */
PUBLIC wtBoolean MapFile_Setup( const char *headFileName, const char *mapFileName, W16 *RLEWtag, W32 *nTotalMaps )
{
	FILE *fileHandle;
	SW32 fileSize;
	char *tempFileName;
	W32 TotalMaps;



	tempFileName = (char *) MM_MALLOC( strlen( headFileName ) + 1 );
	if( tempFileName == NULL )
	{
		return false;
	}
	
	
//
// Load map head file to get offsets and tile info.
//
	wt_strlcpy( tempFileName, headFileName, strlen( headFileName ) + 1 );

	fileHandle = fopen( wt_strupr( tempFileName ), "rb" );
	if( fileHandle == NULL )
	{
		fileHandle = fopen( wt_strlwr( tempFileName ), "rb" );
		if( fileHandle == NULL )
		{
			fprintf( stderr, "Could not open file (%s) for read!\n", tempFileName );

			MM_FREE( tempFileName );
			
			return false;
		}
	}

	fileSize = FS_FileLength( fileHandle );
	

	fread( RLEWtag, 2, 1, fileHandle );
	
	for( TotalMaps = 0 ; TotalMaps < fileSize ; ++TotalMaps )
	{
		fread( &headerOffsets[ TotalMaps ], 4, 1, fileHandle );		
		if( ! headerOffsets[ TotalMaps ] )
		{
			break;
		}
	}


	fclose( fileHandle );




	MM_FREE( tempFileName );
	tempFileName = (char *) MM_MALLOC( strlen( mapFileName ) + 1 );

	wt_strlcpy( tempFileName, mapFileName, strlen( mapFileName ) + 1 );


//
// Open map data file.
//
	map_file_handle = fopen( wt_strupr( tempFileName ), "rb");
	if( NULL == map_file_handle )
	{
		map_file_handle = fopen( wt_strlwr( tempFileName ), "rb");
		if( NULL == map_file_handle )
		{
			MM_FREE( tempFileName );

			return false;
		}
	}


	*nTotalMaps = TotalMaps;


	MM_FREE( tempFileName );


	return true;
}
コード例 #10
0
ファイル: hpak.c プロジェクト: DavidKnight247/xash3d
void HPAK_AddLump( qboolean add_to_queue, const char *name, resource_t *DirEnt, byte *data, file_t *f )
{
	int		i, position, length;
	string		pakname1, pakname2;
	char		md5[16];
	MD5Context_t	MD5_Hash;
	hpak_container_t	hpak1, hpak2;
	file_t		*f1, *f2;
	hpak_dir_t	*dirs;
	byte		*temp;

	if( !name || !name[0] )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: NULL name\n" );
		return;
	}

	if( !DirEnt )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: invalid lump\n" );
		return;
	}

	if( data == NULL && f == NULL )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: missing lump data\n" );
		return;
	}

	if( DirEnt->nDownloadSize < 1024 || DirEnt->nDownloadSize > 131072 )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: invalid size %s\n", Q_pretifymem( DirEnt->nDownloadSize, 2 ));
		return;
	}

	// hash it
	Q_memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
	MD5Init( &MD5_Hash );

	if( data == NULL )
	{
		// there are better ways
		position = FS_Tell( f );
		temp = Z_Malloc( DirEnt->nDownloadSize );
		FS_Read( f, temp, DirEnt->nDownloadSize );
		FS_Seek( f, position, SEEK_SET );

		MD5Update( &MD5_Hash, temp, DirEnt->nDownloadSize );
		Mem_Free( temp );
	}
	else
	{
		MD5Update( &MD5_Hash, data, DirEnt->nDownloadSize );
	}

	MD5Final( md5, &MD5_Hash );

	if( Q_memcmp( md5, DirEnt->rgucMD5_hash, 0x10 ))
	{
		MsgDev( D_ERROR, "HPAK_AddLump: bad checksum for %s. Ignored\n", DirEnt->szFileName );
		return;
	}

	if( add_to_queue )
	{
		HPAK_AddToQueue( name, DirEnt, data, f );
		return;
	}

	Q_strncpy( pakname1, name, sizeof( pakname1 ));
	FS_StripExtension( pakname1 );
	FS_DefaultExtension( pakname1, ".hpk" );

	f1 = FS_Open( pakname1, "rb", false );

	if( !f1 )
	{
		// create new pack
		HPAK_CreatePak( name, DirEnt, data, f );
		return;
	}

	Q_strncpy( pakname2, pakname1, sizeof( pakname2 ));
	FS_StripExtension( pakname2 );
	FS_DefaultExtension( pakname2, ".hp2" );

	f2 = FS_Open( pakname2, "w+b", false );

	if( !f2 )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: couldn't open %s.\n", pakname2 );
		FS_Close( f1 );
		return;
	}

	// load headers
	FS_Read( f1, &hash_pack_header, sizeof( hpak_header_t ));

	if( hash_pack_header.version != IDCUSTOM_VERSION )
	{
		// we don't check the HPAK bit for some reason.
		MsgDev( D_ERROR, "HPAK_AddLump: %s does not have a valid header.\n", pakname2 );
		FS_Close( f1 );
		FS_Close( f2 );
	}

	length = FS_FileLength( f1 );
	HPAK_FileCopy( f2, f1, length );

	FS_Seek( f1, hash_pack_header.seek, SEEK_SET );
	FS_Read( f1, &hpak1.count, sizeof( hpak1.count ));

	if( hpak1.count < 1 || hpak1.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: %s contain too many lumps.\n", pakname1 );
		FS_Close( f1 );
		FS_Close( f2 );
		return;
	}

	// load the data
	hpak1.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak1.count );
	FS_Read( f1, hpak1.dirs, sizeof( hpak_dir_t ) * hpak1.count );
	FS_Close( f1 );

	if( HPAK_FindResource( &hpak1, DirEnt->rgucMD5_hash, NULL ))
	{
		Mem_Free( hpak1.dirs );
		FS_Close( f2 );
	}

	// make a new container
	hpak2.count = hpak1.count;
	hpak2.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak2.count );
	Q_memcpy( hpak2.dirs, hpak1.dirs, hpak1.count );

	for( i = 0, dirs = NULL; i < hpak1.count; i++ )
	{
		if( Q_memcmp( hpak1.dirs[i].DirectoryResource.rgucMD5_hash, DirEnt->rgucMD5_hash, 16 ) < 0 )
		{
			dirs = &hpak1.dirs[i];
			while( i < hpak1.count )
			{
				hpak2.dirs[i+1] = hpak1.dirs[i];
				i++;
			}
			break;
		}
	}

	if( dirs == NULL ) dirs = &hpak2.dirs[hpak2.count-1];

	Q_memset( dirs, 0, sizeof( hpak_dir_t ));
	FS_Seek( f2, hash_pack_header.seek, SEEK_SET );
	dirs->DirectoryResource = *DirEnt;
	dirs->seek = FS_Tell( f2 );
	dirs->size = DirEnt->nDownloadSize;

	if( !data ) HPAK_FileCopy( f2, f, dirs->size );
	else FS_Write( f2, data, dirs->size );

	hash_pack_header.seek = FS_Tell( f2 );
	FS_Write( f2, &hpak2.count, sizeof( hpak2.count ));

	for( i = 0; i < hpak2.count; i++ )
	{
		FS_Write( f2, &hpak2.dirs[i], sizeof( hpak_dir_t ));
	}

	// finalize
	Mem_Free( hpak1.dirs );
	Mem_Free( hpak2.dirs );

	FS_Seek( f2, 0, SEEK_SET );
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));
	FS_Close( f2 );

	FS_Delete( pakname1 );
	FS_Rename( pakname2, pakname1 );
}
コード例 #11
0
ファイル: snd_mp3.c プロジェクト: aktel/surface_multiplayer
/*
=================
Stream_OpenMPG
=================
*/
stream_t *Stream_OpenMPG( const char *filename )
{
	mpeg_t	*mpegFile;
	stream_t	*stream;
	file_t	*file;
	long	filesize, read_len;
	char	tempbuff[FRAME_SIZE];

	file = FS_Open( filename, "rb", false );
	if( !file ) return NULL;

	filesize = FS_FileLength( file );
	if( filesize < FRAME_SIZE )
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		FS_Close( file );
		return NULL;
	}

	// at this point we have valid stream
	stream = Mem_Alloc( host.soundpool, sizeof( stream_t ));
	stream->file = file;
	stream->pos = 0;

	mpegFile = Mem_Alloc( host.soundpool, sizeof( mpeg_t ));

	// couldn't create decoder
	if( !create_decoder( mpegFile ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder\n" );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	read_len = FS_Read( file, tempbuff, sizeof( tempbuff ));
	if( read_len < sizeof( tempbuff ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	// trying to read header
	if( !read_mpeg_header( mpegFile, tempbuff, sizeof( tempbuff ), filesize ))
	{
		MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	stream->buffsize = 0; // how many samples left from previous frame
	stream->channels = mpegFile->channels;
	stream->pos += mpegFile->outsize;
	stream->rate = mpegFile->rate;
	stream->width = 2;	// always 16 bit
	stream->ptr = mpegFile;
	stream->type = WF_MPGDATA;

	return stream;
}
コード例 #12
0
/**
 * \brief Setup for audio decoding.
 * \param[in] aheadfname Audio header file name. 
 * \param[in] audfname Audio file name. 
 * \return On success true, otherwise false.
 */
PUBLIC wtBoolean AudioFile_Setup( const char *aheadfname, const char *audfname )
{
	char tempFileName[ 1024 ];
	FILE *handle;
	SW32 length;
	SW32 count;		/* Number of bytes read from file */

	if( ! aheadfname || ! *aheadfname ||
		! audfname || ! *audfname )
	{
		fprintf( stderr, "[AudioFile_Setup]: NULL file name!\n" );
		
		return false;	
	}

//
// Load audiohed.XXX (offsets and lengths for audio file)
//
	wt_strlcpy( tempFileName, aheadfname, sizeof( tempFileName ) );
		
    handle = fopen( wt_strupr( tempFileName ), "rb" );
	if( handle == NULL )
	{
		handle = fopen( wt_strlwr( tempFileName ), "rb" );
		
		if( handle == NULL )
		{
			fprintf( stderr, "Could not open file (%s) for read!\n", tempFileName );
			
			return false;
		}
    }

	length = FS_FileLength( handle );
	if( length < 4 )
	{
		fclose( handle );

		fprintf( stderr, "[AudioFile_Setup]: Incorrect audio header size on file: %s\n", tempFileName );

		return false;
	}


	audiostarts = (PW32) MM_MALLOC( length );
	if( audiostarts == NULL )
	{
		fclose( handle );

		return false;
	}


	count = fread( audiostarts, 1, length, handle );
	if( count != length )
    {
        fclose( handle );

        fprintf( stderr, "[AudioFile_Setup]: Read error on file: (%s)", tempFileName  );

		return false;
	}


	fclose( handle );

//
// Open the Audio data file
//
	wt_strlcpy( tempFileName, audfname, sizeof( tempFileName ) );
	
	audiohandle = fopen( wt_strupr( tempFileName ), "rb" );
	if( audiohandle == NULL )
	{
		audiohandle = fopen( wt_strlwr( tempFileName ), "rb" );
		if( audiohandle == NULL )
		{
			fprintf( stderr, "[AudioFile_Setup]: Could not open file (%s) for read!\n", tempFileName ); 
			
			return false;
		}
    }
    
    return true;
}
コード例 #13
0
ファイル: cp_save.cpp プロジェクト: MyWifeRules/ufoai-1
/**
 * @brief Loads the given savegame from an xml File.
 * @return true on load success false on failures
 * @param[in] file The Filename to load from (without extension)
 * @param[out] error On failure an errormessage may be set.
 */
bool SAV_GameLoad (const char *file, const char **error)
{
	char filename[MAX_OSPATH];
	qFILE f;
	int i, clen;
	xmlNode_t *topNode, *node;
	saveFileHeader_t header;

	Q_strncpyz(filename, file, sizeof(filename));

	/* open file */
	FS_OpenFile(va("save/%s.%s", filename, SAVEGAME_EXTENSION), &f, FILE_READ);
	if (!f.f) {
		Com_Printf("Couldn't open file '%s'\n", filename);
		*error = "File not found";
		return false;
	}

	clen = FS_FileLength(&f);
	byte* const cbuf = Mem_PoolAllocTypeN(byte, clen + 1 /* for '\0' if not compressed */, cp_campaignPool);
	if (FS_Read(cbuf, clen, &f) != clen)
		Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
	FS_CloseFile(&f);
	Com_Printf("Loading savegame xml (size %d)\n", clen);

	memcpy(&header, cbuf, sizeof(header));
	/* swap all int values if needed */
	header.compressed = LittleLong(header.compressed);
	header.version = LittleLong(header.version);
	header.xmlSize = LittleLong(header.xmlSize);
	/* doing some header verification */
	if (!SAV_VerifyHeader(&header)) {
		/* our header is not valid, we MUST abort loading the game! */
		Com_Printf("The Header of the savegame '%s.%s' is corrupted. Loading aborted\n", filename, SAVEGAME_EXTENSION);
		Mem_Free(cbuf);
		*error = "Corrupted header";
		return false;
	}

	Com_Printf("Loading savegame\n"
			"...version: %i\n"
			"...game version: %s\n"
			"...xml Size: %i, compressed? %c\n",
			header.version, header.gameVersion, header.xmlSize, header.compressed ? 'y' : 'n');

	if (header.compressed) {
		uLongf      len = header.xmlSize + 1 /* for '\0' */;
		byte* const buf = Mem_PoolAllocTypeN(byte, len /* sic, old savegames contain one (garbage) byte more than the header says. */, cp_campaignPool);
		/* uncompress data, skipping comment header */
		const int res = uncompress(buf, &len, cbuf + sizeof(header), clen - sizeof(header));
		buf[header.xmlSize] = '\0'; /* Ensure '\0' termination. */
		Mem_Free(cbuf);

		if (res != Z_OK) {
			Mem_Free(buf);
			*error = _("Error decompressing data");
			Com_Printf("Error decompressing data in '%s'.\n", filename);
			return false;
		}
		topNode = XML_Parse((const char*)buf);
		if (!topNode) {
			Mem_Free(buf);
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return false;
		}
		Mem_Free(buf);
	} else {
		topNode = XML_Parse((const char*)(cbuf + sizeof(header)));
		Mem_Free(cbuf);
		if (!topNode) {
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return false;
		}
	}

	/* doing a subsystem run */
	GAME_ReloadMode();
	node = XML_GetNode(topNode, SAVE_ROOTNODE);
	if (!node) {
		Com_Printf("Error: Failure in loading the xml data! (savegame node not found)\n");
		mxmlDelete(topNode);
		*error = "Invalid xml data";
		return false;
	}

	Com_Printf("Load '%s' %d subsystems\n", filename, saveSubsystemsAmount);
	for (i = 0; i < saveSubsystemsAmount; i++) {
		Com_Printf("...Running subsystem '%s'\n", saveSubsystems[i].name);
		if (!saveSubsystems[i].load(node)) {
			Com_Printf("...subsystem '%s' returned false - savegame could not be loaded\n",
					saveSubsystems[i].name);
			*error = va("Could not load subsystem %s", saveSubsystems[i].name);
			return false;
		} else
			Com_Printf("...subsystem '%s' - loaded.\n", saveSubsystems[i].name);
	}
	mxmlDelete(node);
	mxmlDelete(topNode);

	if (!SAV_GameActionsAfterLoad()) {
		Com_Printf("Savegame postprocessing returned false - savegame could not be loaded\n");
		*error = "Postprocessing failed";
		return false;
	}

	Com_Printf("File '%s' successfully loaded from %s xml savegame.\n",
			filename, header.compressed ? "compressed" : "");

	cgi->UI_InitStack("geoscape", NULL, true, true);
	return true;
}