⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		
		dirtemp = dirp;
		dirp = ( Directory* )dirp->items[1].address;
		if( dirp == NULL )
			break;
		dirp->cur ++;
		if( dirp->items[1].address == 0 && dirp->cur >= dirp->num )
			break;
		chdir( ".." );
	}
	
	fclose( fp );
	chdir( curPath );
	free( curPath );
	return 0;
}

// pack the files in the spath into package, exclude subdirectory
// it's used to create directory tree
Directory*  PackSubdir( DWORD& fpos, char *dpath, char *spath )
{
	printf( "pack subdir %s \n", spath );
	
//	DIR *dirp;
//	dirent *direntp;
	_finddata_t fd;
	long hFile;
	int ftemp;
	int i;
	Directory *dir;
	
	dir = new Directory;
	if( dir == NULL )
		return NULL;
		
	if( _chdir( spath ) == -1 ){
		goto error;
	}
	
	// num includes all files and subdirs and '..' '.' )
	dir->num = FileCount( spath ) + 2;
	printf( "total files:%d\n", dir->num );
	
	dir->items = new DirItem[ dir->num ];
	memset( (char*)dir->items, 0, sizeof( DirItem ) * dir->num );
	if( dir->items == NULL ){
		delete dir;
		return NULL;
	}
	 
	// items[0] is point to this directory
	strcpy( dir->items[0].filename, dpath );
	dir->items[0].address = fpos;
					// sizeof( DirItem ) = 22
	dir->items[0].length = sizeof(Directory) + 22*UPROUND( dir->num, DIRITEM_UNIT );
	dir->items[0].type = DIR_DISK;
	// items[1] is point to the parent directory
	strcpy( dir->items[1].filename, ".." );
	dir->items[1].type = DIR_DISK;

	fpos += dir->items[0].length;
	
	if(( hFile = _findfirst( "*.*", &fd )) == -1 )
		return NULL;
	for( i=2; i<dir->num; i++ ){
		if( fd.name[0] == '.' ){
			i--;
			continue;
		}
		
		if( !( fd.attrib & _A_SUBDIR )){ // file
			if( (ftemp = open( fd.name, O_RDONLY )) == -1 ){
#ifdef _DEBUG
				puts( fd.name );
#endif
				return NULL;
			}
			
			puts( fd.name );
			strcpy( dir->items[i].filename, fd.name );
			dir->items[i].address = fpos;
			dir->items[i].type = ARCHIVE;
			dir->items[i].length = filelength( ftemp );
			fpos += dir->items[i].length;
			
			close( ftemp );
		}
		else if( fd.attrib & _A_SUBDIR ){ // subdirectory
			puts( fd.name );
			dir->items[i].type = DIR_DISK;
			strcpy( dir->items[i].filename, fd.name );
		}
		_findnext( hFile, &fd );
	}
	
	puts( "pack subdir end." );
	return dir;

error:
	delete dir;
	return NULL;
}

Directory* ReadDirFromDisk( FILE *fp, long fpos, Directory* parent )
{
	if( fsetpos( fp, (fpos_t*)&fpos ) != 0 )
		return NULL;

	Directory *dir = new Directory;
	if( dir == NULL )
		return NULL;
	if( dir->ReadDisk( fp ) != 0 ){
		delete dir;
		return NULL;
	}
	dir->items[1].address = ( DWORD )parent;
	
	return dir;
}
/////////////////////////////////////////////////////////////////////

PackFile::PackFile()
{
	for( int i=0; i<MAX_CFILE_NUM; i++ ){
		file[i].fname[0] = 0;
		file[i].root = NULL;
//		file[i].fp = NULL;
//		count[i] = 0;
	}
}

PackFile::~PackFile()
{
	for( int i=0; i<MAX_CFILE_NUM; i++ ){
		if( file[i].root )
			Close( i );
	}
}

// example:convert "aaa.bmp" to "aaa     bmp"
// not been used !!
void PackFile::FixFname( char *newfname, char *fname )
{
	int i = 0;
	memset( newfname, ' ', 11 );
	newfname[11] = 0;
	
	while( *fname ){
		if( *fname != '.' ){
			*newfname++ = *fname;
			i++;
		}
		else{
			newfname += 7 - i;
		}
		fname ++;
	}
}
	
int PackFile::Close( char* fname )
{
	for( int i=0; i<MAX_CFILE_NUM; i++ ){
		if( strcmp( file[i].fname, fname ) == 0 )
			return Close( i );
	}
	return -1;
}

// free the memory occupied by the package file[id]
int PackFile::Close( int id )
{
	if( file[id].root == NULL )
		return 0;
		
	Directory *dirp = file[id].root, *dirtemp;
	
	dirp->cur = 2;
	while( 1 ){
		while( dirp->cur < dirp->num ){
			if( dirp->items[dirp->cur].type == DIR_RAM ){
				dirtemp = ( Directory* )dirp->items[dirp->cur].address;
				if( dirtemp == NULL )
					return -1;
				dirp = dirtemp;
				dirp->cur = 2;
			}
			else
				dirp->cur ++;
		}
		
		dirtemp = dirp;
		dirp = ( Directory* )dirp->items[1].address;
		if( dirp == NULL )
			break;
		dirp->cur ++;
		if( dirp->items[1].address == 0 && dirp->cur >= dirp->num )
			break;
		delete dirtemp;
	}
	delete file[id].root;
	file[id].root = NULL;
	file[id].fname[0] = 0;
	
	return 0;
}

// open package file
int PackFile::OpenCfile( int id, char *filename )
{
	FILE *fp;
	
	if( (fp = fopen( filename, "rb" )) == NULL )
		return -1;
	if(( file[id].root = ReadDirFromDisk( fp, 0, NULL )) == NULL ){
		fclose( fp );
		return -1;
	}
	strcpy( file[id].fname, filename );
	file[id].currentDir = NULL;
	file[id].currentPath[0] = 0;
	
	fclose( fp );
	return 0;
}

// open subfile in the package file
File* PackFile::OpenSubfile( int id, char* subname )
{
	if( file[id].root == NULL )
		return NULL;
		
	FILE *fp;
	if((fp = fopen( file[id].fname, "rb" )) == NULL )
		return NULL;
	
	int i, j;
	char dname[13], path[MAX_PATH_LEN];
	Directory* dirp, *dirtemp;

	GetPathName( path, subname );
	if( file[id].currentDir && strcmp( file[id].currentPath, path ) == 0 ){
	// currentPath can accelerate the finding speed
		dirp = file[id].currentDir;
		if(( j = dirp->SearchDir( dname, ARCHIVE )) != 0 )
			goto foundsubfile;
	}

	i = 1;	
	dirp = file[id].root;	 
	while( GetDirName( dname, subname, i ) ){
	//	printf( "%s: %d, %s\n", subname, i, dname );
	// find the subdirectory in the directory tree
		if( (j = dirp->SearchDir( dname, DIR_DISK | DIR_RAM )) != 0 ){
			if( dirp->items[j].type == DIR_DISK ){
				dirtemp = ReadDirFromDisk( fp, dirp->items[j].address, dirp );
				if( dirtemp == NULL )
					return NULL;
				dirp->items[j].address = ( DWORD )dirtemp;
				dirp->items[j].type = DIR_RAM;
				dirp = dirtemp;
			}
			else
				dirp = ( Directory* )dirp->items[j].address;
		}
		else{
			puts( "not found " );
			return NULL;
		}
		i ++;
	}

	GetFileName( dname, subname );
#ifdef _DEBUG
	puts( dname );
#endif
	if((j = dirp->SearchDir( dname, ARCHIVE )) != 0 ){
	// find and open the subfile 
		file[id].currentDir = dirp;
		strcpy( file[id].currentPath, path );
foundsubfile:		
		File* subf = new File;
		subf->fp = fp;
		subf->address = dirp->items[j].address;
		subf->length = dirp->items[j].length;
		fseek( fp, subf->address, SEEK_SET );
		return subf;
	}
	else{
		fclose( fp );
		return NULL;
	}
}

// normal file does not occupy PackFile resource
File* PackFile::OpenNormalFile( char* filename )
{
	FILE *fp;
	if(( fp = fopen( filename, "rb" )) == NULL ){
#ifdef _DEBUG
		printf( "in CFil::OpenNormalFile: open file %s error\n", filename );
#endif
		return NULL;
	}
	
	File *subfp = new File;
	if( subfp == NULL )
		goto error;
		
	subfp->fp = fp;
	subfp->address = 0;
	subfp->length = filelength( fileno( fp ));
	return subfp;

error:
	delete subfp;
	fclose( fp );
	return NULL;	
}

// fname format: packagefilename#directory/subfilename
File* PackFile::Open( char* fname )
{
	char *p;
	int i, lessuse;
	
	strupr( fname );
	if(( p = strchr( fname, '#' )) == NULL )
		// the fname isn't a package file's name
		return OpenNormalFile( fname );
	
	// fname include package file name, but with no subfile name	
	if( *( p+1 ) == 0 )
		return NULL;	
		
	*p = 0;

#ifdef _DEBUG
	puts( fname );
#endif
	
	for( i=0; i<MAX_CFILE_NUM; i++ ){
		if( strcmp( file[i].fname, fname ) == 0 ){
		// package file has been opened
			return OpenSubfile( i, p+1 );
		}
	}
	
	// package file hasn't been opened
	for( i=0, lessuse=-1; i<MAX_CFILE_NUM; i++ ){
		if( file[i].root == NULL )
			lessuse = i;
	}
	if( lessuse < 0 )	// no space to open package file
		return NULL;
	OpenCfile( lessuse, fname );
	return OpenSubfile( lessuse, p+1 );
}


/*void main( void )
{
	puts( "package" );
	PackFile cfile;

	
	if( cfile.Open( "d:\\wcpp\\gamedev\\mytext.pak#dat\\wav\\song.wav" ) )
		puts( "OK" );
	else
		puts( "shit" );

	CreatePackage( "d:\\wcpp\\gamedev\\vbe\\text.pak", "d:\\wcpp\\gamedev\\vbe\\pic" );
	puts( "create packgae" );
}

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -