Jump to content
  • Advertisement
Sign in to follow this  
Bayle Skyfire

File Management with SDL

This topic is 4787 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm relatively new with programming anything serious, so beare with me. I'm coding an engine that will basically be a skeleton for 2D games, mainly Zelda, Castlevania, and Metroid-esque games. I need to be able to access a listing of the files in the directory, and was hoping someone (anyone) could point me in the right direction. I haven't gotten much coded yet, as this was a priority I wanted to get under my belt before getting too far into the development. Any help is greatly appreciated. BTW, in case anyone wonders or is curious, I'm developing in Windows with the intention of keeping it as OS independant as possible in order to easily port over to Linux at a later date.

Share this post


Link to post
Share on other sites
Advertisement
Look for functions findfirst and findnext. I'm not sure but I think they are OS-dependant though.

Edit: Not SDL functions, but AFAIK SDL doesn't have ways to get directory listing.

Share this post


Link to post
Share on other sites
findfirst and findnext are DOS-specific functions also implemented in the win32 C library.

On other OSs, you typically need to use opendir and readdir, which are similar but different. These functions are not implemented in the normal win32 C library.

Mark

Share this post


Link to post
Share on other sites
SDL has nothing to do with directory and file-reading at all. Well, at least beyond things like LoadBMP(). You'll have to look for some other way of doing it.

Share this post


Link to post
Share on other sites
Listing of the files? Look at this handy class I've written:

Header:


#ifndef TFILESEEKER_H
#define TFILESEEKER_H

// -------------------------------------------------

#include <io.h>

#include <algorithm>
#include <fstream>
#include <vector>

#include "../../Others/Misc/basicTypes.h"

// -------------------------------------------------

namespace SC
{

//! How to sort files found in TFileSeeker.
enum SortBy
{
sb_Name, //!< Sort by name.
sb_Size, //!< Sort by size.
sb_Date, //!< Sort by date.
sb_Type //!< Sort by type.
};


//! Class that wraps up process of searching for files using mask in one (currently active!) directory.
//! You can use "*" and "?" wildcards.
class TFileSeeker
{
private:

typedef std :: vector<_finddata_t> FileVector;

public:

typedef FileVector :: iterator FileVectorItor;
typedef FileVector :: const_iterator FileVectorConstItor;

//! Searches in currently active directory for files that match _mask filepath
//! If _directory != 0, it will automatically change current one to passed, and on the end - return
//! to old one.
//! \return Number of found files, or -1 if error occured.
slint Search(const char * _mask, const char * _directory = 0);

// -------------------------------------------------

//! Returns the iterator which points to the first element.
FileVectorConstItor GetFirst() const { return foundFiles.begin(); }

//! Returns the iterator which points to the place after last element;
//! to speed up "parsing" it should be obtained only once.
FileVectorConstItor GetLast() const { return foundFiles.end(); }

// -------------------------------------------------

//! Sorts all found files with appropriate sorting type mechanism.
void Sort(SortBy _sortingType = sb_Name);

//! Clears results of last search.
void Clear() { foundFiles.clear(); }

//! Returns the number of found files.
ulint Count() const { return foundFiles.size(); }

private:

FileVector foundFiles;

};

}

// -------------------------------------------------

namespace std
{
template <>
struct less< SC :: TFileSeeker :: FileVectorItor >
{
bool operator()( const _finddata_t & _first, const _finddata_t & _second )
{
return stricmp(_first.name, _second.name ) < 0;
}
};

}

/*
struct _finddata_t
{
unsigned attrib; // Attributes

#define _A_NORMAL 0x00000000
#define _A_RDONLY 0x00000001
#define _A_HIDDEN 0x00000002
#define _A_SYSTEM 0x00000004
#define _A_VOLID 0x00000008
#define _A_SUBDIR 0x00000010
#define _A_ARCH 0x00000020

time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[FILENAME_MAX]; // may include spaces.
};
*/


// -------------------------------------------------


#endif




Implementation:



#include "tFileSeeker.h"

#include "genericFileIO.h"

// ------------------------------------------------- start Search

SC :: slint SC :: TFileSeeker :: Search(const char * _mask, const char * _directory)
{

char actualDir[260];

if (_directory)
{
dirGetActual(actualDir);

if (dirChangeActual(_directory) != eOK)
return (-1); // report error
}

// -------------------------------------------------

_finddata_t file;
long searchHandler = _findfirst( _mask, &file );

if (searchHandler == -1) return 0; // no files found
else
{

do
{
foundFiles.push_back(file);
}
while (_findnext( searchHandler, &file ) == 0);

_findclose(searchHandler);

// -------------------------------------------------

if (_directory)
{

if (dirChangeActual(actualDir) != eOK)
return (-1);
}

return foundFiles.size();

}
}

// ------------------------------------------------- end Search

// ------------------------------------------------- start Sort

void SC :: TFileSeeker :: Sort(SortBy _sortingType)
{
if (foundFiles.empty()) return;

// unfortunately currently implemented there's only sorting by name
// but getting other types of sorting is trivial - add new
// template <> struct less< SC :: TFileSeeker :: FileVectorItor > classess
if (_sortingType == sb_Name)
sort(foundFiles.begin(), foundFiles.end(), std :: less<FileVectorItor>());

}

// ------------------------------------------------- end Sort




Some global functions that are used by that class:



// ------------------------------------------------- start dirChangeActual

SC :: eError SC :: dirChangeActual(const char * _new)
{
int ok = _chdir(_new);

if (ok == 0) return eOK;
else return eInvalidArg;

}

// ------------------------------------------------- end dirChangeActual

// ------------------------------------------------- start dirGetActual

void SC :: dirGetActual(char _array[260])
{
_getcwd( _array, 260);
}

// ------------------------------------------------- end dirGetActual




Usage:



TFileSeeker levels;

if ( levels.Search("*.xml", "Levels/") <= 0)
{
logError("Couldn't find any levels.");
return false;
}

levels.Sort();


// -------------------------------------------------

for (TFileSeeker :: FileVectorConstItor itor = levels.GetFirst(); itor != levels.GetLast(); ++itor)
{
std :: string levelName = ((*itor).name);

// in levelName you have name of one the *.xml files that were found in Levels/ directory
// do with it what you want

}



Share this post


Link to post
Share on other sites
Totally go with Boost::Filesystem. I've used it before and it works everywhere. Plus, it's use of operator/= is awesome.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!