Changeset - r27159:693b9615eaea
[Not reviewed]
master
0 8 0
Rubidium - 17 months ago 2023-04-18 20:21:17
rubidium@openttd.org
Codechange: use std::string for base media filename/warning storage
8 files changed with 39 insertions and 44 deletions:
0 comments (0 inline, 0 general)
src/base_media_base.h
Show inline comments
 
@@ -22,27 +22,27 @@ struct IniFile;
 
struct ContentInfo;
 

	
 
/** Structure holding filename and MD5 information about a single file */
 
struct MD5File {
 
	/** The result of a checksum check */
 
	enum ChecksumResult {
 
		CR_UNKNOWN,  ///< The file has not been checked yet
 
		CR_MATCH,    ///< The file did exist and the md5 checksum did match
 
		CR_MISMATCH, ///< The file did exist, just the md5 checksum did not match
 
		CR_NO_FILE,  ///< The file did not exist
 
	};
 

	
 
	const char *filename;        ///< filename
 
	std::string filename;        ///< filename
 
	uint8 hash[16];              ///< md5 sum of the file
 
	const char *missing_warning; ///< warning when this file is missing
 
	std::string missing_warning; ///< warning when this file is missing
 
	ChecksumResult check_result; ///< cached result of md5 check
 

	
 
	ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
 
};
 

	
 
/**
 
 * Information about a single base set.
 
 * @tparam T the real class we're going to be
 
 * @tparam Tnum_files the number of files in the set
 
 * @tparam Tsearch_in_tars whether to search in the tars or not
 
 */
 
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
 
@@ -64,52 +64,47 @@ struct BaseSet {
 
	uint32 version;                ///< The version of this base set
 
	bool fallback;                 ///< This set is a fallback set, i.e. it should be used only as last resort
 

	
 
	MD5File files[NUM_FILES];      ///< All files part of this set
 
	uint found_files;              ///< Number of the files that could be found
 
	uint valid_files;              ///< Number of the files that could be found and are valid
 

	
 
	T *next;                       ///< The next base set in this list
 

	
 
	/** Free everything we allocated */
 
	~BaseSet()
 
	{
 
		for (uint i = 0; i < NUM_FILES; i++) {
 
			free(this->files[i].filename);
 
			free(this->files[i].missing_warning);
 
		}
 

	
 
		delete this->next;
 
	}
 

	
 
	/**
 
	 * Get the number of missing files.
 
	 * @return the number
 
	 */
 
	int GetNumMissing() const
 
	{
 
		return Tnum_files - this->found_files;
 
	}
 

	
 
	/**
 
	 * Get the number of invalid files.
 
	 * @note a missing file is invalid too!
 
	 * @return the number
 
	 */
 
	int GetNumInvalid() const
 
	{
 
		return Tnum_files - this->valid_files;
 
	}
 

	
 
	bool FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename = true);
 
	bool FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
 

	
 
	/**
 
	 * Get the description for the given ISO code.
 
	 * It falls back to the first two characters of the ISO code in case
 
	 * no match could be made with the full ISO code. If even then the
 
	 * matching fails the default is returned.
 
	 * @param isocode the isocode to search for
 
	 * @return the description
 
	 */
 
	const char *GetDescription(const std::string &isocode) const
 
	{
 
		if (!isocode.empty()) {
 
@@ -138,25 +133,25 @@ struct BaseSet {
 
	{
 
		return file->CheckMD5(subdir, SIZE_MAX);
 
	}
 

	
 
	/**
 
	 * Search a textfile file next to this base media.
 
	 * @param type The type of the textfile to search for.
 
	 * @return The filename for the textfile, \c nullptr otherwise.
 
	 */
 
	const char *GetTextfile(TextfileType type) const
 
	{
 
		for (uint i = 0; i < NUM_FILES; i++) {
 
			const char *textfile = ::GetTextfile(type, BASESET_DIR, this->files[i].filename);
 
			const char *textfile = ::GetTextfile(type, BASESET_DIR, this->files[i].filename.c_str());
 
			if (textfile != nullptr) {
 
				return textfile;
 
			}
 
		}
 
		return nullptr;
 
	}
 
};
 

	
 
/**
 
 * Base for all base media (graphics, sounds)
 
 * @tparam Tbase_set the real set we're going to be
 
 */
 
@@ -240,25 +235,25 @@ enum GraphicsFileType {
 

	
 
/** Blitter type for base graphics sets. */
 
enum BlitterType {
 
	BLT_8BPP,       ///< Base set has 8 bpp sprites only.
 
	BLT_32BPP,      ///< Base set has both 8 bpp and 32 bpp sprites.
 
};
 

	
 
/** All data of a graphics set. */
 
struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
 
	PaletteType palette;       ///< Palette of this graphics set
 
	BlitterType blitter;       ///< Blitter of this graphics set
 

	
 
	bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
 
	bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename);
 

	
 
	static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir);
 
};
 

	
 
/** All data/functions related with replacing the base graphics. */
 
class BaseGraphics : public BaseMedia<GraphicsSet> {
 
public:
 
};
 

	
 
/** All data of a sounds set. */
 
struct SoundsSet : BaseSet<SoundsSet, 1, true> {
 
};
 
@@ -270,48 +265,48 @@ public:
 

	
 
/** Maximum number of songs in the 'class' playlists. */
 
static const uint NUM_SONGS_CLASS     = 10;
 
/** Number of classes for songs */
 
static const uint NUM_SONG_CLASSES    = 3;
 
/** Maximum number of songs in the full playlist; theme song + the classes */
 
static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS;
 

	
 
/** Maximum number of songs in the (custom) playlist */
 
static const uint NUM_SONGS_PLAYLIST  = 32;
 

	
 
/* Functions to read DOS music CAT files, similar to but not quite the same as sound effect CAT files */
 
char *GetMusicCatEntryName(const char *filename, size_t entrynum);
 
byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entrylen);
 
char *GetMusicCatEntryName(const std::string &filename, size_t entrynum);
 
byte *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
 

	
 
enum MusicTrackType {
 
	MTT_STANDARDMIDI, ///< Standard MIDI file
 
	MTT_MPSMIDI,      ///< MPS GM driver MIDI format (contained in a CAT file)
 
};
 

	
 
/** Metadata about a music track. */
 
struct MusicSongInfo {
 
	std::string songname;    ///< name of song displayed in UI
 
	byte tracknr;            ///< track number of song displayed in UI
 
	const char *filename;    ///< file on disk containing song (when used in MusicSet class, this pointer is owned by MD5File object for the file)
 
	std::string filename;    ///< file on disk containing song (when used in MusicSet class)
 
	MusicTrackType filetype; ///< decoder required for song file
 
	int cat_index;           ///< entry index in CAT file, for filetype==MTT_MPSMIDI
 
	bool loop;               ///< song should play in a tight loop if possible, never ending
 
	int override_start;      ///< MIDI ticks to skip over in beginning
 
	int override_end;        ///< MIDI tick to end the song at (0 if no override)
 
};
 

	
 
/** All data of a music set. */
 
struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
 
	/** Data about individual songs in set. */
 
	MusicSongInfo songinfo[NUM_SONGS_AVAILABLE];
 
	/** Number of valid songs in set. */
 
	byte num_available;
 

	
 
	bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename);
 
	bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename);
 
};
 

	
 
/** All data/functions related with replacing the base music */
 
class BaseMusic : public BaseMedia<MusicSet> {
 
public:
 
};
 

	
 
#endif /* BASE_MEDIA_BASE_H */
src/base_media_func.h
Show inline comments
 
@@ -29,25 +29,25 @@ extern void CheckExternalFiles();
 
		return false; \
 
	}
 

	
 
/**
 
 * Read the set information from a loaded ini.
 
 * @param ini      the ini to read from
 
 * @param path     the path to this ini file (for filenames)
 
 * @param full_filename the full filename of the loaded file (for error reporting purposes)
 
 * @param allow_empty_filename empty filenames are valid
 
 * @return true if loading was successful.
 
 */
 
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
 
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const char *path, const char *full_filename, bool allow_empty_filename)
 
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
 
{
 
	IniGroup *metadata = ini->GetGroup("metadata");
 
	IniItem *item;
 

	
 
	fetch_metadata("name");
 
	this->name = *item->value;
 

	
 
	fetch_metadata("description");
 
	this->description[std::string{}] = *item->value;
 

	
 
	/* Add the translations of the descriptions too. */
 
	for (item = metadata->item; item != nullptr; item = item->next) {
 
@@ -72,33 +72,33 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
	IniGroup *md5s   = ini->GetGroup("md5s");
 
	IniGroup *origin = ini->GetGroup("origin");
 
	for (uint i = 0; i < Tnum_files; i++) {
 
		MD5File *file = &this->files[i];
 
		/* Find the filename first. */
 
		item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
 
		if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
 
			Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
 
			return false;
 
		}
 

	
 
		if (!item->value.has_value()) {
 
			file->filename = nullptr;
 
			file->filename.clear();
 
			/* If we list no file, that file must be valid */
 
			this->valid_files++;
 
			this->found_files++;
 
			continue;
 
		}
 

	
 
		const char *filename = item->value->c_str();
 
		file->filename = str_fmt("%s%s", path, filename);
 
		const std::string &filename = item->value.value();
 
		file->filename = path + filename;
 

	
 
		/* Then find the MD5 checksum */
 
		item = md5s->GetItem(filename, false);
 
		if (item == nullptr || !item->value.has_value()) {
 
			Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
 
			return false;
 
		}
 
		const char *c = item->value->c_str();
 
		for (uint i = 0; i < sizeof(file->hash) * 2; i++, c++) {
 
			uint j;
 
			if ('0' <= *c && *c <= '9') {
 
				j = *c - '0';
 
@@ -113,27 +113,27 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
			if (i % 2 == 0) {
 
				file->hash[i / 2] = j << 4;
 
			} else {
 
				file->hash[i / 2] |= j;
 
			}
 
		}
 

	
 
		/* Then find the warning message when the file's missing */
 
		item = origin->GetItem(filename, false);
 
		if (item == nullptr) item = origin->GetItem("default", false);
 
		if (item == nullptr || !item->value.has_value()) {
 
			Debug(grf, 1, "No origin warning message specified for: {}", filename);
 
			file->missing_warning = stredup("");
 
			file->missing_warning.clear();
 
		} else {
 
			file->missing_warning = stredup(item->value->c_str());
 
			file->missing_warning = item->value.value();
 
		}
 

	
 
		file->check_result = T::CheckMD5(file, BASESET_DIR);
 
		switch (file->check_result) {
 
			case MD5File::CR_UNKNOWN:
 
				break;
 

	
 
			case MD5File::CR_MATCH:
 
				this->valid_files++;
 
				this->found_files++;
 
				break;
 

	
 
@@ -160,25 +160,25 @@ bool BaseMedia<Tbase_set>::AddFile(const
 
	Tbase_set *set = new Tbase_set();
 
	IniFile *ini = new IniFile();
 
	std::string path{ filename, basepath_length };
 
	ini->LoadFromDisk(path, BASESET_DIR);
 

	
 
	auto psep = path.rfind(PATHSEPCHAR);
 
	if (psep != std::string::npos) {
 
		path.erase(psep + 1);
 
	} else {
 
		path.clear();
 
	}
 

	
 
	if (set->FillSetDetails(ini, path.c_str(), filename.c_str())) {
 
	if (set->FillSetDetails(ini, path, filename)) {
 
		Tbase_set *duplicate = nullptr;
 
		for (Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != nullptr; c = c->next) {
 
			if (c->name == set->name || c->shortname == set->shortname) {
 
				duplicate = c;
 
				break;
 
			}
 
		}
 
		if (duplicate != nullptr) {
 
			/* The more complete set takes precedence over the version number. */
 
			if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
 
					duplicate->valid_files > set->valid_files) {
 
				Debug(grf, 1, "Not adding {} ({}) as base " SET_TYPE " set (duplicate, {})", set->name, set->version,
 
@@ -273,34 +273,34 @@ template <class Tbase_set>
 

	
 
	return p;
 
}
 

	
 
#include "network/core/tcp_content_type.h"
 

	
 
template <class Tbase_set> const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s)
 
{
 
	for (; s != nullptr; s = s->next) {
 
		if (s->GetNumMissing() != 0) continue;
 

	
 
		if (s->shortname != ci->unique_id) continue;
 
		if (!md5sum) return  s->files[0].filename;
 
		if (!md5sum) return s->files[0].filename.c_str();
 

	
 
		byte md5[16];
 
		memset(md5, 0, sizeof(md5));
 
		for (uint i = 0; i < Tbase_set::NUM_FILES; i++) {
 
			for (uint j = 0; j < sizeof(md5); j++) {
 
				md5[j] ^= s->files[i].hash[j];
 
			}
 
		}
 
		if (memcmp(md5, ci->md5sum, sizeof(md5)) == 0) return s->files[0].filename;
 
		if (memcmp(md5, ci->md5sum, sizeof(md5)) == 0) return s->files[0].filename.c_str();
 
	}
 
	return nullptr;
 
}
 

	
 
template <class Tbase_set>
 
/* static */ bool BaseMedia<Tbase_set>::HasSet(const ContentInfo *ci, bool md5sum)
 
{
 
	return (TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::available_sets) != nullptr) ||
 
			(TryGetBaseSetFile(ci, md5sum, BaseMedia<Tbase_set>::duplicate_sets) != nullptr);
 
}
 

	
 
/**
src/fileio.cpp
Show inline comments
 
@@ -131,25 +131,25 @@ bool FileExists(const std::string &filen
 
 */
 
void FioFCloseFile(FILE *f)
 
{
 
	fclose(f);
 
}
 

	
 
/**
 
 * Find a path to the filename in one of the search directories.
 
 * @param subdir Subdirectory to try.
 
 * @param filename Filename to look for.
 
 * @return String containing the path if the path was found, else an empty string.
 
 */
 
std::string FioFindFullPath(Subdirectory subdir, const char *filename)
 
std::string FioFindFullPath(Subdirectory subdir, const std::string &filename)
 
{
 
	assert(subdir < NUM_SUBDIRS);
 

	
 
	for (Searchpath sp : _valid_searchpaths) {
 
		std::string buf = FioGetDirectory(sp, subdir);
 
		buf += filename;
 
		if (FileExists(buf)) return buf;
 
#if !defined(_WIN32)
 
		/* Be, as opening files, aware that sometimes the filename
 
		 * might be in uppercase when it is in lowercase on the
 
		 * disk. Of course Windows doesn't care about casing. */
 
		if (strtolower(buf, _searchpaths[sp].size() - 1) && FileExists(buf)) return buf;
src/fileio_func.h
Show inline comments
 
@@ -9,25 +9,25 @@
 

	
 
#ifndef FILEIO_FUNC_H
 
#define FILEIO_FUNC_H
 

	
 
#include "core/enum_type.hpp"
 
#include "fileio_type.h"
 
#include <string>
 
#include <vector>
 

	
 
void FioFCloseFile(FILE *f);
 
FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize = nullptr);
 
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir);
 
std::string FioFindFullPath(Subdirectory subdir, const char *filename);
 
std::string FioFindFullPath(Subdirectory subdir, const std::string &filename);
 
std::string FioGetDirectory(Searchpath sp, Subdirectory subdir);
 
std::string FioFindDirectory(Subdirectory subdir);
 
void FioCreateDirectory(const std::string &name);
 

	
 
const char *FiosGetScreenshotDir();
 

	
 
void SanitizeFilename(char *filename);
 
void AppendPathSeparator(std::string &buf);
 
void DeterminePaths(const char *exe, bool only_local_path);
 
std::unique_ptr<char[]> ReadFileToMem(const std::string &filename, size_t &lenp, size_t maxsize);
 
bool FileExists(const std::string &filename);
 
bool ExtractTar(const std::string &tar_filename, Subdirectory subdir);
src/gfxinit.cpp
Show inline comments
 
@@ -33,35 +33,35 @@ static const SpriteID * const _landscape
 
	_landscape_spriteindexes_arctic,
 
	_landscape_spriteindexes_tropic,
 
	_landscape_spriteindexes_toyland,
 
};
 

	
 
/**
 
 * Load an old fashioned GRF file.
 
 * @param filename   The name of the file to open.
 
 * @param load_index The offset of the first sprite.
 
 * @param needs_palette_remap Whether the colours in the GRF file need a palette remap.
 
 * @return The number of loaded sprites.
 
 */
 
static uint LoadGrfFile(const char *filename, uint load_index, bool needs_palette_remap)
 
static uint LoadGrfFile(const std::string &filename, uint load_index, bool needs_palette_remap)
 
{
 
	uint load_index_org = load_index;
 
	uint sprite_id = 0;
 

	
 
	SpriteFile &file = OpenCachedSpriteFile(filename, BASESET_DIR, needs_palette_remap);
 

	
 
	Debug(sprite, 2, "Reading grf-file '{}'", filename);
 

	
 
	byte container_ver = file.GetContainerVersion();
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename);
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename.c_str());
 
	ReadGRFSpriteOffsets(file);
 
	if (container_ver >= 2) {
 
		/* Read compression. */
 
		byte compression = file.ReadByte();
 
		if (compression != 0) usererror("Unsupported compression format");
 
	}
 

	
 
	while (LoadNextSprite(load_index, file, sprite_id)) {
 
		load_index++;
 
		sprite_id++;
 
		if (load_index >= MAX_SPRITES) {
 
			usererror("Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
 
@@ -70,35 +70,35 @@ static uint LoadGrfFile(const char *file
 
	Debug(sprite, 2, "Currently {} sprites are loaded", load_index);
 

	
 
	return load_index - load_index_org;
 
}
 

	
 
/**
 
 * Load an old fashioned GRF file to replace already loaded sprites.
 
 * @param filename   The name of the file to open.
 
 * @param index_tbl  The offsets of each of the sprites.
 
 * @param needs_palette_remap Whether the colours in the GRF file need a palette remap.
 
 * @return The number of loaded sprites.
 
 */
 
static void LoadGrfFileIndexed(const char *filename, const SpriteID *index_tbl, bool needs_palette_remap)
 
static void LoadGrfFileIndexed(const std::string &filename, const SpriteID *index_tbl, bool needs_palette_remap)
 
{
 
	uint start;
 
	uint sprite_id = 0;
 

	
 
	SpriteFile &file = OpenCachedSpriteFile(filename, BASESET_DIR, needs_palette_remap);
 

	
 
	Debug(sprite, 2, "Reading indexed grf-file '{}'", filename);
 

	
 
	byte container_ver = file.GetContainerVersion();
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename);
 
	if (container_ver == 0) usererror("Base grf '%s' is corrupt", filename.c_str());
 
	ReadGRFSpriteOffsets(file);
 
	if (container_ver >= 2) {
 
		/* Read compression. */
 
		byte compression = file.ReadByte();
 
		if (compression != 0) usererror("Unsupported compression format");
 
	}
 

	
 
	while ((start = *index_tbl++) != END) {
 
		uint end = *index_tbl++;
 

	
 
		do {
 
			[[maybe_unused]] bool b = LoadNextSprite(start, file, sprite_id);
 
@@ -128,37 +128,37 @@ void CheckExternalFiles()
 
	 * message per set.
 
	 */
 
	char error_msg[MISSING_FILE_MESSAGE_LENGTH * (GraphicsSet::NUM_FILES + SoundsSet::NUM_FILES) + 2 * ERROR_MESSAGE_LENGTH];
 
	error_msg[0] = '\0';
 
	char *add_pos = error_msg;
 
	const char *last = lastof(error_msg);
 

	
 
	if (used_set->GetNumInvalid() != 0) {
 
		/* Not all files were loaded successfully, see which ones */
 
		add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->name.c_str());
 
		for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) {
 
			MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR);
 
			if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
 
			if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename.c_str(), res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning.c_str());
 
		}
 
		add_pos += seprintf(add_pos, last, "\n");
 
	}
 

	
 
	const SoundsSet *sounds_set = BaseSounds::GetUsedSet();
 
	if (sounds_set->GetNumInvalid() != 0) {
 
		add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->name.c_str());
 

	
 
		static_assert(SoundsSet::NUM_FILES == 1);
 
		/* No need to loop each file, as long as there is only a single
 
		 * sound file. */
 
		add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename, SoundsSet::CheckMD5(sounds_set->files, BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning);
 
		add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename.c_str(), SoundsSet::CheckMD5(sounds_set->files, BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning.c_str());
 
	}
 

	
 
	if (add_pos != error_msg) ShowInfoI(error_msg);
 
}
 

	
 
/** Actually load the sprite tables. */
 
static void LoadSpriteTables()
 
{
 
	const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
 

	
 
	LoadGrfFile(used_set->files[GFT_BASE].filename, 0, PAL_DOS != used_set->palette);
 

	
 
@@ -192,25 +192,25 @@ static void LoadSpriteTables()
 
	 * so we have to manually add it, and then remove it later.
 
	 */
 
	GRFConfig *top = _grfconfig;
 

	
 
	/* Default extra graphics */
 
	static const char *master_filename = "OPENTTD.GRF";
 
	GRFConfig *master = new GRFConfig(master_filename);
 
	master->palette |= GRFP_GRF_DOS;
 
	FillGRFDetails(master, false, BASESET_DIR);
 
	ClrBit(master->flags, GCF_INIT_ONLY);
 

	
 
	/* Baseset extra graphics */
 
	GRFConfig *extra = new GRFConfig(used_set->files[GFT_EXTRA].filename);
 
	GRFConfig *extra = new GRFConfig(used_set->files[GFT_EXTRA].filename.c_str());
 

	
 
	/* We know the palette of the base set, so if the base NewGRF is not
 
	 * setting one, use the palette of the base set and not the global
 
	 * one which might be the wrong palette for this base NewGRF.
 
	 * The value set here might be overridden via action14 later. */
 
	switch (used_set->palette) {
 
		case PAL_DOS:     extra->palette |= GRFP_GRF_DOS;     break;
 
		case PAL_WINDOWS: extra->palette |= GRFP_GRF_WINDOWS; break;
 
		default: break;
 
	}
 
	FillGRFDetails(extra, false, BASESET_DIR);
 
	ClrBit(extra->flags, GCF_INIT_ONLY);
 
@@ -346,25 +346,25 @@ void GfxLoadSprites()
 
	Debug(sprite, 2, "Loading sprite set {}", _settings_game.game_creation.landscape);
 

	
 
	SwitchNewGRFBlitter();
 
	VideoDriver::GetInstance()->ClearSystemSprites();
 
	ClearFontCache();
 
	GfxInitSpriteMem();
 
	LoadSpriteTables();
 
	GfxInitPalettes();
 

	
 
	UpdateCursorSize();
 
}
 

	
 
bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename)
 
bool GraphicsSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename)
 
{
 
	bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false);
 
	if (ret) {
 
		IniGroup *metadata = ini->GetGroup("metadata");
 
		IniItem *item;
 

	
 
		fetch_metadata("palette");
 
		this->palette = ((*item->value)[0] == 'D' || (*item->value)[0] == 'd') ? PAL_DOS : PAL_WINDOWS;
 

	
 
		/* Get optional blitter information. */
 
		item = metadata->GetItem("blitter", false);
 
		this->blitter = (item != nullptr && (*item->value)[0] == '3') ? BLT_32BPP : BLT_8BPP;
src/music.cpp
Show inline comments
 
@@ -16,25 +16,25 @@
 

	
 
#include "safeguards.h"
 
#include "random_access_file_type.h"
 

	
 

	
 
/**
 
 * Read the name of a music CAT file entry.
 
 * @param filename Name of CAT file to read from
 
 * @param entrynum Index of entry whose name to read
 
 * @return Pointer to string, caller is responsible for freeing memory,
 
 *         nullptr if entrynum does not exist.
 
 */
 
char *GetMusicCatEntryName(const char *filename, size_t entrynum)
 
char *GetMusicCatEntryName(const std::string &filename, size_t entrynum)
 
{
 
	if (!FioCheckFileExists(filename, BASESET_DIR)) return nullptr;
 

	
 
	RandomAccessFile file(filename, BASESET_DIR);
 
	uint32 ofs = file.ReadDword();
 
	size_t entry_count = ofs / 8;
 
	if (entrynum < entry_count) {
 
		file.SeekTo(entrynum * 8, SEEK_SET);
 
		file.SeekTo(file.ReadDword(), SEEK_SET);
 
		byte namelen = file.ReadByte();
 
		char *name = MallocT<char>(namelen + 1);
 
		file.ReadBlock(name, namelen);
 
@@ -43,25 +43,25 @@ char *GetMusicCatEntryName(const char *f
 
	}
 
	return nullptr;
 
}
 

	
 
/**
 
 * Read the full data of a music CAT file entry.
 
 * @param filename Name of CAT file to read from.
 
 * @param entrynum Index of entry to read
 
 * @param[out] entrylen Receives length of data read
 
 * @return Pointer to buffer with data read, caller is responsible for freeind memory,
 
 *         nullptr if entrynum does not exist.
 
 */
 
byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entrylen)
 
byte *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen)
 
{
 
	entrylen = 0;
 
	if (!FioCheckFileExists(filename, BASESET_DIR)) return nullptr;
 

	
 
	RandomAccessFile file(filename, BASESET_DIR);
 
	uint32 ofs = file.ReadDword();
 
	size_t entry_count = ofs / 8;
 
	if (entrynum < entry_count) {
 
		file.SeekTo(entrynum * 8, SEEK_SET);
 
		size_t entrypos = file.ReadDword();
 
		entrylen = file.ReadDword();
 
		file.SeekTo(entrypos, SEEK_SET);
 
@@ -107,58 +107,58 @@ template <class Tbase_set>
 
				(best->fallback && !c->fallback) ||
 
				best->valid_files < c->valid_files ||
 
				(best->valid_files == c->valid_files &&
 
					(best->shortname == c->shortname && best->version < c->version))) {
 
			best = c;
 
		}
 
	}
 

	
 
	BaseMedia<Tbase_set>::used_set = best;
 
	return BaseMedia<Tbase_set>::used_set != nullptr;
 
}
 

	
 
bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename)
 
bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename)
 
{
 
	bool ret = this->BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false>::FillSetDetails(ini, path, full_filename);
 
	if (ret) {
 
		this->num_available = 0;
 
		IniGroup *names = ini->GetGroup("names");
 
		IniGroup *catindex = ini->GetGroup("catindex");
 
		IniGroup *timingtrim = ini->GetGroup("timingtrim");
 
		uint tracknr = 1;
 
		for (uint i = 0; i < lengthof(this->songinfo); i++) {
 
			const char *filename = this->files[i].filename;
 
			if (names == nullptr || StrEmpty(filename) || this->files[i].check_result == MD5File::CR_NO_FILE) {
 
			const std::string &filename = this->files[i].filename;
 
			if (filename.empty() || this->files[i].check_result == MD5File::CR_NO_FILE) {
 
				continue;
 
			}
 

	
 
			this->songinfo[i].filename = filename; // non-owned pointer
 

	
 
			IniItem *item = catindex->GetItem(_music_file_names[i], false);
 
			if (item != nullptr && item->value.has_value() && !item->value->empty()) {
 
				/* Song has a CAT file index, assume it's MPS MIDI format */
 
				this->songinfo[i].filetype = MTT_MPSMIDI;
 
				this->songinfo[i].cat_index = atoi(item->value->c_str());
 
				char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index);
 
				if (songname == nullptr) {
 
					Debug(grf, 0, "Base music set song missing from CAT file: {}/{}", filename, this->songinfo[i].cat_index);
 
					continue;
 
				}
 
				this->songinfo[i].songname = songname;
 
				free(songname);
 
			} else {
 
				this->songinfo[i].filetype = MTT_STANDARDMIDI;
 
			}
 

	
 
			const char *trimmed_filename = filename;
 
			const char *trimmed_filename = filename.c_str();
 
			/* As we possibly add a path to the filename and we compare
 
			 * on the filename with the path as in the .obm, we need to
 
			 * keep stripping path elements until we find a match. */
 
			for (; trimmed_filename != nullptr; trimmed_filename = strchr(trimmed_filename, PATHSEPCHAR)) {
 
				/* Remove possible double path separator characters from
 
				 * the beginning, so we don't start reading e.g. root. */
 
				while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++;
 

	
 
				item = names->GetItem(trimmed_filename, false);
 
				if (item != nullptr && item->value.has_value() && !item->value->empty()) break;
 
			}
 

	
src/music/midifile.cpp
Show inline comments
 
@@ -840,25 +840,25 @@ const byte MpsMachine::programvelocities
 
bool MidiFile::LoadMpsData(const byte *data, size_t length)
 
{
 
	_midifile_instance = this;
 

	
 
	MpsMachine machine(data, length, *this);
 
	return machine.PlayInto() && FixupMidiData(*this);
 
}
 

	
 
bool MidiFile::LoadSong(const MusicSongInfo &song)
 
{
 
	switch (song.filetype) {
 
		case MTT_STANDARDMIDI:
 
			return this->LoadFile(song.filename);
 
			return this->LoadFile(song.filename.c_str());
 
		case MTT_MPSMIDI:
 
		{
 
			size_t songdatalen = 0;
 
			byte *songdata = GetMusicCatEntryData(song.filename, song.cat_index, songdatalen);
 
			if (songdata != nullptr) {
 
				bool result = this->LoadMpsData(songdata, songdatalen);
 
				free(songdata);
 
				return result;
 
			} else {
 
				return false;
 
			}
 
		}
 
@@ -1051,27 +1051,27 @@ std::string MidiFile::GetSMFFile(const M
 
		std::string filename = FioFindFullPath(Subdirectory::BASESET_DIR, song.filename);
 
		if (!filename.empty()) return filename;
 
		filename = FioFindFullPath(Subdirectory::OLD_GM_DIR, song.filename);
 
		if (!filename.empty()) return filename;
 

	
 
		return std::string();
 
	}
 

	
 
	if (song.filetype != MTT_MPSMIDI) return std::string();
 

	
 
	char basename[MAX_PATH];
 
	{
 
		const char *fnstart = strrchr(song.filename, PATHSEPCHAR);
 
		const char *fnstart = strrchr(song.filename.c_str(), PATHSEPCHAR);
 
		if (fnstart == nullptr) {
 
			fnstart = song.filename;
 
			fnstart = song.filename.c_str();
 
		} else {
 
			fnstart++;
 
		}
 

	
 
		/* Remove all '.' characters from filename */
 
		char *wp = basename;
 
		for (const char *rp = fnstart; *rp != '\0'; rp++) {
 
			if (*rp != '.') *wp++ = *rp;
 
		}
 
		*wp++ = '\0';
 
	}
 

	
src/sound.cpp
Show inline comments
 
@@ -14,36 +14,36 @@
 
#include "random_access_file_type.h"
 
#include "window_gui.h"
 
#include "vehicle_base.h"
 

	
 
/* The type of set we're replacing */
 
#define SET_TYPE "sounds"
 
#include "base_media_func.h"
 

	
 
#include "safeguards.h"
 

	
 
static SoundEntry _original_sounds[ORIGINAL_SAMPLE_COUNT];
 

	
 
static void OpenBankFile(const char *filename)
 
static void OpenBankFile(const std::string &filename)
 
{
 
	/**
 
	 * The sound file for the original sounds, i.e. those not defined/overridden by a NewGRF.
 
	 * Needs to be kept alive during the game as _original_sounds[n].file refers to this.
 
	 */
 
	static std::unique_ptr<RandomAccessFile> original_sound_file;
 

	
 
	memset(_original_sounds, 0, sizeof(_original_sounds));
 

	
 
	/* If there is no sound file (nosound set), don't load anything */
 
	if (filename == nullptr) return;
 
	if (filename.empty()) return;
 

	
 
	original_sound_file.reset(new RandomAccessFile(filename, BASESET_DIR));
 
	size_t pos = original_sound_file->GetPos();
 
	uint count = original_sound_file->ReadDword();
 

	
 
	/* The new format has the highest bit always set */
 
	bool new_format = HasBit(count, 31);
 
	ClrBit(count, 31);
 
	count /= 8;
 

	
 
	/* Simple check for the correct number of original sounds. */
 
	if (count != ORIGINAL_SAMPLE_COUNT) {
0 comments (0 inline, 0 general)