Merge remote-tracking branch 'upstream/master'
This commit is contained in:
123
src/gfxinit.cpp
123
src/gfxinit.cpp
@@ -17,6 +17,7 @@
|
||||
#include "blitter/factory.hpp"
|
||||
#include "video/video_driver.hpp"
|
||||
#include "window_func.h"
|
||||
#include "palette_func.h"
|
||||
|
||||
/* The type of set we're replacing */
|
||||
#define SET_TYPE "graphics"
|
||||
@@ -42,7 +43,7 @@ static const SpriteID * const _landscape_spriteindexes[] = {
|
||||
* @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;
|
||||
@@ -52,19 +53,19 @@ static uint LoadGrfFile(const char *filename, uint load_index, bool needs_palett
|
||||
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 '{}' is corrupt", filename);
|
||||
ReadGRFSpriteOffsets(file);
|
||||
if (container_ver >= 2) {
|
||||
/* Read compression. */
|
||||
byte compression = file.ReadByte();
|
||||
if (compression != 0) usererror("Unsupported compression format");
|
||||
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.");
|
||||
UserError("Too many sprites. Recompile with higher MAX_SPRITES value or remove some custom GRF files.");
|
||||
}
|
||||
}
|
||||
Debug(sprite, 2, "Currently {} sprites are loaded", load_index);
|
||||
@@ -79,7 +80,7 @@ static uint LoadGrfFile(const char *filename, uint load_index, bool needs_palett
|
||||
* @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;
|
||||
@@ -89,12 +90,12 @@ static void LoadGrfFileIndexed(const char *filename, const SpriteID *index_tbl,
|
||||
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 '{}' is corrupt", filename);
|
||||
ReadGRFSpriteOffsets(file);
|
||||
if (container_ver >= 2) {
|
||||
/* Read compression. */
|
||||
byte compression = file.ReadByte();
|
||||
if (compression != 0) usererror("Unsupported compression format");
|
||||
if (compression != 0) UserError("Unsupported compression format");
|
||||
}
|
||||
|
||||
while ((start = *index_tbl++) != END) {
|
||||
@@ -121,38 +122,29 @@ void CheckExternalFiles()
|
||||
|
||||
Debug(grf, 1, "Using the {} base graphics set", used_set->name);
|
||||
|
||||
static const size_t ERROR_MESSAGE_LENGTH = 256;
|
||||
static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
|
||||
|
||||
/* Allocate for a message for each missing file and for one error
|
||||
* 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);
|
||||
|
||||
std::string error_msg;
|
||||
auto output_iterator = std::back_inserter(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());
|
||||
fmt::format_to(output_iterator, "Trying to load graphics set '{}', 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);
|
||||
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) fmt::format_to(output_iterator, "\t{} is {} ({})\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
|
||||
}
|
||||
add_pos += seprintf(add_pos, last, "\n");
|
||||
fmt::format_to(output_iterator, "\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());
|
||||
fmt::format_to(output_iterator, "Trying to load sound set '{}', 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);
|
||||
|
||||
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);
|
||||
fmt::format_to(output_iterator, "\t{} is {} ({})\n", sounds_set->files->filename, SoundsSet::CheckMD5(sounds_set->files, BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning);
|
||||
}
|
||||
|
||||
if (add_pos != error_msg) ShowInfoF("%s", error_msg);
|
||||
if (!error_msg.empty()) ShowInfoI(error_msg);
|
||||
}
|
||||
|
||||
/** Actually load the sprite tables. */
|
||||
@@ -202,18 +194,8 @@ static void LoadSpriteTables()
|
||||
ClrBit(master->flags, GCF_INIT_ONLY);
|
||||
|
||||
/* Baseset extra graphics */
|
||||
GRFConfig *extra = new GRFConfig(used_set->files[GFT_EXTRA].filename);
|
||||
|
||||
/* 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);
|
||||
GRFConfig *extra = new GRFConfig(used_set->GetOrCreateExtraConfig());
|
||||
if (extra->num_params == 0) extra->SetParameterDefaults();
|
||||
ClrBit(extra->flags, GCF_INIT_ONLY);
|
||||
|
||||
extra->next = top;
|
||||
@@ -223,6 +205,7 @@ static void LoadSpriteTables()
|
||||
LoadNewGRF(SPR_NEWGRFS_BASE, 2);
|
||||
|
||||
uint total_extra_graphics = SPR_NEWGRFS_BASE - SPR_OPENTTD_BASE;
|
||||
Debug(sprite, 4, "Checking sprites from fallback grf");
|
||||
_missing_extra_graphics = GetSpriteCountForFile(master_filename, SPR_OPENTTD_BASE, SPR_NEWGRFS_BASE);
|
||||
Debug(sprite, 1, "{} extra sprites, {} from baseset, {} from fallback", total_extra_graphics, total_extra_graphics - _missing_extra_graphics, _missing_extra_graphics);
|
||||
|
||||
@@ -249,7 +232,7 @@ static void RealChangeBlitter(const char *repl_blitter)
|
||||
|
||||
if (!VideoDriver::GetInstance()->AfterBlitterChange()) {
|
||||
/* Failed to switch blitter, let's hope we can return to the old one. */
|
||||
if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
|
||||
if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !VideoDriver::GetInstance()->AfterBlitterChange()) UserError("Failed to reinitialize video driver. Specify a fixed blitter in the config");
|
||||
}
|
||||
|
||||
/* Clear caches that might have sprites for another blitter. */
|
||||
@@ -356,23 +339,75 @@ void GfxLoadSprites()
|
||||
UpdateCursorSize();
|
||||
}
|
||||
|
||||
bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename)
|
||||
GraphicsSet::GraphicsSet()
|
||||
: BaseSet<GraphicsSet, MAX_GFT, true>{}, palette{}, blitter{}
|
||||
{
|
||||
// instantiate here, because unique_ptr needs a complete type
|
||||
}
|
||||
|
||||
GraphicsSet::~GraphicsSet()
|
||||
{
|
||||
// instantiate here, because unique_ptr needs a complete type
|
||||
}
|
||||
|
||||
bool GraphicsSet::FillSetDetails(const 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;
|
||||
const IniGroup *metadata = ini.GetGroup("metadata");
|
||||
assert(metadata != nullptr); /* ret can't be true if metadata isn't present. */
|
||||
const 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);
|
||||
item = metadata->GetItem("blitter");
|
||||
this->blitter = (item != nullptr && (*item->value)[0] == '3') ? BLT_32BPP : BLT_8BPP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return configuration for the extra GRF, or lazily create it.
|
||||
* @return NewGRF configuration
|
||||
*/
|
||||
GRFConfig &GraphicsSet::GetOrCreateExtraConfig() const
|
||||
{
|
||||
if (!this->extra_cfg) {
|
||||
this->extra_cfg.reset(new GRFConfig(this->files[GFT_EXTRA].filename));
|
||||
|
||||
/* 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 (this->palette) {
|
||||
case PAL_DOS: this->extra_cfg->palette |= GRFP_GRF_DOS; break;
|
||||
case PAL_WINDOWS: this->extra_cfg->palette |= GRFP_GRF_WINDOWS; break;
|
||||
default: break;
|
||||
}
|
||||
FillGRFDetails(this->extra_cfg.get(), false, BASESET_DIR);
|
||||
}
|
||||
return *this->extra_cfg;
|
||||
}
|
||||
|
||||
bool GraphicsSet::IsConfigurable() const
|
||||
{
|
||||
const GRFConfig &cfg = this->GetOrCreateExtraConfig();
|
||||
/* This check is more strict than the one for NewGRF Settings.
|
||||
* There are no legacy basesets with parameters, but without Action14 */
|
||||
return !cfg.param_info.empty();
|
||||
}
|
||||
|
||||
void GraphicsSet::CopyCompatibleConfig(const GraphicsSet &src)
|
||||
{
|
||||
const GRFConfig *src_cfg = src.GetExtraConfig();
|
||||
if (src_cfg == nullptr || src_cfg->num_params == 0) return;
|
||||
GRFConfig &dest_cfg = this->GetOrCreateExtraConfig();
|
||||
if (dest_cfg.IsCompatible(src_cfg->version)) return;
|
||||
dest_cfg.CopyParams(*src_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and check the MD5 hash of the supplied GRF.
|
||||
* @param file The file get the hash of.
|
||||
@@ -415,8 +450,8 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size)
|
||||
size = std::min(size, max_size);
|
||||
|
||||
Md5 checksum;
|
||||
uint8 buffer[1024];
|
||||
uint8 digest[16];
|
||||
uint8_t buffer[1024];
|
||||
MD5Hash digest;
|
||||
size_t len;
|
||||
|
||||
while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
|
||||
@@ -427,7 +462,7 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size)
|
||||
FioFCloseFile(f);
|
||||
|
||||
checksum.Finish(digest);
|
||||
return memcmp(this->hash, digest, sizeof(this->hash)) == 0 ? CR_MATCH : CR_MISMATCH;
|
||||
return this->hash == digest ? CR_MATCH : CR_MISMATCH;
|
||||
}
|
||||
|
||||
/** Names corresponding to the GraphicsFileType */
|
||||
|
||||
Reference in New Issue
Block a user