improved open function in File class

svn-id: r4945
This commit is contained in:
Paweł Kołodziejski 2002-09-15 19:28:34 +00:00
parent 37d7a52c47
commit f7ff5c67fa
12 changed files with 106 additions and 158 deletions

View file

@ -22,38 +22,59 @@
#include "file.h" #include "file.h"
#include "engine.h" // For debug/warning/error #include "engine.h" // For debug/warning/error
FILE *fopen_nocase(const char *path, const char *mode) FILE *File::fopenNoCase(const char *filename, const char * directory, const char *mode) {
{
FILE *file; FILE *file;
char buf[256];
char *ptr;
file = fopen(path, mode); strcpy(buf, directory);
if (file) if (directory[0] != 0) {
return file; strcpy(buf, directory);
strcat(buf, "/");
char buf[256], *ptr;
int32 i = 0, pos = 0;
strcpy(buf, path);
while (buf[i] != 0) {
if ((buf[i] == '/') || (buf[i] == '\\')) {
pos = i + 1;
}
i++;
} }
strcat(buf, filename);
ptr = buf + pos;
do
*ptr++ = toupper(*ptr);
while (*ptr);
file = fopen(buf, mode); file = fopen(buf, mode);
if (file) if (file)
return file; return file;
ptr = buf + pos; char dirs[7][10];
do dirs[0][0] = 0;
*ptr++ = tolower(*ptr); strcpy(dirs[1], "video/");
while (*ptr); strcpy(dirs[2], "VIDEO/");
return fopen(buf, mode); strcpy(dirs[3], "data/");
strcpy(dirs[4], "DATA/");
strcpy(dirs[5], "resource/");
strcpy(dirs[6], "RESOURCE/");
for (uint8 l = 0; l < 7; l++) {
strcpy(buf, directory);
if (directory[0] != 0) {
strcpy(buf, directory);
strcat(buf, "/");
}
strcat(buf, dirs[l]);
int8 len = strlen(buf);
strcat(buf, filename);
ptr = buf + len;
do
*ptr++ = toupper(*ptr);
while (*ptr);
file = fopen(buf, mode);
if (file)
return file;
ptr = buf + len;
do
*ptr++ = tolower(*ptr);
while (*ptr);
file = fopen(buf, mode);
if (file)
return file;
}
return NULL;
} }
File::File() { File::File() {
@ -66,7 +87,7 @@ File::~File() {
close(); close();
} }
bool File::open(const char *filename, int mode, byte encbyte) { bool File::open(const char *filename, const char *directory, int mode, byte encbyte) {
if (_handle) { if (_handle) {
debug(2, "File %s already opened", filename); debug(2, "File %s already opened", filename);
@ -76,14 +97,14 @@ bool File::open(const char *filename, int mode, byte encbyte) {
clearIOFailed(); clearIOFailed();
if (mode == kFileReadMode) { if (mode == kFileReadMode) {
_handle = fopen_nocase(filename, "rb"); _handle = fopenNoCase(filename, directory, "rb");
if (_handle == NULL) { if (_handle == NULL) {
debug(2, "File %s not found", filename); debug(2, "File %s not found", filename);
return false; return false;
} }
} }
else if (mode == kFileWriteMode) { else if (mode == kFileWriteMode) {
_handle = fopen_nocase(filename, "wb"); _handle = fopenNoCase(filename, directory, "wb");
if (_handle == NULL) { if (_handle == NULL) {
debug(2, "File %s not opened", filename); debug(2, "File %s not opened", filename);
return false; return false;

View file

@ -26,10 +26,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "scummsys.h" #include "scummsys.h"
// fopen_nocase is like fopen only that it will try various variations
// of the given filename (with different cases) if the initial one isn't found.
FILE *fopen_nocase(const char *path, const char *mode);
class File { class File {
private: private:
@ -37,6 +33,8 @@ private:
bool _ioFailed; bool _ioFailed;
byte _encbyte; byte _encbyte;
FILE *fopenNoCase(const char *filename, const char *directory, const char *mode);
public: public:
enum { enum {
kFileReadMode = 1, kFileReadMode = 1,
@ -45,7 +43,7 @@ public:
File(); File();
~File(); ~File();
bool open(const char *filename, int mode = kFileReadMode, byte encbyte = 0); bool open(const char *filename, const char *directory, int mode = kFileReadMode, byte encbyte = 0);
void close(); void close();
bool isOpen(); bool isOpen();
bool ioFailed(); bool ioFailed();

View file

@ -31,13 +31,13 @@ Bundle::Bundle() {
Bundle::~Bundle() { Bundle::~Bundle() {
} }
bool Bundle::openVoiceFile(char *filename) { bool Bundle::openVoiceFile(const char *filename, const char *directory) {
int32 tag, offset; int32 tag, offset;
if (_voiceFile.isOpen() == true) if (_voiceFile.isOpen() == true)
return true; return true;
if (_voiceFile.open(filename) == false) { if (_voiceFile.open(filename, directory) == false) {
warning("Bundle: Can't open voice bundle file: %s", filename); warning("Bundle: Can't open voice bundle file: %s", filename);
return false; return false;
} }
@ -71,13 +71,13 @@ bool Bundle::openVoiceFile(char *filename) {
return true; return true;
} }
bool Bundle::openMusicFile(char *filename) { bool Bundle::openMusicFile(const char *filename, const char *directory) {
int32 tag, offset; int32 tag, offset;
if (_musicFile.isOpen() == true) if (_musicFile.isOpen() == true)
return true; return true;
if (_musicFile.open(filename) == false) { if (_musicFile.open(filename, directory) == false) {
warning("Bundle: Can't open music bundle file: %s", filename); warning("Bundle: Can't open music bundle file: %s", filename);
return false; return false;
} }

View file

@ -56,8 +56,8 @@ public:
Bundle(); Bundle();
~Bundle(); ~Bundle();
bool openVoiceFile(char *filename); bool openVoiceFile(const char *filename, const char *directory);
bool openMusicFile(char *filename); bool openMusicFile(const char *filename, const char *directory);
int32 decompressVoiceSampleByName(char *name, byte *comp_final); int32 decompressVoiceSampleByName(char *name, byte *comp_final);
int32 decompressVoiceSampleByIndex(int32 index, byte *comp_final); int32 decompressVoiceSampleByIndex(int32 index, byte *comp_final);
int32 decompressMusicSampleByName(char *name, int32 number, byte *comp_final); int32 decompressMusicSampleByName(char *name, int32 number, byte *comp_final);

View file

@ -73,16 +73,16 @@ void Scumm::openRoom(int room)
if (!(_features & GF_SMALL_HEADER)) { if (!(_features & GF_SMALL_HEADER)) {
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
sprintf(buf, "%s%s.la%d", _gameDataPath, _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]); sprintf(buf, "%s.la%d", _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]);
else if (_features & GF_HUMONGOUS) else if (_features & GF_HUMONGOUS)
sprintf(buf, "%s%s.he%.1d", _gameDataPath, _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]); sprintf(buf, "%s.he%.1d", _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]);
else else
sprintf(buf, "%s%s.%.3d", _gameDataPath, _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]); sprintf(buf, "%s.%.3d", _exe_name, room == 0 ? 0 : res.roomno[rtRoom][room]);
_encbyte = (_features & GF_USE_KEY) ? 0x69 : 0; _encbyte = (_features & GF_USE_KEY) ? 0x69 : 0;
} else if (!(_features & GF_SMALL_NAMES)) { } else if (!(_features & GF_SMALL_NAMES)) {
if (room == 0 || room >= 900) { if (room == 0 || room >= 900) {
sprintf(buf, "%s%.3d.lfl", _gameDataPath, room); sprintf(buf, "%.3d.lfl", room);
_encbyte = 0; _encbyte = 0;
if (openResourceFile(buf)) { if (openResourceFile(buf)) {
return; return;
@ -90,11 +90,11 @@ void Scumm::openRoom(int room)
askForDisk(buf); askForDisk(buf);
} else { } else {
sprintf(buf, "%sdisk%.2d.lec", _gameDataPath, res.roomno[rtRoom][room]); sprintf(buf, "disk%.2d.lec", res.roomno[rtRoom][room]);
_encbyte = 0x69; _encbyte = 0x69;
} }
} else { } else {
sprintf(buf, "%s%.2d.lfl", _gameDataPath, room); sprintf(buf, "%.2d.lfl", room);
if (_features & GF_OLD_BUNDLE) if (_features & GF_OLD_BUNDLE)
_encbyte = 0xFF; _encbyte = 0xFF;
else else
@ -186,26 +186,7 @@ bool Scumm::openResourceFile(const char *filename)
} }
strcpy(buf, filename); strcpy(buf, filename);
_fileHandle.open(buf, 1, _encbyte); _fileHandle.open(buf, getGameDataPath(), 1, _encbyte);
if (_fileHandle.isOpen() == false) {
char *e = strrchr(buf, '/');
if (!e)
e = buf;
do
*e = tolower(*e);
while (*e++);
_fileHandle.open(buf, 1, _encbyte);
}
if (_fileHandle.isOpen() == false) {
char *e = strrchr(buf, '/');
if (!e)
e = buf;
do
*e = toupper(*e);
while (*e++);
_fileHandle.open(buf, 1, _encbyte);
}
return _fileHandle.isOpen(); return _fileHandle.isOpen();
} }

View file

@ -2719,9 +2719,8 @@ void Scumm::o6_miscOps()
SmushPlayer sp(&sr); SmushPlayer sp(&sr);
char filename[512]; char filename[512];
strcpy(filename, _gameDataPath); strcpy(filename, _gameDataPath);
strcat(filename, "video/");
strcat(filename, (char*)getStringAddressVar(VAR_VIDEONAME)); strcat(filename, (char*)getStringAddressVar(VAR_VIDEONAME));
sp.play(filename); sp.play(filename, getGameDataPath());
} }
break; break;
case 7: case 7:

View file

@ -871,9 +871,9 @@ void Scumm::dumpResource(char *tag, int idx, byte *ptr)
sprintf(buf, "dumps/%s%d.dmp", tag, idx); sprintf(buf, "dumps/%s%d.dmp", tag, idx);
#endif #endif
out.open(buf, 1); out.open(buf, "", 1);
if (out.isOpen() == false) { if (out.isOpen() == false) {
out.open(buf, 2); out.open(buf, "", 2);
if (out.isOpen() == false) if (out.isOpen() == false)
return; return;
out.write(ptr, size); out.write(ptr, size);

View file

@ -34,33 +34,33 @@
*/ */
class FilePtr { class FilePtr {
char * _filename; char * _filename;
FILE * _ifs; File _ifs;
int32 _refcount; int32 _refcount;
int32 _curPos; int32 _curPos;
public: public:
FilePtr(const char * fname) : _refcount(1), _curPos(0) { FilePtr(const char * fname, const char * directory) : _refcount(1), _curPos(0) {
debug(9, "FilePtr created for %s", fname); debug(9, "FilePtr created for %s", fname);
_filename = strdup(fname); _filename = strdup(fname);
_ifs = fopen_nocase(fname, "rb"); _ifs.open(fname, directory);
if(_ifs == NULL) error("FilePtr unable to read file \"%s\"", fname); if(_ifs.isOpen() == false) error("FilePtr unable to read file %s", fname);
} }
~FilePtr() { ~FilePtr() {
debug(9, "FilePtr destroyed for %s", _filename); debug(9, "FilePtr destroyed for %s", _filename);
free(_filename); free(_filename);
fclose(_ifs); _ifs.close();
} }
int32 tell() { int32 tell() {
return _curPos; return _curPos;
} }
bool seek(int32 pos) { bool seek(int32 pos) {
if(pos != _curPos) { if(pos != _curPos) {
fseek(_ifs, pos, SEEK_SET); _ifs.seek(pos, SEEK_SET);
_curPos = pos; _curPos = pos;
} }
return true; return true;
} }
bool read(void * ptr, int32 size) { bool read(void * ptr, int32 size) {
fread(ptr, size, 1, _ifs); _ifs.read(ptr, size);
_curPos += size; _curPos += size;
return true; return true;
} }
@ -90,8 +90,8 @@ FileChunk::~FileChunk() {
if(_data) _data->decRef(); if(_data) _data->decRef();
} }
FileChunk::FileChunk(const char * fname) { FileChunk::FileChunk(const char * fname, const char * directory) {
_data = new FilePtr(fname); _data = new FilePtr(fname, directory);
_data->read(&_type, 4); _data->read(&_type, 4);
_type = TO_BE_32(_type); _type = TO_BE_32(_type);
_data->read(&_size, 4); _data->read(&_size, 4);

View file

@ -76,7 +76,7 @@ private:
protected: protected:
FileChunk(); FileChunk();
public: public:
FileChunk(const char * fname); FileChunk(const char * fname, const char * directory);
virtual ~FileChunk(); virtual ~FileChunk();
type getType() const; type getType() const;
uint32 getSize() const; uint32 getSize() const;

View file

@ -616,10 +616,10 @@ void SmushPlayer::handleAnimHeader(Chunk & b) {
} }
#define NEW_FILE 1 #define NEW_FILE 1
static StringResource * getStrings(const char * file, bool is_encoded) { static StringResource * getStrings(const char * file, const char * directory, bool is_encoded) {
debug(7, "trying to read text ressources from %s", file); debug(7, "trying to read text ressources from %s", file);
File theFile; File theFile;
theFile.open(file); theFile.open(file, directory);
if (!theFile.isOpen()) if (!theFile.isOpen())
return 0; return 0;
int32 length = theFile.size(); int32 length = theFile.size();
@ -633,7 +633,7 @@ static StringResource * getStrings(const char * file, bool is_encoded) {
Chunk::type type = READ_BE_UINT32(filebuffer); Chunk::type type = READ_BE_UINT32(filebuffer);
if(type != TYPE_ETRS) { if(type != TYPE_ETRS) {
delete [] filebuffer; delete [] filebuffer;
return getStrings(file, false); return getStrings(file, directory, false);
} }
char * old = filebuffer; char * old = filebuffer;
filebuffer = new char[length - ETRS_HEADER_LENGTH]; filebuffer = new char[length - ETRS_HEADER_LENGTH];
@ -649,102 +649,58 @@ static StringResource * getStrings(const char * file, bool is_encoded) {
return sr; return sr;
} }
bool SmushPlayer::readString(const char * file, bool & ft) { bool SmushPlayer::readString(const char * file, const char * directory, bool & ft) {
const char * i = strrchr(file, '.'); const char * i = strrchr(file, '.');
if(i == NULL) error("invalid filename : %s", file); if(i == NULL) error("invalid filename : %s", file);
char fname[260]; char fname[260];
memcpy(fname, file, i - file); memcpy(fname, file, i - file);
strcpy(fname + (i - file), ".trs"); strcpy(fname + (i - file), ".trs");
if((_strings = getStrings(fname, false)) != 0) { if((_strings = getStrings(fname, directory, false)) != 0) {
ft = true; ft = true;
return true; return true;
} }
i = strrchr(file, '\\');
if(i == NULL) i = strrchr(file, '/');
else {
char * j = strrchr(file, '/');
if(j > i) i = j;
}
if(i == NULL) error("invalid filename : %s", file);
memcpy(fname, file, i - file + 1); if((_strings = getStrings("digtxt.trs", directory, true)) != 0) {
strcpy(fname + (i - file + 1), "digtxt.trs");
if((_strings = getStrings(fname, true)) != 0) {
ft = false; ft = false;
return true; return true;
} }
return false; return false;
} }
static FontRenderer * loadFont(const char * file, bool original = false) { static FontRenderer * loadFont(const char * file, const char * directory, bool original = false) {
#ifdef DEBUG #ifdef DEBUG
debug(5, "loading font from \"%s\"", file); debug(5, "loading font from \"%s\"", file);
#endif #endif
FontRenderer * fr = new FontRenderer(original); FontRenderer * fr = new FontRenderer(original);
SmushPlayer p(fr, false, false); SmushPlayer p(fr, false, false);
p.play(file); p.play(file, directory);
return fr; return fr;
} }
bool SmushPlayer::play(const char * file) { bool SmushPlayer::play(const char * file, const char * directory) {
#ifdef DEBUG #ifdef DEBUG
debug(5, "start of animation : %s", file); debug(5, "start of animation : %s", file);
#endif #endif
char * i = strrchr(file, '\\');
if(i == NULL)
{
i = strrchr(file, '/');
} else {
char * j = strrchr(i, '/');
if(j != NULL)
i = j;
}
char directory[260];
if(i != NULL) {
strcpy(directory, file);
directory[i-file] = 0;
//! @todo remove this...
_fname = strdup(i);
} else {
directory[0] = 0;
_fname = strdup(file);
}
clean(); clean();
if(_wait) { if(_wait) {
bool isFullthrottle; bool isFullthrottle;
if(!readString(file, isFullthrottle)) if(!readString(file, directory, isFullthrottle))
warning("unable to read text information for \"%s\"", file); warning("unable to read text information for \"%s\"", file);
if(_strings) { if(_strings) {
if(isFullthrottle) { if(isFullthrottle) {
if(strcmp(directory, "") == 0) { _fr[0] = loadFont("scummfnt.nut", directory, true);
strcpy(directory, "../data/"); _fr[2] = loadFont("titlfnt.nut", directory, true);
} else {
char * i = strrchr(directory, '\\');
char * j = strrchr(directory, '/');
if(j > i) i = j;
if(i == NULL) {
strcpy(directory, "data/");
} else {
*i = 0;
strcat(directory, "/data/");
}
}
char file[260];
strcpy(file, directory); strcat(file, "scummfnt.nut");
_fr[0] = loadFont(file, true);
strcpy(file, directory); strcat(file, "titlfnt.nut");
_fr[2] = loadFont(file, true);
} else { } else {
for(int32 i = 0; i < 4; i++) { for(int32 i = 0; i < 4; i++) {
char file[260]; char file_font[20];
sprintf(file, "%s/font%d.nut",directory, i); sprintf((char*)&file_font, "font%d.nut", i);
_fr[i] = loadFont(file, i != 0); _fr[i] = loadFont(file_font, directory, i != 0);
} }
} }
} }
} }
FileChunk base = FileChunk(file); FileChunk base = FileChunk(file, directory);
checkBlock(base, TYPE_ANIM); checkBlock(base, TYPE_ANIM);

View file

@ -73,12 +73,12 @@ private:
public: public:
SmushPlayer(Renderer *, bool wait = true, bool output_sound = true); SmushPlayer(Renderer *, bool wait = true, bool output_sound = true);
virtual ~SmushPlayer(); virtual ~SmushPlayer();
bool play(const char *); bool play(const char *, const char * directory);
void updatePalette(void); void updatePalette(void);
void show(const char *); void show(const char *);
void hide(const char *); void hide(const char *);
protected: protected:
bool readString(const char * file, bool &); bool readString(const char * file, const char * directory, bool &);
void clean(); void clean();
void checkBlock(const Chunk &, Chunk::type, uint32 = 0); void checkBlock(const Chunk &, Chunk::type, uint32 = 0);
void handleAnimHeader(Chunk &); void handleAnimHeader(Chunk &);

View file

@ -751,10 +751,9 @@ File * Sound::openSfxFile() {
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
offset_table = NULL; offset_table = NULL;
sprintf(buf, "%s%s.so3", _scumm->getGameDataPath(), _scumm->_exe_name); sprintf(buf, "%s.so3", _scumm->_exe_name);
if (!file->open(buf)) { if (!file->open(buf, _scumm->getGameDataPath())) {
sprintf(buf, "%smonster.so3", _scumm->getGameDataPath()); file->open("monster.so3", _scumm->getGameDataPath());
file->open(buf);
} }
if (file->isOpen() == true) { if (file->isOpen() == true) {
/* Now load the 'offset' index in memory to be able to find the MP3 data /* Now load the 'offset' index in memory to be able to find the MP3 data
@ -791,10 +790,9 @@ File * Sound::openSfxFile() {
return file; return file;
} }
#endif #endif
sprintf(buf, "%s%s.sou", _scumm->getGameDataPath(), _scumm->_exe_name); sprintf(buf, "%s.sou", _scumm->_exe_name);
if (!file->open(buf)) { if (!file->open(buf, _scumm->getGameDataPath())) {
sprintf(buf, "%smonster.sou", _scumm->getGameDataPath()); file->open("monster.sou", _scumm->getGameDataPath());
file->open(buf);
} }
return file; return file;
} }
@ -837,11 +835,8 @@ static void music_handler (Scumm * scumm) {
#define OUTPUT_SIZE 66150 // ((22050 * 2 * 2) / 4) * 3 #define OUTPUT_SIZE 66150 // ((22050 * 2 * 2) / 4) * 3
void Sound::playBundleMusic(int32 song) { void Sound::playBundleMusic(int32 song) {
char buf[256];
if (_numberBundleMusic == -1) { if (_numberBundleMusic == -1) {
sprintf(buf, "%s%smusic.bun", _scumm->getGameDataPath(), _scumm->_exe_name); if (_scumm->_bundle->openMusicFile("digmusic.bun", _scumm->getGameDataPath()) == false) {
if (_scumm->_bundle->openMusicFile((char*)&buf) == false) {
return; return;
} }
@ -958,11 +953,9 @@ void Sound::bundleMusicHandler(Scumm * scumm) {
} }
void Sound::playBundleSound(char *sound) { void Sound::playBundleSound(char *sound) {
char buf[256];
byte * ptr; byte * ptr;
sprintf(buf, "%s%svoice.bun", _scumm->getGameDataPath(), _scumm->_exe_name); if (_scumm->_bundle->openVoiceFile("digvoice.bun", _scumm->getGameDataPath()) == false) {
if (_scumm->_bundle->openVoiceFile((char*)&buf) == false) {
return; return;
} }
@ -1093,8 +1086,8 @@ int Sound::getCachedTrack(int track) {
_current_cache %= CACHE_TRACKS; _current_cache %= CACHE_TRACKS;
// Not found, see if it exists // Not found, see if it exists
sprintf(track_name, "%strack%d.mp3", _scumm->getGameDataPath(), track); sprintf(track_name, "track%d.mp3", track);
file->open(track_name); file->open(track_name, _scumm->getGameDataPath());
_cached_tracks[current_index] = track; _cached_tracks[current_index] = track;
/* First, close the previous file */ /* First, close the previous file */