mirror of https://github.com/OpenTTD/OpenTTD
(svn r9560) -Codechange: add support for multiple 'base' directories for newgrf searching.
-Codechange: do not add duplicate files to the newgrf list.release/0.6
parent
a1b7fb8909
commit
db91588845
|
@ -170,7 +170,7 @@ void FioOpenFile(int slot, const char *filename)
|
||||||
FioFreeHandle();
|
FioFreeHandle();
|
||||||
#endif /* LIMITED_FDS */
|
#endif /* LIMITED_FDS */
|
||||||
f = FioFOpenFile(filename);
|
f = FioFOpenFile(filename);
|
||||||
if (f == NULL) error("Cannot open file '%s%s'", _paths.data_dir, filename);
|
if (f == NULL) error("Cannot open file '%s'", filename);
|
||||||
|
|
||||||
FioCloseFile(slot); // if file was opened before, close it
|
FioCloseFile(slot); // if file was opened before, close it
|
||||||
_fio.handles[slot] = f;
|
_fio.handles[slot] = f;
|
||||||
|
@ -206,12 +206,16 @@ FILE *FioFOpenFile(const char *filename)
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename);
|
if (strrchr(filename, PATHSEPCHAR) == NULL) {
|
||||||
|
snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename);
|
||||||
|
} else {
|
||||||
|
ttd_strlcpy(buf, filename, lengthof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
f = fopen(buf, "rb");
|
f = fopen(buf, "rb");
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
strtolower(buf + strlen(_paths.data_dir) - 1);
|
strtolower(strrchr(buf, PATHSEPCHAR));
|
||||||
f = fopen(buf, "rb");
|
f = fopen(buf, "rb");
|
||||||
|
|
||||||
#if defined SECOND_DATA_DIR
|
#if defined SECOND_DATA_DIR
|
||||||
|
@ -308,6 +312,8 @@ void DetermineBasePaths(const char *exe)
|
||||||
#if defined(SECOND_DATA_DIR)
|
#if defined(SECOND_DATA_DIR)
|
||||||
_paths.second_data_dir = MallocT<char>(MAX_PATH);
|
_paths.second_data_dir = MallocT<char>(MAX_PATH);
|
||||||
ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
|
ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
|
||||||
|
#else
|
||||||
|
_paths.second_data_dir = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_HOMEDIR)
|
#if defined(USE_HOMEDIR)
|
||||||
|
|
|
@ -391,12 +391,13 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo
|
||||||
/* Don't know the GRF, so mark game incompatible and the (possibly)
|
/* Don't know the GRF, so mark game incompatible and the (possibly)
|
||||||
* already resolved name for this GRF (another server has sent the
|
* already resolved name for this GRF (another server has sent the
|
||||||
* name of the GRF already */
|
* name of the GRF already */
|
||||||
config->name = FindUnknownGRFName(config->grfid, config->md5sum, true);
|
config->name = FindUnknownGRFName(config->grfid, config->md5sum, true);
|
||||||
config->status = GCS_NOT_FOUND;
|
config->status = GCS_NOT_FOUND;
|
||||||
} else {
|
} else {
|
||||||
config->filename = f->filename;
|
config->filename = f->filename;
|
||||||
config->name = f->name;
|
config->full_path = f->full_path;
|
||||||
config->info = f->info;
|
config->name = f->name;
|
||||||
|
config->info = f->info;
|
||||||
}
|
}
|
||||||
SETBIT(config->flags, GCF_COPY);
|
SETBIT(config->flags, GCF_COPY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4305,7 +4305,7 @@ static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
|
||||||
|
|
||||||
if (newfile == NULL) error ("Out of memory");
|
if (newfile == NULL) error ("Out of memory");
|
||||||
|
|
||||||
newfile->filename = strdup(config->filename);
|
newfile->filename = strdup(config->full_path);
|
||||||
newfile->sprite_offset = sprite_offset;
|
newfile->sprite_offset = sprite_offset;
|
||||||
|
|
||||||
/* Copy the initial parameter list */
|
/* Copy the initial parameter list */
|
||||||
|
@ -4583,7 +4583,7 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
|
||||||
|
|
||||||
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
|
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
|
||||||
{
|
{
|
||||||
const char *filename = config->filename;
|
const char *filename = config->full_path;
|
||||||
uint16 num;
|
uint16 num;
|
||||||
|
|
||||||
/* A .grf file is activated only if it was active when the game was
|
/* A .grf file is activated only if it was active when the game was
|
||||||
|
@ -4699,7 +4699,7 @@ void LoadNewGRF(uint load_index, uint file_index)
|
||||||
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
|
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
|
||||||
|
|
||||||
/* @todo usererror() */
|
/* @todo usererror() */
|
||||||
if (!FioCheckFileExists(c->filename)) error("NewGRF file is missing '%s'", c->filename);
|
if (!FileExists(c->full_path)) error("NewGRF file is missing '%s'", c->filename);
|
||||||
|
|
||||||
if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
|
if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
|
||||||
LoadNewGRFFile(c, slot++, stage);
|
LoadNewGRFFile(c, slot++, stage);
|
||||||
|
|
|
@ -35,14 +35,12 @@ GRFConfig *_grfconfig_static;
|
||||||
static bool CalcGRFMD5Sum(GRFConfig *config)
|
static bool CalcGRFMD5Sum(GRFConfig *config)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char filename[MAX_PATH];
|
|
||||||
md5_state_t md5state;
|
md5_state_t md5state;
|
||||||
md5_byte_t buffer[1024];
|
md5_byte_t buffer[1024];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
snprintf(filename, lengthof(filename), "%s%s", _paths.data_dir, config->filename);
|
f = fopen(config->full_path, "rb");
|
||||||
f = fopen(filename, "rb");
|
|
||||||
if (f == NULL) return false;
|
if (f == NULL) return false;
|
||||||
|
|
||||||
/* calculate md5sum */
|
/* calculate md5sum */
|
||||||
|
@ -61,7 +59,7 @@ static bool CalcGRFMD5Sum(GRFConfig *config)
|
||||||
/* Find the GRFID and calculate the md5sum */
|
/* Find the GRFID and calculate the md5sum */
|
||||||
bool FillGRFDetails(GRFConfig *config, bool is_static)
|
bool FillGRFDetails(GRFConfig *config, bool is_static)
|
||||||
{
|
{
|
||||||
if (!FioCheckFileExists(config->filename)) {
|
if (!FileExists(config->full_path)) {
|
||||||
config->status = GCS_NOT_FOUND;
|
config->status = GCS_NOT_FOUND;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +89,7 @@ void ClearGRFConfig(GRFConfig **config)
|
||||||
/* GCF_COPY as in NOT strdupped/alloced the filename, name and info */
|
/* GCF_COPY as in NOT strdupped/alloced the filename, name and info */
|
||||||
if (!HASBIT((*config)->flags, GCF_COPY)) {
|
if (!HASBIT((*config)->flags, GCF_COPY)) {
|
||||||
free((*config)->filename);
|
free((*config)->filename);
|
||||||
|
free((*config)->full_path);
|
||||||
free((*config)->name);
|
free((*config)->name);
|
||||||
free((*config)->info);
|
free((*config)->info);
|
||||||
free((*config)->error);
|
free((*config)->error);
|
||||||
|
@ -123,10 +122,11 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src)
|
||||||
for (; src != NULL; src = src->next) {
|
for (; src != NULL; src = src->next) {
|
||||||
GRFConfig *c = CallocT<GRFConfig>(1);
|
GRFConfig *c = CallocT<GRFConfig>(1);
|
||||||
*c = *src;
|
*c = *src;
|
||||||
if (src->filename != NULL) c->filename = strdup(src->filename);
|
if (src->filename != NULL) c->filename = strdup(src->filename);
|
||||||
if (src->name != NULL) c->name = strdup(src->name);
|
if (src->full_path != NULL) c->full_path = strdup(src->full_path);
|
||||||
if (src->info != NULL) c->info = strdup(src->info);
|
if (src->name != NULL) c->name = strdup(src->name);
|
||||||
if (src->error != NULL) {
|
if (src->info != NULL) c->info = strdup(src->info);
|
||||||
|
if (src->error != NULL) {
|
||||||
c->error = CallocT<GRFError>(1);
|
c->error = CallocT<GRFError>(1);
|
||||||
memcpy(c->error, src->error, sizeof(GRFError));
|
memcpy(c->error, src->error, sizeof(GRFError));
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,9 @@ compatible_grf:
|
||||||
* already a local one, so there is no need to replace it. */
|
* already a local one, so there is no need to replace it. */
|
||||||
if (!HASBIT(c->flags, GCF_COPY)) {
|
if (!HASBIT(c->flags, GCF_COPY)) {
|
||||||
free(c->filename);
|
free(c->filename);
|
||||||
|
free(c->full_path);
|
||||||
c->filename = strdup(f->filename);
|
c->filename = strdup(f->filename);
|
||||||
|
c->full_path = strdup(f->full_path);
|
||||||
memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum));
|
memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum));
|
||||||
if (c->name == NULL && f->name != NULL) c->name = strdup(f->name);
|
if (c->name == NULL && f->name != NULL) c->name = strdup(f->name);
|
||||||
if (c->info == NULL && f->info != NULL) c->info = strdup(f->info);
|
if (c->info == NULL && f->info != NULL) c->info = strdup(f->info);
|
||||||
|
@ -278,7 +280,7 @@ static uint ScanPath(const char *path)
|
||||||
struct dirent *dirent;
|
struct dirent *dirent;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
if ((dir = ttd_opendir(path)) == NULL) return 0;
|
if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0;
|
||||||
|
|
||||||
while ((dirent = readdir(dir)) != NULL) {
|
while ((dirent = readdir(dir)) != NULL) {
|
||||||
const char *d_name = FS2OTTD(dirent->d_name);
|
const char *d_name = FS2OTTD(dirent->d_name);
|
||||||
|
@ -286,24 +288,26 @@ static uint ScanPath(const char *path)
|
||||||
|
|
||||||
if (!FiosIsValidFile(path, dirent, &sb)) continue;
|
if (!FiosIsValidFile(path, dirent, &sb)) continue;
|
||||||
|
|
||||||
snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name);
|
snprintf(filename, lengthof(filename), "%s%s", path, d_name);
|
||||||
|
|
||||||
if (sb.st_mode & S_IFDIR) {
|
if (sb.st_mode & S_IFDIR) {
|
||||||
/* Directory */
|
/* Directory */
|
||||||
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
|
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
|
||||||
|
AppendPathSeparator(filename, lengthof(filename));
|
||||||
num += ScanPath(filename);
|
num += ScanPath(filename);
|
||||||
} else if (sb.st_mode & S_IFREG) {
|
} else if (sb.st_mode & S_IFREG) {
|
||||||
/* File */
|
/* File */
|
||||||
char *ext = strrchr(filename, '.');
|
char *ext = strrchr(filename, '.');
|
||||||
char *file = filename + strlen(_paths.data_dir) + 1; // Crop base path
|
|
||||||
|
|
||||||
/* If no extension or extension isn't .grf, skip the file */
|
/* If no extension or extension isn't .grf, skip the file */
|
||||||
if (ext == NULL) continue;
|
if (ext == NULL) continue;
|
||||||
if (strcasecmp(ext, ".grf") != 0) continue;
|
if (strcasecmp(ext, ".grf") != 0) continue;
|
||||||
|
|
||||||
GRFConfig *c = CallocT<GRFConfig>(1);
|
GRFConfig *c = CallocT<GRFConfig>(1);
|
||||||
c->filename = strdup(file);
|
c->full_path = strdup(filename);
|
||||||
|
c->filename = strdup(strrchr(filename, PATHSEPCHAR) + 1);
|
||||||
|
|
||||||
|
bool added = true;
|
||||||
if (FillGRFDetails(c, false)) {
|
if (FillGRFDetails(c, false)) {
|
||||||
if (_all_grfs == NULL) {
|
if (_all_grfs == NULL) {
|
||||||
_all_grfs = c;
|
_all_grfs = c;
|
||||||
|
@ -312,20 +316,28 @@ static uint ScanPath(const char *path)
|
||||||
* name, so the list is sorted as we go along */
|
* name, so the list is sorted as we go along */
|
||||||
GRFConfig **pd, *d;
|
GRFConfig **pd, *d;
|
||||||
for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
|
for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
|
||||||
|
if (c->grfid == d->grfid && memcmp(c->md5sum, d->md5sum, sizeof(c->md5sum)) == 0) added = false;
|
||||||
if (strcasecmp(c->name, d->name) <= 0) break;
|
if (strcasecmp(c->name, d->name) <= 0) break;
|
||||||
}
|
}
|
||||||
c->next = d;
|
if (added) {
|
||||||
*pd = c;
|
c->next = d;
|
||||||
|
*pd = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num++;
|
|
||||||
} else {
|
} else {
|
||||||
|
added = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!added) {
|
||||||
/* File couldn't be opened, or is either not a NewGRF or is a
|
/* File couldn't be opened, or is either not a NewGRF or is a
|
||||||
* 'system' NewGRF, so forget about it. */
|
* 'system' NewGRF or it's already known, so forget about it. */
|
||||||
free(c->filename);
|
free(c->filename);
|
||||||
|
free(c->full_path);
|
||||||
free(c->name);
|
free(c->name);
|
||||||
free(c->info);
|
free(c->info);
|
||||||
free(c);
|
free(c);
|
||||||
|
} else {
|
||||||
|
num++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +356,8 @@ void ScanNewGRFFiles()
|
||||||
ClearGRFConfigList(&_all_grfs);
|
ClearGRFConfigList(&_all_grfs);
|
||||||
|
|
||||||
DEBUG(grf, 1, "Scanning for NewGRFs");
|
DEBUG(grf, 1, "Scanning for NewGRFs");
|
||||||
num = ScanPath(_paths.data_dir);
|
num = ScanPath(_paths.data_dir);
|
||||||
|
num += ScanPath(_paths.second_data_dir);
|
||||||
DEBUG(grf, 1, "Scan complete, found %d files", num);
|
DEBUG(grf, 1, "Scan complete, found %d files", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct GRFError {
|
||||||
|
|
||||||
struct GRFConfig : public GRFIdentifier {
|
struct GRFConfig : public GRFIdentifier {
|
||||||
char *filename;
|
char *filename;
|
||||||
|
char *full_path;
|
||||||
char *name;
|
char *name;
|
||||||
char *info;
|
char *info;
|
||||||
GRFError *error;
|
GRFError *error;
|
||||||
|
|
|
@ -946,6 +946,7 @@ void GetCurrentDirectoryW(int length, wchar_t *path)
|
||||||
void DetermineBasePaths(const char *exe)
|
void DetermineBasePaths(const char *exe)
|
||||||
{
|
{
|
||||||
_paths.personal_dir = _paths.game_data_dir = MallocT<char>(MAX_PATH);
|
_paths.personal_dir = _paths.game_data_dir = MallocT<char>(MAX_PATH);
|
||||||
|
_paths.second_data_dir = NULL;
|
||||||
#if defined(UNICODE)
|
#if defined(UNICODE)
|
||||||
TCHAR path[MAX_PATH];
|
TCHAR path[MAX_PATH];
|
||||||
GetCurrentDirectory(MAX_PATH - 1, path);
|
GetCurrentDirectory(MAX_PATH - 1, path);
|
||||||
|
|
Loading…
Reference in New Issue