Beispiel #1
0
// reads all pak files from a dir
void vfsInitDirectory(const char *path)
{
	char            filename[PATH_MAX];
	char           *dirlist;
	GDir           *dir;

	if(g_numDirs == (VFS_MAXDIRS - 1))
		return;

	Sys_Printf("VFS Init: %s\n", path);

	strcpy(g_strDirs[g_numDirs], path);
	vfsFixDOSName(g_strDirs[g_numDirs]);
	vfsAddSlash(g_strDirs[g_numDirs]);
	g_numDirs++;

	if(g_bUsePak)
	{
		dir = g_dir_open(path, 0, NULL);

		if(dir != NULL)
		{
			while(1)
			{
				const char     *name = g_dir_read_name(dir);

				if(name == NULL)
					break;

				dirlist = g_strdup(name);

				{
					char           *ext = strrchr(dirlist, '.');

					if(ext && !Q_stricmp(ext, ".pk3dir")) 
					{
						if(g_numDirs == VFS_MAXDIRS)
							continue;
						//snprintf(g_strDirs[g_numDirs], PATH_MAX, "%s/%s", path, name);
						sprintf(g_strDirs[g_numDirs], "%s/%s", path, name);
						Sys_Printf("VFS Init: %s (pk3dir)\n", g_strDirs[g_numDirs]);
						g_strDirs[g_numDirs][PATH_MAX] = '\0';
						vfsFixDOSName (g_strDirs[g_numDirs]);
						vfsAddSlash (g_strDirs[g_numDirs]);
						++g_numDirs;
					}

					if((ext == NULL) || (Q_stricmp(ext, ".pk3") != 0))
						continue;
				}

				sprintf(filename, "%s/%s", path, dirlist);
				vfsInitPakFile(filename);

				g_free(dirlist);
			}
			g_dir_close(dir);
		}
	}
}
Beispiel #2
0
// return the number of files that match
int vfsGetFileCount (const char *filename)
{
  int i, count = 0;
  char fixed[NAME_MAX], tmp[NAME_MAX];
  GSList *lst;
  
  strcpy (fixed, filename);
  vfsFixDOSName (fixed);
  g_strdown (fixed);
  
  for (lst = g_pakFiles; lst != NULL; lst = g_slist_next (lst))
  {
    VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;
    
    if (strcmp (file->name, fixed) == 0)
      count++;
  }
  
  for (i = 0; i < g_numDirs; i++)
  {
    strcpy (tmp, g_strDirs[i]);
    strcat (tmp, fixed);
    if (access (tmp, R_OK) == 0)
      count++;
  }
  
  return count;
}
Beispiel #3
0
void vfsInitDirectory (const char *path)
{
  char filename[PATH_MAX];
  //struct dirent *direntry;
  GDir *dir;
  GSList *dirlist = NULL;

  if (g_numDirs == (VFS_MAXDIRS-1))
    return;

  strcpy (g_strDirs[g_numDirs], path);
  vfsFixDOSName (g_strDirs[g_numDirs]);
  vfsAddSlash (g_strDirs[g_numDirs]);
  g_numDirs++;

  if (g_bUsePak)
  {
    dir = g_dir_open (path, 0, NULL);
    if (dir != NULL)
    {
      g_FuncTable.m_pfnSysPrintf("vfs directory: %s\n", path);

	  for(;;)
      {
        const char* name = g_dir_read_name(dir);
        if(name == NULL)
          break;

        char *ext = strrchr (name, '.');
        if ((ext == NULL) || (strcasecmp (ext, ".pak") != 0))
          continue;

        char* direntry = g_strdup(name);
		dirlist = g_slist_append (dirlist, direntry);
      }

      g_dir_close (dir);


      // sort them
      dirlist = g_slist_sort (dirlist, vfsPakSort);

      // add the entries to the vfs and free the list
      while (dirlist)
      {
        GSList *cur = dirlist;
        char* name = (char*)cur->data;

        sprintf (filename, "%s/%s", path, name);
        vfsInitPakFile (filename);

        g_free (name);
        dirlist = g_slist_remove (cur, name);
      }
    } else
          g_FuncTable.m_pfnSysFPrintf(SYS_WRN, "vfs directory not found: %s\n", path);

  }
}
Beispiel #4
0
void vfsCleanFileName( char *in ){
	strlwr( in );
	vfsFixDOSName( in );
	int n = strlen( in );
	if ( in[n - 1] == '/' ) {
		in[n - 1] = '\0';
	}
}
Beispiel #5
0
// 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 ){
	int i, count = 0;
	char tmp[NAME_MAX], fixed[NAME_MAX];
	GSList *lst;

	*bufferptr = NULL;
	strcpy( fixed, filename );
	vfsFixDOSName( fixed );
	strlwr( fixed );

	for ( i = 0; i < g_numDirs; i++ )
	{
		strcpy( tmp, g_strDirs[i] );
		strcat( tmp, filename );
		if ( access( tmp, R_OK ) == 0 ) {
			if ( count == index ) {
				return vfsLoadFullPathFile( tmp,bufferptr );
			}

			count++;
		}
	}

	for ( lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) )
	{
		VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;

		if ( strcmp( file->name, fixed ) != 0 ) {
			continue;
		}

		if ( count == index ) {
			memcpy( file->zipfile, &file->zipinfo, sizeof( unz_s ) );

			if ( unzOpenCurrentFile( file->zipfile ) != UNZ_OK ) {
				return -1;
			}

			*bufferptr = g_malloc( file->size + 1 );
			// we need to end the buffer with a 0
			( (char*) ( *bufferptr ) )[file->size] = 0;

			i = unzReadCurrentFile( file->zipfile, *bufferptr, file->size );
			unzCloseCurrentFile( file->zipfile );
			if ( i > 0 ) {
				return file->size;
			}
			else{
				return -1;
			}
		}

		count++;
	}

	return -1;
}
Beispiel #6
0
// removed CString usage
void vfsCleanFileName( char *in ){
	char str[PATH_MAX];
	vfsBuildShortPathName( in, str, PATH_MAX );
	strlwr( str );
	vfsFixDOSName( str );
	int n = strlen( str );
	if ( str[n - 1] == '/' ) {
		str[n - 1] = '\0';
	}
	strcpy( in, str );
}
Beispiel #7
0
// HYDRA: this now searches VFS/PAK files in addition to the filesystem
// if FLAG is unspecified then ONLY dirs are searched.
// PAK's are searched before DIRs to mimic engine behaviour
// index is ignored when searching PAK files.
// see ifilesystem.h
char* vfsGetFullPath(const char *in, int index, int flag)
{
  int count = 0;
  static char out[PATH_MAX];
  char tmp[NAME_MAX];
  int i;

  if (flag & VFS_SEARCH_PAK)
  {
    char fixed[NAME_MAX];
    GSList *lst;

    strcpy (fixed, in);
    vfsFixDOSName (fixed);
    g_strdown (fixed);

    for (lst = g_pakFiles; lst != NULL; lst = g_slist_next (lst))
    {
      VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;

      char *ptr,*lastptr;
      lastptr = file->name;

      while ((ptr = strchr(lastptr,'/')) != NULL)
        lastptr = ptr+1;

      if (strcmp (lastptr, fixed) == 0)
      {
        strncpy(out,file->name,PATH_MAX);
        return out;
      }
    }

  }

  if (!flag || (flag & VFS_SEARCH_DIR))
  {
  for (i = 0; i < g_numDirs; i++)
  {
    strcpy (tmp, g_strDirs[i]);
    strcat (tmp, in);
    if (access (tmp, R_OK) == 0)
    {
      if (count == index)
      {
        strcpy (out, tmp);
        return out;
      }
      count++;
    }
  }
  }
  return NULL;
}
Beispiel #8
0
static void vfsInitPakFile (const char *filename)
{
  pakheader_t header;
  FILE *f;
  long i;

  f = fopen (filename, "rb");
  if (f == NULL)
    return;

  // read header
  fread (header.magic, 1, 4, f);
  fread (&header.diroffset, 1, 4, f);
  fread (&header.dirsize, 1, 4, f);

  // fix endianess
  header.diroffset = GINT32_FROM_LE (header.diroffset);
  header.dirsize = GINT32_FROM_LE (header.dirsize);

  // check that the magic header
  if (strncmp (header.magic, "PACK", 4))
  {
    fclose (f);
    return;
  }

  g_FuncTable.m_pfnSysPrintf("  pak file: %s\n", filename);

  g_unzFiles = g_slist_append (g_unzFiles, f);
  fseek (f, header.diroffset, SEEK_SET);

  for (i = 0; i < (long)(header.dirsize/sizeof (pakentry_t)); i++)
  {
    VFS_PAKFILE* file;

    file = (VFS_PAKFILE*)g_malloc (sizeof (VFS_PAKFILE));
    g_pakFiles = g_slist_append (g_pakFiles, file);

    fread (file->entry.filename, 1, sizeof (file->entry.filename), f);
    fread (&file->entry.offset, 1, sizeof (file->entry.offset), f);
    fread (&file->entry.size, 1, sizeof (file->entry.size), f);
    file->pak = f;

    // fix endianess
    file->entry.offset = GINT32_FROM_LE (file->entry.offset);
    file->entry.size = GINT32_FROM_LE (file->entry.size);

    // fix filename
    vfsFixDOSName (file->entry.filename);
    g_strdown (file->entry.filename);
    //g_FuncTable.m_pfnSysPrintf("vfs file from pak: %s\n", file->entry.filename);
  }
}
Beispiel #9
0
static void vfsInitPakFile( const char *filename ){
	unz_global_info gi;
	unzFile uf;
	guint32 i;
	int err;

	uf = unzOpen( filename );
	if ( uf == NULL ) {
		g_FuncTable.m_pfnSysFPrintf( SYS_WRN, "  failed to init pak file %s\n", filename );
		return;
	}
	g_FuncTable.m_pfnSysPrintf( "  pak file: %s\n", filename );

	g_unzFiles = g_slist_append( g_unzFiles, uf );

	err = unzGetGlobalInfo( uf,&gi );
	if ( err != UNZ_OK ) {
		return;
	}
	unzGoToFirstFile( uf );

	for ( i = 0; i < gi.number_entry; i++ )
	{
		char filename_inzip[NAME_MAX];
		unz_file_info file_info;
		VFS_PAKFILE* file;

		err = unzGetCurrentFileInfo( uf, &file_info, filename_inzip, sizeof( filename_inzip ), NULL, 0, NULL, 0 );
		if ( err != UNZ_OK ) {
			break;
		}

		file = (VFS_PAKFILE*)g_malloc( sizeof( VFS_PAKFILE ) );
		g_pakFiles = g_slist_append( g_pakFiles, file );

		vfsFixDOSName( filename_inzip );
		strlwr( filename_inzip );

		file->name = g_strdup( filename_inzip );
		file->size = file_info.uncompressed_size;
		file->zipfile = uf;
		memcpy( &file->zipinfo, uf, sizeof( unz_s ) );

		if ( ( i + 1 ) < gi.number_entry ) {
			err = unzGoToNextFile( uf );
			if ( err != UNZ_OK ) {
				break;
			}
		}
	}
}
Beispiel #10
0
static void vfsInitPakFile(const char *filename)
{
	unz_global_info gi;
	unzFile         uf;
	guint32         i;
	int             err;

	uf = unzOpen(filename);
	if(uf == NULL)
		return;

	g_unzFiles = g_slist_append(g_unzFiles, uf);

	err = unzGetGlobalInfo(uf, &gi);
	if(err != UNZ_OK)
		return;
	unzGoToFirstFile(uf);

	Sys_Printf("VFS Init: %s (pk3)\n", filename);

	for(i = 0; i < gi.number_entry; i++)
	{
		char            filename_inzip[NAME_MAX];
		unz_file_info   file_info;
		VFS_PAKFILE    *file;

		err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
		if(err != UNZ_OK)
			break;

		file = (VFS_PAKFILE *) safe_malloc(sizeof(VFS_PAKFILE));
		g_pakFiles = g_slist_append(g_pakFiles, file);

		vfsFixDOSName(filename_inzip);
		g_strdown(filename_inzip);

		file->name = strdup(filename_inzip);
		file->size = file_info.uncompressed_size;
		file->zipfile = uf;
		memcpy(&file->zipinfo, uf, sizeof(unz_s));

		if((i + 1) < gi.number_entry)
		{
			err = unzGoToNextFile(uf);
			if(err != UNZ_OK)
				break;
		}
	}
}
Beispiel #11
0
// reads all pak files from a dir
void vfsInitDirectory( const char *path ){
	char filename[PATH_MAX];

	if ( g_numDirs == ( VFS_MAXDIRS - 1 ) ) {
		return;
	}

	strcpy( g_strDirs[g_numDirs], path );
	vfsFixDOSName( g_strDirs[g_numDirs] );
	vfsAddSlash( g_strDirs[g_numDirs] );
	g_numDirs++;

//  if (g_PrefsDlg.m_bPAK)
	// TODO: can't read prefs from a module, bah..
	if ( 1 ) {
		GDir* dir = g_dir_open( path, 0, NULL );
		if ( dir != NULL ) {
			g_FuncTable.m_pfnSysPrintf( "vfs directory: %s\n", path );
			while ( 1 )
			{
				const char* name = g_dir_read_name( dir );
				if ( name == NULL ) {
					break;
				}

				const char *ext = strrchr( name, '.' );
				if ( ( ext == NULL ) || ( strcmp( ext, ".wad" ) != 0 ) ) {
					continue;
				}

				sprintf( filename, "%s/%s", path, name );
				vfsInitPakFile( filename );
			}
			g_dir_close( dir );
		}
		else{
			g_FuncTable.m_pfnSysFPrintf( SYS_WRN, "vfs directory not found: %s\n", path );
		}
	}
}
Beispiel #12
0
// 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)
{
  int i, count = 0;
  char tmp[NAME_MAX], fixed[NAME_MAX];
  GSList *lst;
  
  // filename is a full path
  if (index == -1)
  {
    long len;
    FILE *f;
    
    f = fopen (filename, "rb");
    if (f == NULL)
      return -1;
    
    fseek (f, 0, SEEK_END);
    len = ftell (f);
    rewind (f);
    
    *bufferptr = safe_malloc (len+1);
    if (*bufferptr == NULL)
      return -1;
    
    fread (*bufferptr, 1, len, f);
    fclose (f);
    
    // we need to end the buffer with a 0
    ((char*) (*bufferptr))[len] = 0;
    
    return len;
  }
  
  *bufferptr = NULL;
  strcpy (fixed, filename);
  vfsFixDOSName (fixed);
  g_strdown (fixed);
  
  for (i = 0; i < g_numDirs; i++)
  {
    strcpy (tmp, g_strDirs[i]);
    strcat (tmp, filename);
    if (access (tmp, R_OK) == 0)
    {
      if (count == index)
      {
        long len;
        FILE *f;
        
        f = fopen (tmp, "rb");
        if (f == NULL)
          return -1;
        
        fseek (f, 0, SEEK_END);
        len = ftell (f);
        rewind (f);
        
        *bufferptr = safe_malloc (len+1);
        if (*bufferptr == NULL)
          return -1;
        
        fread (*bufferptr, 1, len, f);
        fclose (f);
        
        // we need to end the buffer with a 0
        ((char*) (*bufferptr))[len] = 0;
        
        return len;
      }
      
      count++;
    }
  }
  
  for (lst = g_pakFiles; lst != NULL; lst = g_slist_next (lst))
  {
    VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;
    
    if (strcmp (file->name, fixed) != 0)
      continue;
    
    if (count == index)
    {
      memcpy (file->zipfile, &file->zipinfo, sizeof (unz_s));
      
      if (unzOpenCurrentFile (file->zipfile) != UNZ_OK)
        return -1;
      
      *bufferptr = safe_malloc (file->size+1);
      // we need to end the buffer with a 0
      ((char*) (*bufferptr))[file->size] = 0;
      
      i = unzReadCurrentFile (file->zipfile , *bufferptr, file->size);
      unzCloseCurrentFile (file->zipfile);
      if (i < 0)
        return -1;
      else
        return file->size;
    }
    
    count++;
  }
  
  return -1;
}
Beispiel #13
0
// 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)
{
  int i, count = 0;
  char tmp[NAME_MAX], fixed[NAME_MAX];
  GSList *lst;

  *bufferptr = NULL;
  strcpy (fixed, filename);
  vfsFixDOSName (fixed);
  g_strdown (fixed);

  for (i = 0; i < g_numDirs; i++)
  {
    strcpy (tmp, g_strDirs[i]);
    strcat (tmp, filename);
    if (access (tmp, R_OK) == 0)
    {
      if (count == index)
      {
	long len;
	FILE *f;

	f = fopen (tmp, "rb");
	if (f == NULL)
	  return -1;

	fseek (f, 0, SEEK_END);
	len = ftell (f);
	rewind (f);

	*bufferptr = malloc (len+1);
	if (*bufferptr == NULL)
	  return -1;

	fread (*bufferptr, 1, len, f);
	fclose (f);

        // we need to end the buffer with a 0
        ((char*) (*bufferptr))[len] = 0;

	return len;
      }

      count++;
    }
  }

  for (lst = g_pakFiles; lst != NULL; lst = g_slist_next (lst))
  {
    VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;

    if (strcmp (file->entry.filename, fixed) != 0)
      continue;

    if (count == index)
    {
      fseek (file->pak, file->entry.offset, SEEK_SET);

      *bufferptr = malloc (file->entry.size+1);
      // we need to end the buffer with a 0
      ((char*) (*bufferptr))[file->entry.size] = 0;

      return fread (*bufferptr, 1, file->entry.size, file->pak);
    }

    count++;
  }

  return -1;
}
Beispiel #14
0
static void vfsInitPakFile( const char *filename ){
	wadFile_t *wf;
	unsigned int i;
	int err;
	char wadname[NAME_MAX];
	char *ext;

	if ( !filename || strlen( filename ) <= 0 ) {
		g_FuncTable.m_pfnSysFPrintf( SYS_WRN, "  missing wad filename\n" );
		return;
	}
	wf = wadOpen( filename );
	if ( wf == NULL ) {
		g_FuncTable.m_pfnSysFPrintf( SYS_WRN, "  failed to init wad file %s\n", filename );
		return;
	}
	g_FuncTable.m_pfnSysPrintf( "  wad file: %s\n", filename );

	ExtractFileName( filename, wadname );
	strlwr( wadname );

	ext = strrchr( wadname, '.' );
	if ( ext && strcmp( ext, ".wad" ) == 0 ) {
		*ext = 0; // ditch the .wad so everthing looks nice!
	}

	g_wadFiles = g_slist_append( g_wadFiles, wf ); // store the wadfile handle

	wadGoToFirstFile( wf );

	for ( i = 0; i < wf->lpHeader->numlumps; i++ )
	{
		char filename_inwad[NAME_MAX];
		char filename_inwadfixed[NAME_MAX];
		unsigned long filesize;
		VFS_PAKFILE* file;

		err = wadGetCurrentFileInfo( wf, filename_inwad, sizeof( filename_inwad ) - 5, &filesize ); // -5 for extension + null terminator
		if ( err != 1 ) {
			break;
		}

		file = (VFS_PAKFILE*)g_malloc( sizeof( VFS_PAKFILE ) );
		g_pakFiles = g_slist_append( g_pakFiles, file );

		vfsFixDOSName( filename_inwad );
		strlwr( filename_inwad );

		// texturenames in wad files don't have an extensions or paths, so we must add them!
		if ( wf->lpLump->type == WAD2_TYPE_MIP ) {
			sprintf( filename_inwadfixed,"textures/%s/%s.mip",wadname,filename_inwad );
		}
		else {
			sprintf( filename_inwadfixed,"textures/%s/%s.hlw",wadname,filename_inwad );
		}

		//g_FuncTable.m_pfnSysFPrintf(SYS_WRN, "  scanned %s\\%s\n", filename,filename_inwad);

		file->name = g_strdup( filename_inwadfixed );
		file->size = filesize;
		file->filenumber = wf->currentfile;
		file->wadfile = wf;
		memcpy( &file->wadlump, wf->lpLump, sizeof( WAD3_LUMP ) );

		err = wadGoToNextFile( wf );
		if ( err != 1 ) {
			break;
		}
	}
}
Beispiel #15
0
/*!
   The gamemode hacks in here will do undefined things with files called zz_*.
   This is simple to fix by cleaning up the hacks, but may be better left alone
   if the engine code does the same thing.
 */
void vfsInitDirectory( const char *path ){
	char filename[PATH_MAX];
	GDir *dir;
	GSList *dirlist = NULL;
	int iGameMode; // 0: no filtering 1: SP 2: MP

	if ( g_numDirs == ( VFS_MAXDIRS - 1 ) ) {
		return;
	}

	// See if we are in "sp" or "mp" mapping mode
	const char* gamemode = g_FuncTable.m_pfnReadProjectKey( "gamemode" );

	if ( gamemode ) {
		if ( strcmp( gamemode, "sp" ) == 0 ) {
			iGameMode = 1;
		}
		else if ( strcmp( gamemode, "mp" ) == 0 ) {
			iGameMode = 2;
		}
		else{
			iGameMode = 0;
		}
	}
	else{
		iGameMode = 0;
	}

	strcpy( g_strDirs[g_numDirs], path );
	vfsFixDOSName( g_strDirs[g_numDirs] );
	vfsAddSlash( g_strDirs[g_numDirs] );
	g_numDirs++;

	if ( g_bUsePak ) {
		dir = g_dir_open( path, 0, NULL );

		if ( dir != NULL ) {
			g_FuncTable.m_pfnSysPrintf( "vfs directory: %s\n", path );

			for (;; )
			{
				const char* name = g_dir_read_name( dir );
				if ( name == NULL ) {
					break;
				}

				char *ext = (char*)strrchr( name, '.' );
				if ( ( ext == NULL ) || ( strcasecmp( ext, ".pk3" ) != 0 ) ) {
					continue;
				}

				char* direntry = g_strdup( name );

				// using the same kludge as in engine to ensure consistency
				switch ( iGameMode )
				{
				case 1: // SP
					if ( strncmp( direntry,"sp_",3 ) == 0 ) {
						memcpy( direntry,"zz",2 );
					}
					break;
				case 2: // MP
					if ( strncmp( direntry,"mp_",3 ) == 0 ) {
						memcpy( direntry,"zz",2 );
					}
					break;
				}

				dirlist = g_slist_append( dirlist, direntry );
			}

			g_dir_close( dir );

			// sort them
			dirlist = g_slist_sort( dirlist, vfsPakSort );

			// add the entries to the vfs and free the list
			while ( dirlist )
			{
				GSList *cur = dirlist;
				char* name = (char*)cur->data;

				switch ( iGameMode )
				{
				case 1: // SP
					if ( strncmp( name,"mp_",3 ) == 0 ) {
						g_free( name );
						dirlist = g_slist_remove( cur, name );
						continue;
					}
					else if ( strncmp( name,"zz_",3 ) == 0 ) {
						memcpy( name,"sp",2 );
					}
					break;
				case 2: // MP
					if ( strncmp( name,"sp_",3 ) == 0 ) {
						g_free( name );
						dirlist = g_slist_remove( cur, name );
						continue;
					}
					else if ( strncmp( name,"zz_",3 ) == 0 ) {
						memcpy( name,"mp",2 );
					}
					break;
				}

				sprintf( filename, "%s/%s", path, name );
				vfsInitPakFile( filename );

				g_free( name );
				dirlist = g_slist_remove( cur, name );
			}
		}
		else{
			g_FuncTable.m_pfnSysFPrintf( SYS_WRN, "vfs directory not found: %s\n", path );
		}
	}
}
Beispiel #16
0
static GSList* vfsGetListInternal( const char *refdir, const char *ext, bool directories ){
	GSList *lst, *lst_aux, *files = NULL;
	char dirname[NAME_MAX], extension[NAME_MAX], filename[NAME_MAX];
	char basedir[NAME_MAX];
	int dirlen;
	char *ptr;
	char *dirlist;
	struct stat st;
	GDir *diskdir;
	int i;

	if ( refdir != NULL ) {
		strcpy( dirname, refdir );
		strlwr( dirname );
		vfsFixDOSName( dirname );
		vfsAddSlash( dirname );
	}
	else{
		dirname[0] = '\0';
	}
	dirlen = strlen( dirname );

	if ( ext != NULL ) {
		strcpy( extension, ext );
	}
	else{
		extension[0] = '\0';
	}
	strlwr( extension );

	for ( lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) )
	{
		VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;
		gboolean found = FALSE;
		ptr = file->name;

		// check that the file name begins with dirname
		for ( i = 0; ( *ptr && i < dirlen ); i++, ptr++ )
			if ( *ptr != dirname[i] ) {
				break;
			}

		if ( i != dirlen ) {
			continue;
		}

		if ( directories ) {
			char *sep = strchr( ptr, '/' );
			if ( sep == NULL ) {
				continue;
			}

			i = sep - ptr;

			// check for duplicates
			for ( lst_aux = files; lst_aux; lst_aux = g_slist_next( lst_aux ) )
				if ( strncmp( (char*)lst_aux->data, ptr, i ) == 0 ) {
					found = TRUE;
					break;
				}

			if ( !found ) {
				char *name = g_strndup( ptr, i + 1 );
				name[i] = '\0';
				files = g_slist_append( files, name );
			}
		}
		else
		{
			// check extension
			char *ptr_ext = strrchr( ptr, '.' );
			if ( ( ext != NULL ) && ( ( ptr_ext == NULL ) || ( strcmp( ptr_ext + 1, extension ) != 0 ) ) ) {
				continue;
			}

			// check for duplicates
			for ( lst_aux = files; lst_aux; lst_aux = g_slist_next( lst_aux ) )
				if ( strcmp( (char*)lst_aux->data, ptr ) == 0 ) {
					found = TRUE;
					break;
				}

			if ( !found ) {
				files = g_slist_append( files, g_strdup( ptr ) );
			}
		}
	}

	for ( i = 0; i < g_numDirs; i++ )
	{
		strcpy( basedir, g_strDirs[i] );
		strcat( basedir, dirname );

		diskdir = g_dir_open( basedir, 0, NULL );

		if ( diskdir != NULL ) {
			while ( 1 )
			{
				const char* name = g_dir_read_name( diskdir );
				if ( name == NULL ) {
					break;
				}

				if ( directories && ( name[0] == '.' ) ) {
					continue;
				}

				sprintf( filename, "%s%s", basedir, name );
				stat( filename, &st );

				if ( ( S_ISDIR( st.st_mode ) != 0 ) != directories ) {
					continue;
				}

				gboolean found = FALSE;

				dirlist = g_strdup( name );

				strlwr( dirlist );

				char *ptr_ext = strrchr( dirlist, '.' );
				if ( ext == NULL
					 || ( ext != NULL && ptr_ext != NULL && ptr_ext[0] != '\0' && strcmp( ptr_ext + 1, extension ) == 0 ) ) {

					// check for duplicates
					for ( lst_aux = files; lst_aux; lst_aux = g_slist_next( lst_aux ) )
						if ( strcmp( (char*)lst_aux->data, dirlist ) == 0 ) {
							found = TRUE;
							break;
						}

					if ( !found ) {
						files = g_slist_append( files, g_strdup( dirlist ) );
					}
				}

				g_free( dirlist );
			}
			g_dir_close( diskdir );
		}
	}

	return files;
}
Beispiel #17
0
// 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 ){
	int i, count = 0;
	char tmp[NAME_MAX], fixed[NAME_MAX];
	GSList *lst;

	*bufferptr = NULL;
	strcpy( fixed, filename );
	vfsFixDOSName( fixed );
	strlwr( fixed );

	for ( i = 0; i < g_numDirs; i++ )
	{
		strcpy( tmp, g_strDirs[i] );
		strcat( tmp, filename );
		if ( access( tmp, R_OK ) == 0 ) {
			if ( count == index ) {
				return vfsLoadFullPathFile( tmp,bufferptr );
				/*
				   long len;
				   FILE *f;

				   f = fopen (tmp, "rb");
				   if (f == NULL)
				   return -1;

				   fseek (f, 0, SEEK_END);
				   len = ftell (f);
				   rewind (f);

				   *bufferptr = g_malloc (len+1);
				   if (*bufferptr == NULL)
				   return -1;

				   fread (*bufferptr, 1, len, f);
				   fclose (f);

				   // we need to end the buffer with a 0
				   ((char*) (*bufferptr))[len] = 0;

				   return len;
				 */
			}

			count++;
		}
	}


	// Textures in HalfLife wads don't have paths, but in the list of files
	// we store the actual full paths of the files and what WAD they're in.
	// so what we have to do is strip the paths and just compare filenames.

	// Hydra: well, we did do this, but now we don't, as the map loader now
	// fills in the correct paths for each texture.

	/*
	   char *searchname;
	   char *fixedptr;

	   fixedptr = fixed;

	   for (i = strlen(fixed)-1 ; i >= 0 && fixed[i] != '\\' && fixed[i] != '/' ; i --)
	   fixedptr = (char *)fixed + i;
	 */
	for ( lst = g_pakFiles; lst != NULL; lst = g_slist_next( lst ) )
	{
		VFS_PAKFILE* file = (VFS_PAKFILE*)lst->data;


		/*
		   searchname = file->name;
		   for (i = strlen(file->name)-1 ; i >= 0 && file->name[i] != '\\' && file->name[i] != '/' ; i --)
		   searchname = (char *)file->name + i;
		   if (strcmp (searchname, fixedptr) != 0)
		   continue;
		 */

		if ( strcmp( file->name, fixed ) != 0 ) {
			continue;
		}

		if ( count == index ) {
			// Useful for debugging
			//Sys_Printf("VFSWAD: reading from %s\n",file->wadfile->wadfilename);

			if ( wadOpenCurrentFileByNum( file->wadfile, file->filenumber ) != 1 ) {
				return -1;
			}

			*bufferptr = g_malloc( file->size + 1 );
			// we need to end the buffer with a 0
			( (char*) ( *bufferptr ) )[file->size] = 0;

			i = wadReadCurrentFile( file->wadfile, (char *)*bufferptr, file->size );
			wadCloseCurrentFile( file->wadfile );
			if ( i > 0 ) {
				return file->size;
			}
			else{
				return -1;
			}
		}

		count++;
	}

	return -1;
}