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

📄 file.cpp

📁 diablo 游戏部分源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "gl.h"

#define UPROUND( a, b )	((a)+((b)-1))/(b)*(b)

#define DIRITEM_UNIT	64

#define NONE    0
#define ARCHIVE 1
#define DIR_DISK 2
#define DIR_RAM 4

PackFile cfile;

Directory*  PackSubdir( DWORD& fp, char *dpath, char *spath );

/////////////////////////////////////////////////////////////////////
Directory::~Directory()
{
	delete[] items;
}

// read directory from disk
int Directory::ReadDisk( FILE *fp )
{
	if( items )
		delete[] items;

	fread( &cur, sizeof( long ), 1, fp );
	fread( &num, sizeof( long ), 1, fp );
	fread( &items, sizeof( DirItem* ), 1, fp );
	
	items = new DirItem[num];
	if( items == NULL )
		return -1;
	for( int i=0; i<num; i++ ){
		fread( &items[i].type, sizeof( BYTE ), 1, fp );
		fread( items[i].filename, 13, 1, fp );
//		puts( items[i].filename );
		fread( &items[i].address, sizeof( DWORD ), 1, fp );
		fread( &items[i].length, sizeof( DWORD ), 1, fp );
	}
	if( errno ){
		delete[] items;
		return -1;
	}
	return 0;
}

// whether the dname is in this directory
int Directory::SearchDir( char dname[13], int type )
{
	if( strcmp( items[cur].filename, dname ) == 0
		&& ( items[cur].type & type ))
		return cur;
		
	for( int i=2; i<num; i++ ){
		if( strcmp( items[i].filename, dname ) == 0 
			&& ( items[i].type & type ))
			return i;
	}
	return 0;
}
/////////////////////////////////////////////////////////////////////
File::File(){
	fp = NULL;
	count = 0;
};

File::~File()
{
	if( fp != NULL )
		fclose( fp );
}

int File::Close( void ){
	if( fp ) return fclose( fp );
	return -1;
}
	
char* File::Gets( char* buf, int size )
{
	fpos_t pos1, pos2;
	char *temp;
	fgetpos( fp, &pos1 );
	temp = fgets( buf, size, fp );
	fgetpos( fp, &pos2 );
	count += (DWORD)(pos2 - pos1);
	return temp;
}

int File::Getw( void )
{
	int w;
	if( length - count - 2 < 0 )
		return EOF;
	count += fread( &w, 1, 2, fp );
	return w;
}

int File::Getdw( void )
{
	int dw;
	if( length - count - 4 < 0 )
		return EOF;
	count += fread( &dw, 1, 4, fp );
	return dw;
}

int File::Read( void* buffer, DWORD size )
{
	int rs;
	if( length - count - size < 0 )
		size = length - count;
	rs = fread( buffer, 1, size, fp );
	count += rs;
	return rs;
}

int File::Seek( DWORD d, int mode )
{
	switch( mode ){
	case SEEK_SET:
	break;
	
	case SEEK_CUR:
	default:
		d += count;
	break;
	
	case SEEK_END:
		d += length - 1;
	break;
	}

	if( d > length ){
		d = length - count - 1;
		count = length - 1;
	}
	else if( d < 0 ){
		d = 0 - count;
		count = 0;
	}
	else{
		d = d - count;
		count += d;
	}

	return fseek( fp, d, SEEK_CUR );

	fpos_t t;
	fgetpos( fp, &t );
	printf( "fpos: %u\n", t );
	return 0;
}

/////////////////////////////////////////////////////////////////////
// helper functions
int FileCount( char *path )
{
	_finddata_t fd;
	long hFile;
	int i = 0;

	if(( hFile = _findfirst( "*.*", &fd )) == -1 )
		return 0;
	i++;
	while( (_findnext( hFile, &fd )) == 0 ){
		if( fd.name[0] != '.' )
			i++;
	}

	return i;
}

int GetDirName( char* dname, char* fullname, int level )
{
	if( level <= 0 ){
		dname[0] = 0;
		return false;
	}
	char *temp = fullname;
	
	while( *fullname ){
		if( *fullname == '\\' ){
			level --;
			if( level == 0 ){
				while( *temp != '\\' )
					*dname++ = *temp ++;
				*dname = 0;
				return true;
			}
			temp = fullname + 1;
		}
		fullname ++;
	}
	
	return false;
}

int GetFileName( char* dname, char *fullname )
{
	char *temp = fullname;
	
	while( *fullname ){
		if( *fullname == '\\' )
			temp = fullname + 1;
		fullname ++;
	}
	while( *temp )
		*dname++ = *temp++;
	*dname = 0;
		
	return true;
}

int GetPathName( char* dname, char *fullname )
{
	char *temp = NULL, *pname = fullname;
	
	while( *pname ){
		if( *pname == '\\' )
			temp = pname;
		pname ++;
	}
	pname = fullname;
	while( pname <= temp )
		*dname++ = *pname++;
	*dname = 0;
		
	return true;
}

/////////////////////////////////////////////////////////////////////
//将一个目录下的所有文件(包括子目录)打包成一个文件.
/////////////////////////////////////////////////////////////////////
// filename: destination package filename
// mode: CFILE_APPEND, CFILE_DELETE, CFILE_CREATE

static int WriteDirToDisk( FILE *fp, Directory *dir )
{
	FILE *file;
	int j;
	Directory *dirtemp;
	
	fwrite( &(dir->cur), sizeof( long ), 1, fp );
	fwrite( &(dir->num), sizeof( long ), 1, fp );
	fwrite( &(dir->items), sizeof( DirItem* ), 1, fp );
	
// write items[0] to disk
	fwrite( &(dir->items[0].type), sizeof( BYTE ), 1, fp );
	fwrite( dir->items[0].filename, 13, 1, fp );
	fwrite( &(dir->items[0].address), sizeof( DWORD ), 1, fp );
	fwrite( &(dir->items[0].length), sizeof( DWORD ), 1, fp );
// write items[1] to disk
	fwrite( &(dir->items[1].type), sizeof( BYTE ), 1, fp );
	fwrite( dir->items[1].filename, 13, 1, fp );
	dirtemp = ( Directory* )(dir->items[1].address);
	if( dirtemp )
		fwrite( &(dirtemp->items[0].address), sizeof( DWORD ), 1, fp );
	else
		fwrite( &(dir->items[1].address), sizeof( DWORD ), 1, fp );
	fwrite( &(dir->items[1].length), sizeof( DWORD ), 1, fp );

	for( int i=2; i<dir->num; i++ ){
		if( dir->items[i].type == DIR_DISK ){
			fwrite( &(dir->items[i].type), sizeof( BYTE ), 1, fp );
			fwrite( dir->items[i].filename, 13, 1, fp );
			dirtemp = ( Directory* )dir->items[i].address;
			fwrite( &(dirtemp->items[0].address), sizeof( DWORD ), 1, fp );
			fwrite( &(dir->items[i].length), sizeof( DWORD ), 1, fp );
		}
		else{
			fwrite( &(dir->items[i].type), sizeof( BYTE ), 1, fp );
			fwrite( dir->items[i].filename, 13, 1, fp );
			fwrite( &(dir->items[i].address), sizeof( DWORD ), 1, fp );
			fwrite( &(dir->items[i].length), sizeof( DWORD ), 1, fp );
		}
	}

	char *buf = new char[4096];
	if( buf == NULL )
		return -1;
	for( i=2; i<dir->num; i++ ){
		if( dir->items[i].type == ARCHIVE ){
			puts( dir->items[i].filename );
			fflush( fp );
			if( ( file = fopen( dir->items[i].filename, "rb" )) == NULL )
				return -1;
			fseek( fp, dir->items[i].address, SEEK_SET );
			while( (j = fread( buf, 1, 4096, file )) != 0 )
				fwrite( buf, 1, j, fp );
			fclose( file );
		}
	}
	if( errno )
		return -1;
		
	return 0;
}

int CreatePackage( char *filename, char *spath )
{
	FILE *fp;
	Directory *dirp, *dirtemp, *dirsave;
	char *curPath;
	DWORD fpos = 0;
	
	if( (fp = fopen( filename, "wb+" )) == NULL )
		return -1;
		
	if( (curPath = getcwd( NULL, 0 )) == NULL )
		return -1;

	if( chdir( spath ) != 0 )
		return -1;
	
	dirp = PackSubdir( fpos, "\\", "." );
	dirsave = dirp;
	dirp->items[0].address = dirp->items[1].address = 0;
	dirp->cur = 2;
	
//create dirctory tree first
	while( 1 ){
		while( dirp->cur < dirp->num ){
			if( dirp->items[dirp->cur].type == DIR_DISK ){
			
				chdir( dirp->items[dirp->cur].filename );
				dirtemp = PackSubdir( fpos, dirp->items[dirp->cur].filename, "." );
				if( dirtemp == NULL )
					return -1;
				dirtemp->items[1].address = ( DWORD )dirp;
				dirtemp->items[1].length = dirp->items[0].length;
				dirp->items[dirp->cur].address = ( DWORD )dirtemp;
				dirp->items[dirp->cur].length = dirtemp->items[0].length;
				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;
		chdir( ".." );
	}
	
// then, we write directory tree and its files to disk
	puts( "write to disk." );
	dirp = dirsave;
	dirp->cur = 2;
	chdir( spath );
	WriteDirToDisk( fp, dirp );
	while( 1 ){
		while( dirp->cur < dirp->num ){
			if( dirp->items[dirp->cur].type == DIR_DISK ){
			
				chdir( dirp->items[dirp->cur].filename );
				dirtemp = ( Directory* )dirp->items[dirp->cur].address;
				dirp = dirtemp;
				dirp->cur = 2;
				
				WriteDirToDisk( fp, dirtemp );
			}
			else
				dirp->cur ++;

⌨️ 快捷键说明

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