From ba1779b978bb9640e278113c642b51517658c32f Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 12 Jan 2014 18:00:39 +0000 Subject: [PATCH] (svn r26241) -Codechange: Remember the GRFFile which filled the TextRefStack in the TextRefStack. --- src/build_vehicle_gui.cpp | 7 ++++--- src/command.cpp | 8 +++++--- src/command_type.h | 22 +++++++++++++++++----- src/error.h | 7 +++++-- src/error_gui.cpp | 19 +++++++++++-------- src/industry_gui.cpp | 6 +++--- src/newgrf_commons.cpp | 2 +- src/newgrf_commons.h | 2 -- src/newgrf_text.cpp | 18 ++++++++++++++---- src/newgrf_text.h | 2 +- src/object_gui.cpp | 2 +- 11 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 4e5a738178..0719f29ec6 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -772,13 +772,14 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine) { uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, NULL); if (callback == CALLBACK_FAILED || callback == 0x400) return y; + const GRFFile *grffile = Engine::Get(engine)->GetGRF(); if (callback > 0x400) { - ErrorUnknownCallbackResult(Engine::Get(engine)->GetGRFID(), CBID_VEHICLE_ADDITIONAL_TEXT, callback); + ErrorUnknownCallbackResult(grffile->grfid, CBID_VEHICLE_ADDITIONAL_TEXT, callback); return y; } - StartTextRefStackUsage(6); - uint result = DrawStringMultiLine(left, right, y, INT32_MAX, GetGRFStringID(Engine::Get(engine)->GetGRFID(), 0xD000 + callback), TC_BLACK); + StartTextRefStackUsage(grffile, 6); + uint result = DrawStringMultiLine(left, right, y, INT32_MAX, GetGRFStringID(grffile->grfid, 0xD000 + callback), TC_BLACK); StopTextRefStackUsage(); return result; } diff --git a/src/command.cpp b/src/command.cpp index fe44dabde8..543db30a1d 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -571,7 +571,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac /* Only show the error when it's for us. */ StringID error_part1 = GB(cmd, 16, 16); if (estimate_only || (IsLocalCompany() && error_part1 != 0 && my_cmd)) { - ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackSize(), res.GetTextRefStack()); + ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); } } else if (estimate_only) { ShowEstimatedCostOrIncome(res.GetCost(), x, y); @@ -779,13 +779,15 @@ uint32 CommandCost::textref_stack[16]; /** * Activate usage of the NewGRF #TextRefStack for the error message. - * @param number of entries to copy from the temporary NewGRF registers + * @param grffile NewGRF that provides the #TextRefStack + * @param num_registers number of entries to copy from the temporary NewGRF registers */ -void CommandCost::UseTextRefStack(uint num_registers) +void CommandCost::UseTextRefStack(const GRFFile *grffile, uint num_registers) { extern TemporaryStorageArray _temp_store; assert(num_registers < lengthof(textref_stack)); + this->textref_stack_grffile = grffile; this->textref_stack_size = num_registers; for (uint i = 0; i < num_registers; i++) { textref_stack[i] = _temp_store.GetValue(0x100 + i); diff --git a/src/command_type.h b/src/command_type.h index 6e3ccd3ae8..d1c328e4c7 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -16,6 +16,8 @@ #include "strings_type.h" #include "tile_type.h" +struct GRFFile; + /** * Common return value for all commands. Wraps the cost and * a possible error message/state together. @@ -25,6 +27,7 @@ class CommandCost { Money cost; ///< The cost of this action StringID message; ///< Warning message for when success is unset bool success; ///< Whether the comment went fine up to this moment + const GRFFile *textref_stack_grffile; ///< NewGRF providing the #TextRefStack content. uint textref_stack_size; ///< Number of uint32 values to put on the #TextRefStack for the error message. static uint32 textref_stack[16]; @@ -33,25 +36,25 @@ public: /** * Creates a command cost return with no cost and no error */ - CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_size(0) {} + CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} /** * Creates a command return value the is failed with the given message */ - explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_size(0) {} + explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(NULL), textref_stack_size(0) {} /** * Creates a command cost with given expense type and start cost of 0 * @param ex_t the expense type */ - explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_size(0) {} + explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} /** * Creates a command return value with the given start cost and expense type * @param ex_t the expense type * @param cst the initial cost of this command */ - CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_size(0) {} + CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} /** @@ -103,7 +106,16 @@ public: this->message = message; } - void UseTextRefStack(uint num_registers); + void UseTextRefStack(const GRFFile *grffile, uint num_registers); + + /** + * Returns the NewGRF providing the #TextRefStack of the error message. + * @return the NewGRF. + */ + const GRFFile *GetTextRefStackGRF() const + { + return this->textref_stack_grffile; + } /** * Returns the number of uint32 values for the #TextRefStack of the error message. diff --git a/src/error.h b/src/error.h index 4a78a07aab..597b62efbe 100644 --- a/src/error.h +++ b/src/error.h @@ -16,6 +16,8 @@ #include "company_type.h" #include "core/geometry_type.hpp" +struct GRFFile; + /** Message severity/type */ enum WarningLevel { WL_INFO, ///< Used for DoCommand-like (and some non-fatal AI GUI) errors/information @@ -30,6 +32,7 @@ protected: uint duration; ///< Length of display of the message. 0 means forever, uint64 decode_params[20]; ///< Parameters of the message strings. const char *strings[20]; ///< Copies of raw strings that were used. + const GRFFile *textref_stack_grffile; ///< NewGRF that filled the #TextRefStack for the error message. uint textref_stack_size; ///< Number of uint32 values to put on the #TextRefStack for the error message. uint32 textref_stack[16]; ///< Values to put on the #TextRefStack for the error message. StringID summary_msg; ///< General error message showed in first line. Must be valid. @@ -40,7 +43,7 @@ protected: public: ErrorMessageData(const ErrorMessageData &data); ~ErrorMessageData(); - ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); + ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); /** Check whether error window shall display a company manager face */ bool HasFace() const { return face != INVALID_COMPANY; } @@ -53,7 +56,7 @@ public: void ScheduleErrorMessage(const ErrorMessageData &data); -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); void ClearErrorMessages(); void ShowFirstError(); void UnshowCriticalError(); diff --git a/src/error_gui.cpp b/src/error_gui.cpp index b498cff63e..5e8f52432d 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -94,11 +94,13 @@ ErrorMessageData::~ErrorMessageData() * @param duration The amount of time to show this error message. * @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. * @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. + * @param textref_stack_grffile NewGRF that provides the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. */ -ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, uint textref_stack_size, const uint32 *textref_stack) : +ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) : duration(duration), + textref_stack_grffile(textref_stack_grffile), textref_stack_size(textref_stack_size), summary_msg(summary_msg), detailed_msg(detailed_msg), @@ -126,7 +128,7 @@ void ErrorMessageData::CopyOutDParams() memset(this->strings, 0, sizeof(this->strings)); /* Get parameters using type information */ - if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_size, this->textref_stack); + if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); CopyOutDParam(this->decode_params, this->strings, this->detailed_msg == INVALID_STRING_ID ? this->summary_msg : this->detailed_msg, lengthof(this->decode_params)); if (this->textref_stack_size > 0) StopTextRefStackUsage(); @@ -181,7 +183,7 @@ public: if (widget != WID_EM_MESSAGE) return; CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); - if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_size, this->textref_stack); + if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); int text_width = max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); this->height_summary = GetStringHeight(this->summary_msg, text_width); @@ -253,7 +255,7 @@ public: case WID_EM_MESSAGE: CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); - if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_size, this->textref_stack); + if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); if (this->detailed_msg == INVALID_STRING_ID) { DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, @@ -358,19 +360,20 @@ void UnshowCriticalError() * @param wl Message severity. * @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. * @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. + * @param textref_stack_grffile NewGRF providing the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. */ -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, uint textref_stack_size, const uint32 *textref_stack) +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) { - assert(textref_stack_size == 0 || textref_stack != NULL); + assert(textref_stack_size == 0 || (textref_stack_grffile != NULL && textref_stack != NULL)); if (summary_msg == STR_NULL) summary_msg = STR_EMPTY; if (wl != WL_INFO) { /* Print message to console */ char buf[DRAW_STRING_BUFFER]; - if (textref_stack_size > 0) StartTextRefStackUsage(textref_stack_size, textref_stack); + if (textref_stack_size > 0) StartTextRefStackUsage(textref_stack_grffile, textref_stack_size, textref_stack); char *b = GetString(buf, summary_msg, lastof(buf)); if (detailed_msg != INVALID_STRING_ID) { @@ -390,7 +393,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return; - ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_size, textref_stack); + ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack); data.CopyOutDParams(); ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index b21ab70ca0..cc305509f2 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -79,7 +79,7 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind, if (callback > 0x400) { ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_CARGO_SUFFIX, callback); } else if (indspec->grf_prop.grffile->grf_version >= 8 || GB(callback, 0, 8) != 0xFF) { - StartTextRefStackUsage(6); + StartTextRefStackUsage(indspec->grf_prop.grffile, 6); GetString(suffix, GetGRFStringID(indspec->grf_prop.grffile->grfid, 0xD000 + callback), suffix_last); StopTextRefStackUsage(); } @@ -471,7 +471,7 @@ public: } else { str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string if (str != STR_UNDEFINED) { - StartTextRefStackUsage(6); + StartTextRefStackUsage(indsp->grf_prop.grffile, 6); DrawStringMultiLine(left, right, y, bottom, str, TC_YELLOW); StopTextRefStackUsage(); } @@ -800,7 +800,7 @@ public: if (message != STR_NULL && message != STR_UNDEFINED) { y += WD_PAR_VSEP_WIDE; - StartTextRefStackUsage(6); + StartTextRefStackUsage(ind->grf_prop.grffile, 6); /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */ diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 81228866df..ef75be5d8c 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -501,7 +501,7 @@ CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, const GRFFi } /* Copy some parameters from the registers to the error message text ref. stack */ - res.UseTextRefStack(4); + res.UseTextRefStack(grffile, 4); return res; } diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index a9cc506591..4202c18dbe 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -22,8 +22,6 @@ #include "direction_type.h" #include "company_type.h" -struct GRFFile; - /** Context for tile accesses */ enum TileContext { TCX_NORMAL, ///< Nothing special. diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 81dd1654b7..ffdb3db3c8 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -880,12 +880,14 @@ void CleanUpStrings() struct TextRefStack { byte stack[0x30]; byte position; + const GRFFile *grffile; bool used; - TextRefStack() : position(0), used(false) {} + TextRefStack() : position(0), grffile(NULL), used(false) {} TextRefStack(const TextRefStack &stack) : position(stack.position), + grffile(stack.grffile), used(stack.used) { memcpy(this->stack, stack.stack, sizeof(this->stack)); @@ -937,7 +939,14 @@ struct TextRefStack { this->stack[this->position + 1] = GB(word, 8, 8); } - void ResetStack() { this->position = 0; this->used = true; } + void ResetStack(const GRFFile *grffile) + { + assert(grffile != NULL); + this->position = 0; + this->grffile = grffile; + this->used = true; + } + void RewindStack() { this->position = 0; } }; @@ -986,14 +995,15 @@ void RestoreTextRefStackBackup(struct TextRefStack *backup) * by calling #StopTextRefStackUsage(), so NewGRF string codes operate on the * normal string parameters again. * + * @param grffile the NewGRF providing the stack data * @param numEntries number of entries to copy from the registers * @param values values to copy onto the stack; if NULL the temporary NewGRF registers will be used instead */ -void StartTextRefStackUsage(byte numEntries, const uint32 *values) +void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values) { extern TemporaryStorageArray _temp_store; - _newgrf_textrefstack.ResetStack(); + _newgrf_textrefstack.ResetStack(grffile); byte *p = _newgrf_textrefstack.stack; for (uint i = 0; i < numEntries; i++) { diff --git a/src/newgrf_text.h b/src/newgrf_text.h index 4b7f4e2df1..78e0b8ca55 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -35,7 +35,7 @@ void CleanUpGRFText(struct GRFText *grftext); bool CheckGrfLangID(byte lang_id, byte grf_version); -void StartTextRefStackUsage(byte numEntries, const uint32 *values = NULL); +void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values = NULL); void StopTextRefStackUsage(); void RewindTextRefStack(); bool UsingNewGRFTextStack(); diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 3bd3798877..29a9d0d5ef 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -286,7 +286,7 @@ public: } else { StringID message = GetGRFStringID(spec->grf_prop.grffile->grfid, 0xD000 + callback_res); if (message != STR_NULL && message != STR_UNDEFINED) { - StartTextRefStackUsage(6); + StartTextRefStackUsage(spec->grf_prop.grffile, 6); /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */