Changeset - r21155:4f83de14e882
[Not reviewed]
master
0 11 0
frosch - 11 years ago 2014-01-12 18:00:39
frosch@openttd.org
(svn r26241) -Codechange: Remember the GRFFile which filled the TextRefStack in the TextRefStack.
11 files changed with 62 insertions and 33 deletions:
0 comments (0 inline, 0 general)
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -772,13 +772,14 @@ static uint ShowAdditionalText(int left,
 
{
 
	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;
 
}
src/command.cpp
Show inline comments
 
@@ -571,7 +571,7 @@ bool DoCommandP(TileIndex tile, uint32 p
 
		/* 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<int32, 0x110> _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);
src/command_type.h
Show inline comments
 
@@ -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.
src/error.h
Show inline comments
 
@@ -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();
src/error_gui.cpp
Show inline comments
 
@@ -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_m
 

	
 
	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);
src/industry_gui.cpp
Show inline comments
 
@@ -79,7 +79,7 @@ static void GetCargoSuffix(uint cargo, C
 
		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. */
src/newgrf_commons.cpp
Show inline comments
 
@@ -501,7 +501,7 @@ CommandCost GetErrorMessageFromLocationC
 
	}
 

	
 
	/* Copy some parameters from the registers to the error message text ref. stack */
 
	res.UseTextRefStack(4);
 
	res.UseTextRefStack(grffile, 4);
 

	
 
	return res;
 
}
src/newgrf_commons.h
Show inline comments
 
@@ -22,8 +22,6 @@
 
#include "direction_type.h"
 
#include "company_type.h"
 

	
 
struct GRFFile;
 

	
 
/** Context for tile accesses */
 
enum TileContext {
 
	TCX_NORMAL,         ///< Nothing special.
src/newgrf_text.cpp
Show inline comments
 
@@ -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 Te
 
 * 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<int32, 0x110> _temp_store;
 

	
 
	_newgrf_textrefstack.ResetStack();
 
	_newgrf_textrefstack.ResetStack(grffile);
 

	
 
	byte *p = _newgrf_textrefstack.stack;
 
	for (uint i = 0; i < numEntries; i++) {
src/newgrf_text.h
Show inline comments
 
@@ -35,7 +35,7 @@ void CleanUpGRFText(struct GRFText *grft
 

	
 
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();
src/object_gui.cpp
Show inline comments
 
@@ -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. */
0 comments (0 inline, 0 general)