diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -20,6 +20,7 @@ #include "network_internal.h" #include "network_udp.h" #include "network_gamelist.h" +#include "../newgrf_text.h" NetworkGameList *_network_game_list = NULL; @@ -175,7 +176,7 @@ void NetworkAfterNewGRFScan() /* Don't know the GRF, so mark game incompatible and the (possibly) * already resolved name for this GRF (another server has sent the * name of the GRF already */ - c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true); + AddGRFTextToList(&c->name, FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true)); c->status = GCS_NOT_FOUND; /* If we miss a file, we're obviously incompatible */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -28,6 +28,7 @@ #include "../company_base.h" #include "../thread/thread.h" #include "../rev.h" +#include "../newgrf_text.h" #include "core/udp.h" @@ -366,11 +367,11 @@ void ClientNetworkUDPSocketHandler::Hand /* Don't know the GRF, so mark game incompatible and the (possibly) * already resolved name for this GRF (another server has sent the * name of the GRF already */ - config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true); + AddGRFTextToList(&config->name, FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true)); config->status = GCS_NOT_FOUND; } else { config->filename = f->filename; - config->name = f->name; + config->name = DuplicateGRFText(f->name); config->info = f->info; } SetBit(config->flags, GCF_COPY); diff --git a/src/newgrf.cpp b/src/newgrf.cpp --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4830,11 +4830,11 @@ static void ScanInfo(ByteReader *buf) if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM); const char *name = buf->ReadString(); - _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name); + AddGRFTextToList(&_cur_grfconfig->name, 0x7F, grfid, name); if (buf->HasData()) { const char *info = buf->ReadString(); - _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info); + AddGRFTextToList(&_cur_grfconfig->info, 0x7F, grfid, info); } /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */ diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -16,6 +16,7 @@ #include "gamelog.h" #include "network/network_func.h" #include "gfx_func.h" +#include "newgrf_text.h" #include "fileio_func.h" #include "fios.h" @@ -45,21 +46,21 @@ GRFConfig::GRFConfig(const GRFConfig &co MemCpyT(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT(this->param, config.param, lengthof(this->param)); if (config.filename != NULL) this->filename = strdup(config.filename); - if (config.name != NULL) this->name = strdup(config.name); - if (config.info != NULL) this->info = strdup(config.info); + this->name = DuplicateGRFText(config.name); + this->info = DuplicateGRFText(config.info); if (config.error != NULL) this->error = new GRFError(*config.error); } /** Cleanup a GRFConfig object. */ GRFConfig::~GRFConfig() { - /* GCF_COPY as in NOT strdupped/alloced the filename, name and info */ + /* GCF_COPY as in NOT strdupped/alloced the filename and info */ if (!HasBit(this->flags, GCF_COPY)) { free(this->filename); - free(this->name); - free(this->info); + CleanUpGRFText(this->info); delete this->error; } + CleanUpGRFText(this->name); } /** @@ -69,8 +70,8 @@ GRFConfig::~GRFConfig() */ const char *GRFConfig::GetName() const { - if (StrEmpty(this->name)) return this->filename; - return this->name; + const char *name = GetGRFStringFromGRFText(this->name); + return StrEmpty(name) ? this->filename : name; } /** @@ -79,7 +80,7 @@ const char *GRFConfig::GetName() const */ const char *GRFConfig::GetDescription() const { - return this->info; + return GetGRFStringFromGRFText(this->info); } GRFConfig *_all_grfs; @@ -349,8 +350,8 @@ compatible_grf: free(c->filename); c->filename = strdup(f->filename); memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum)); - 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->name == NULL) c->name = DuplicateGRFText(f->name); + if (c->info == NULL) c->info = DuplicateGRFText(f->info); c->error = NULL; } } diff --git a/src/newgrf_config.h b/src/newgrf_config.h --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -87,12 +87,12 @@ struct GRFConfig : ZeroedMemoryAllocator GRFConfig(const GRFConfig &config); ~GRFConfig(); - GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs + GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded - char *filename; ///< Filename - either with or without full path - char *name; ///< NOSAVE: GRF name (Action 0x08) - char *info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) - GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) + char *filename; ///< Filename - either with or without full path + struct GRFText *name; ///< NOSAVE: GRF name (Action 0x08) + struct GRFText *info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) + GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) uint8 flags; ///< NOSAVE: GCF_Flags, bitset GRFStatus status; ///< NOSAVE: GRFStatus, enum diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -126,6 +126,16 @@ public: } /** + * Create a copy of this GRFText. + * @param orig the grftext to copy + * @return an exact copy of the given text + */ + static GRFText *Copy(GRFText *orig) + { + return GRFText::New(orig->langid, orig->text); + } + + /** * Helper allocation function to disallow something. * Don't allow simple 'news'; they wouldn't have enough memory. * @param size the amount of space not to allocate @@ -353,6 +363,50 @@ void AddGRFTextToList(GRFText **list, GR } /** + * Add a string to a GRFText list. + * @param list The list where the text should be added to. + * @param langid The language of the new text. + * @param grfid The grfid where this string is defined. + * @param text_to_add The text to add to the list. + * @note All text-codes will be translated. + */ +void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, const char *text_to_add) +{ + char *translatedtext = TranslateTTDPatchCodes(grfid, text_to_add); + GRFText *newtext = GRFText::New(langid, translatedtext); + free(translatedtext); + + AddGRFTextToList(list, newtext); +} + +/** + * Add a GRFText to a GRFText list. The text should not contain any text-codes. + * The text will be added as a 'default language'-text. + * @param list The list where the text should be added to. + * @param text_to_add The text to add to the list. + */ +void AddGRFTextToList(struct GRFText **list, const char *text_to_add) +{ + AddGRFTextToList(list, GRFText::New(0x7F, text_to_add)); +} + +/** + * Create a copy of this GRFText list. + * @param orig The GRFText list to copy. + * @return A duplicate of the given GRFText. + */ +GRFText *DuplicateGRFText(GRFText *orig) +{ + GRFText *newtext = NULL; + GRFText **ptext = &newtext; + for (; orig != NULL; orig = orig->next) { + *ptext = GRFText::Copy(orig); + ptext = &(*ptext)->next; + } + return newtext; +} + +/** * Add the new read string into our structure. */ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, const char *text_to_add, StringID def_string) diff --git a/src/newgrf_text.h b/src/newgrf_text.h --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -16,10 +16,16 @@ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid, bool new_scheme, const char *text_to_add, StringID def_string); StringID GetGRFStringID(uint32 grfid, uint16 stringid); +const char *GetGRFStringFromGRFText(const struct GRFText *text); const char *GetGRFStringPtr(uint16 stringid); void CleanUpStrings(); void SetCurrentGrfLangID(byte language_id); char *TranslateTTDPatchCodes(uint32 grfid, const char *str); +struct GRFText *DuplicateGRFText(struct GRFText *orig); +void AddGRFTextToList(struct GRFText **list, struct GRFText *text_to_add); +void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, const char *text_to_add); +void AddGRFTextToList(struct GRFText **list, const char *text_to_add); +void CleanUpGRFText(struct GRFText *grftext); bool CheckGrfLangID(byte lang_id, byte grf_version);