This is a patch file for "gnumch" 0.2.0. These changes replace the original "gnumch" filesystem code with a simplified version. Explanation: The original "gnumch" filesystem code wasn't compatible with Linux- Live-based distros that used "squashfs-lzma" and/or "aufs". The new filesystem code corrects the problem. Additionally, two minor filename/pathname changes have been made: a. The high-scores file has been renamed to "scores.dat". b. "gnumch.cfg" and "scores.dat" are always stored in the direc- tory $HOME/.gnumch [which is created, if necessary]. The new code never tries to put these two files in the "install" tree. The new code should be compatible with most Linux distros that support the original program. --- gnumch-0.2.0.old/src/game/FileSys.h +++ gnumch-0.2.0/src/game/FileSys.h @@ -30,10 +30,6 @@ Directory(Directory*, const char*); ~Directory(); - void rewind(); - string read(); - string read(string*); - string readShort(); const char *name(); protected: @@ -62,7 +58,6 @@ Mix_Chunk *openSound(const char *name); Mix_Chunk *openAnimSound(const char *name); FILE *openCfg(const char*, bool write=0); - void getCfg(string&, const string&) throw (int); ConfigFile *openConfig(const char *, bool write=0); void readScores(vector&, vector&); @@ -81,9 +76,6 @@ Directory *sound; SDL_Surface *openAnimPic(const string&, int width, int height); - vector *scanDir(Directory*, string); - void getFile(Directory*, string&, const string&) throw (int); - static SDL_mutex *fs_mutex; }; --- gnumch-0.2.0.old/src/game/FileSys.cpp +++ gnumch-0.2.0/src/game/FileSys.cpp @@ -19,24 +19,35 @@ #include #include -extern Game *game; +// Some notes on this version: The original "gnumch" filesystem code +// wasn't compatible with LinuxLive-based distros that used "squashfs- +// lzma" and/or "aufs". This version of "gnumch" uses simplified file- +// system code that corrects the problem. The new code has only been +// tested under Linux, but it should be compatible with BSD and other +// UNIX systems. +extern Game *game; +Directory *userPkgDir; SDL_mutex *FileSys::fs_mutex; FileSys::FileSys() { - char *home = getenv("HOME"); - - char main[strlen(DATADIR) + strlen(PACKAGE) + 3]; - sprintf(main, "%s/%s/", DATADIR, PACKAGE); - - if(home) { - char backup[strlen(home) + strlen(PACKAGE) + 4]; - sprintf(backup, "%s/.%s/", home, PACKAGE); - base = new Directory(backup, main); - } else { - base = new Directory(main, NULL); - } + char *home = getenv ("HOME"); + // This is a kludge + if (!home) home = "/tmp"; + char namePkgDir [strlen (home) + strlen (PACKAGE) + 4]; + sprintf (namePkgDir, "%s/.%s/", home, PACKAGE); + + char main [strlen (DATADIR) + strlen (PACKAGE) + 3]; + sprintf (main, "%s/%s/", DATADIR, PACKAGE); + + userPkgDir = new Directory (namePkgDir , NULL); + base = new Directory (main , NULL); + + string cmdtmp1 = "/bin/mkdir -p "; + string cmdtmp2 = userPkgDir->name(); + string cmdtmpx = cmdtmp1 + cmdtmp2; + system (cmdtmpx.c_str()); /* set up the directory structure */ anim = new Directory(base, "animation" ); @@ -59,15 +70,17 @@ delete pic; } +void nameKludge (Directory *dir, string &full, const string &name) +{ + full = dir->name() + name; +} + TTF_Font *FileSys::openFont(const char *name, int size) { TTF_Font *ret; string filename; - SDL_mutexP(fs_mutex); - getFile(font, filename, name); - SDL_mutexV(fs_mutex); - + nameKludge (font, filename, name); ret = TTF_OpenFont(filename.c_str(), size); if(!ret) { printError("Couldn't open font: %s\n", TTF_GetError()); @@ -80,11 +93,8 @@ if(!name) return NULL; string filename; - SDL_mutexP(fs_mutex); - getFile(pic, filename, name); + nameKludge (pic, filename, name); SDL_Surface *ret = openAnimPic(filename, w, h); - SDL_mutexV(fs_mutex); - return ret; } @@ -93,11 +103,8 @@ if (!name) return NULL; string filename; - SDL_mutexP(fs_mutex); - getFile(anim_pic, filename, name); + nameKludge (anim_pic, filename, name); SDL_Surface *ret = openAnimPic(filename, w, h); - SDL_mutexV(fs_mutex); - return ret; } @@ -106,11 +113,8 @@ if (!name) return NULL; string filename; - SDL_mutexP(fs_mutex); - getFile(anim_sound, filename, name); + nameKludge (anim_sound, filename, name); Mix_Chunk *ret = Mix_LoadWAV(filename.c_str()); - SDL_mutexV(fs_mutex); - return ret; } @@ -119,13 +123,9 @@ if (!name) return NULL; string filename; - SDL_mutexP(fs_mutex); - getFile(sound, filename, name); - Mix_Chunk *ret = Mix_LoadWAV(filename.c_str()); - SDL_mutexV(fs_mutex); - + nameKludge (sound, filename, name); + Mix_Chunk *ret = Mix_LoadWAV (filename.c_str()); if (!ret) printWarning("couldn't open sound %s: %s\n", name, Mix_GetError()); - return ret; } @@ -153,16 +153,15 @@ printWarning("unrecognised directory passed to FileSys\n"); throw ENOENT; } - getFile(d, *full, name); + + nameKludge (d, *full, name); } FILE *FileSys::openCfg(const char *name, bool write) { string filename; - SDL_mutexP(fs_mutex); - getFile(base, filename, name); - SDL_mutexV(fs_mutex); + nameKludge (base, filename, name); FILE *ret = fopen(filename.c_str(), "r"); if(!ret) printError("couldn't open file %s\n", name); @@ -172,31 +171,56 @@ ConfigFile *FileSys::openConfig(const char *name, bool write) { string fullname; + FILE *ifp; + int is_there = 0; - SDL_mutexP(fs_mutex); - try { - getFile(base, fullname, name); - } catch (int e) { - if (e == ENOENT) { - printWarning("config file %s doesn't exist, creating it\n", name); - write = true; - } else { - printError("couldn't open config file %s: %s\n", name, strerror(e)); - } + if (!strcmp (name, "gnumch.cfg")) + { + string nametmp1 = userPkgDir->name(); + string nametmp2 = name; + fullname = nametmp1 + nametmp2; + } + else + { + nameKludge (base, fullname, name); + } + + if ((ifp = fopen (fullname.c_str(), "r")) != NULL) + { + fclose (ifp); + is_there = 1; + } + + if (!is_there) + { + printWarning ("config file %s doesn't exist, creating it\n", name); + write = true; } - SDL_mutexV(fs_mutex); + return new ConfigFile(fullname, write); } void FileSys::readScores(vector &names, vector &scores) { - string filename; + FILE *ifp; + int is_there = 0; + + string nametmp1 = userPkgDir->name(); + string nametmp2 = "scores.dat"; + string filename = nametmp1 + nametmp2; + + if ((ifp = fopen (filename.c_str(), "r")) != NULL) + { + fclose (ifp); + is_there = 1; + } + names.clear(); scores.clear(); - SDL_mutexP(fs_mutex); - try { - getFile(base, filename, "scores.txt"); - ifstream fin(filename.c_str()); + + if (is_there) + { + ifstream fin (filename.c_str()); string tmp_s; int tmp_i; @@ -205,10 +229,11 @@ fin >> tmp_i; scores.push_back(tmp_i); } - } catch(int i) { - printWarning("high scores file doesn't exist\n"); } - SDL_mutexV(fs_mutex); + else + { + printWarning ("high scores file doesn't exist yet\n"); + } } bool FileSys::checkScore(int score) @@ -238,20 +263,11 @@ scores.pop_back(); } - string filename; - ofstream fout; + string nametmp1 = userPkgDir->name(); + string nametmp2 = "scores.dat"; + string filename = nametmp1 + nametmp2; - SDL_mutexP(fs_mutex); - try { - getCfg(filename, "scores.txt"); - } catch(int i) { - if(i == ENOENT) { - cout << "creating config file\n"; - } else { - printError("unexpected exception %d\n", i); - } - } - SDL_mutexV(fs_mutex); + ofstream fout; fout.open(filename.c_str(), ios::trunc); for(i=scores.begin(), s=names.begin(); i *FileSys::scanDir(Directory *dir, string pattern) -{ - vector *ret = new vector(); - string file; - - dir->rewind(); - - while( !(file = dir->read()).empty() ) { - if(pattern.empty() || file.find(pattern, 0) != string::npos) { - ret->push_back(file); - } - } - return ret; -} - -void FileSys::getFile(Directory *dir, string &full, const string &name) - throw (int) -{ - string ret, dirname; - dir->rewind(); - while( !(ret = dir->read(&dirname)).empty() ) { - if(ret == name) { - full = dirname + ret; - return; - } - } - full = dir->name() + name; - printWarning("file not found: %s\n", full.c_str()); - throw (int)ENOENT; -} - /*________________________________Directory___________________________________*/ Directory::Directory(const char *one, const char *two) @@ -388,57 +370,6 @@ closedir(backup); } -void Directory::rewind() -{ - rewinddir(main); - if(backup) rewinddir(backup); -} - -string Directory::read() -{ - struct dirent *ent; - - ent = readdir(main); - if(ent) return (string)mainname + ent->d_name; - - if(backup) { - ent = readdir(backup); - if(ent) return (string)backupname + ent->d_name; - } - - return ""; -} - -string Directory::read(string *dirname) -{ - struct dirent *ent; - - ent = readdir(main); - if(ent) *dirname = mainname; - - if(!ent && backup) { - ent = readdir(backup); - if(ent) *dirname = backupname; - } - - if(ent) return ent->d_name; - return ""; -} - -string Directory::readShort() -{ - struct dirent *ent; - - ent = readdir(main); - - if(!ent && backup) { - ent = readdir(backup); - } - - if(ent) return ent->d_name; - return ""; -} - const char *Directory::name() { return mainname;