Changeset - r6139:0128edd33976
[Not reviewed]
master
0 5 0
maedhros - 17 years ago 2007-02-24 16:34:37
maedhros@openttd.org
(svn r8881) -Feature: Allow built-in newgrf error messages to be translated, and load custom error messages properly.
5 files changed with 106 insertions and 35 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2893,18 +2893,28 @@ STR_PERFORMANCE_DETAIL_TOTAL_TIP        
 
STR_NEWGRF_SETTINGS_BUTTON                                      :{BLACK}NewGRF Settings
 
STR_NEWGRF_SETTINGS_CAPTION                                     :{WHITE}NewGRF settings
 
STR_NEWGRF_APPLY_CHANGES                                        :{BLACK}Apply changes
 
STR_NEWGRF_SET_PARAMETERS                                       :{BLACK}Set parameters
 
STR_NEWGRF_TIP                                                  :{BLACK}A list of all the Newgrf sets that you have installed. Click a set to change the settings
 
STR_NEWGRF_NO_FILES_INSTALLED                                   :{BLACK}There are currently no newgrf files installed! Please refer to the manual for instructions on installing new graphics
 
STR_NEWGRF_ERROR_MSG                                            :{RED}{STRING}
 
STR_NEWGRF_FILENAME                                             :{BLACK}Filename: {SILVER}{STRING}
 
STR_NEWGRF_GRF_ID                                               :{BLACK}GRF ID: {SILVER}{STRING}
 
STR_NEWGRF_MD5SUM                                               :{BLACK}MD5sum: {SILVER}{STRING}
 
STR_NEWGRF_CONFIRMATION_TEXT                                    :{YELLOW}You are about to make changes to a running game; this can crash OpenTTD.{}Are you absolutely sure about this?
 

	
 
STR_NEWGRF_ERROR_MSG_INFO                                       :{SILVER}{STRING}
 
STR_NEWGRF_ERROR_MSG_WARNING                                    :{RED}Warning: {SILVER}{STRING}
 
STR_NEWGRF_ERROR_MSG_ERROR                                      :{RED}Error: {SILVER}{STRING}
 
STR_NEWGRF_ERROR_MSG_FATAL                                      :{RED}Fatal: {SILVER}{STRING}
 
STR_NEWGRF_ERROR_VERSION_NUMBER                                 :{STRING} will not work with the TTDPatch version reported by OpenTTD.
 
STR_NEWGRF_ERROR_DOS_OR_WINDOWS                                 :{STRING} is for the {STRING} version of TTD.
 
STR_NEWGRF_ERROR_UNSET_SWITCH                                   :{STRING} is designed to be used with {STRING}
 
STR_NEWGRF_ERROR_INVALID_PARAMETER                              :Invalid parameter for {STRING}: parameter {STRING} ({NUM})
 
STR_NEWGRF_ERROR_LOAD_BEFORE                                    :{STRING} must be loaded before {STRING}.
 
STR_NEWGRF_ERROR_LOAD_AFTER                                     :{STRING} must be loaded after {STRING}.
 

	
 
STR_NEWGRF_ADD                                                  :{BLACK}Add
 
STR_NEWGRF_ADD_TIP                                              :{BLACK}Add a NewGRF file to the list
 
STR_NEWGRF_REMOVE                                               :{BLACK}Remove
 
STR_NEWGRF_REMOVE_TIP                                           :{BLACK}Remove the selected NewGRF file from the list
 
STR_NEWGRF_MOVEUP                                               :{BLACK}Move Up
 
STR_NEWGRF_MOVEUP_TIP                                           :{BLACK}Move the selected NewGRF file up the list
src/newgrf.cpp
Show inline comments
 
@@ -2641,13 +2641,13 @@ static void SpriteReplace(byte *buf, int
 
			_nfo_line++;
 
		}
 
	}
 
}
 

	
 
/* Action 0x0B */
 
static void GRFError(byte *buf, int len)
 
static void GRFLoadError(byte *buf, int len)
 
{
 
	/* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
 
	 *
 
	 * B severity      00: notice, contine loading grf file
 
	 *                 01: warning, continue loading grf file
 
	 *                 02: error, but continue loading grf file, and attempt
 
@@ -2656,78 +2656,111 @@ static void GRFError(byte *buf, int len)
 
	 *                     the future (only when restarting the patch)
 
	 * B language-id   see action 4, use 1F for built-in error messages
 
	 * B message-id    message to show, see below
 
	 * S message       for custom messages (message-id FF), text of the message
 
	 *                 not present for built-in messages.
 
	 * V data          additional data for built-in (or custom) messages
 
	 * B parnum        see action 6, only used with built-in message 03 */
 
	/* TODO: For now we just show the message, sometimes incomplete and never translated. */
 

	
 
	static const char *const msgstr[] = {
 
		"%sRequires at least pseudo-TTDPatch version %s.",
 
		"%sThis file is for %s version of TTD.",
 
		"%sDesigned to be used with %s",
 
		"%sInvalid parameter %s.",
 
		"%sMust be loaded before %s.",
 
		"%sMust be loaded after %s.",
 
		"%s%s"
 
	 * B parnum        parameter numbers to be shown in the message (maximum of 2) */
 

	
 
	static const StringID msgstr[] = {
 
		STR_NEWGRF_ERROR_VERSION_NUMBER,
 
		STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
 
		STR_NEWGRF_ERROR_UNSET_SWITCH,
 
		STR_NEWGRF_ERROR_INVALID_PARAMETER,
 
		STR_NEWGRF_ERROR_LOAD_BEFORE,
 
		STR_NEWGRF_ERROR_LOAD_AFTER
 
	};
 

	
 
	static const char *const sevstr[] = {
 
		"",
 
		"Warning: ",
 
		"Error: ",
 
		"Fatal: ",
 
	static const StringID sevstr[] = {
 
		STR_NEWGRF_ERROR_MSG_INFO,
 
		STR_NEWGRF_ERROR_MSG_WARNING,
 
		STR_NEWGRF_ERROR_MSG_ERROR,
 
		STR_NEWGRF_ERROR_MSG_FATAL
 
	};
 

	
 
	if (!check_length(len, 6, "GRFError")) return;
 
	/* AddGRFString expects the string to be referred to by an id in the newgrf
 
	 * file. Errors messages are never referred to however, so invent ids that
 
	 * are unlikely to be reached in a newgrf file so they don't overwrite
 
	 * anything else. */
 
	enum {
 
		MESSAGE_STRING_ID = MAX_UVALUE(StringID) - 1,
 
		MESSAGE_DATA_ID   = MAX_UVALUE(StringID)
 
	};
 

	
 
	if (!check_length(len, 6, "GRFLoadError")) return;
 

	
 
	/* For now we can only show one message per newgrf file. */
 
	if (_cur_grfconfig->error != NULL) return;
 

	
 
	buf++; /* Skip the action byte. */
 
	byte severity   = grf_load_byte(&buf);
 
	buf++; /* TODO: Language id. */
 
	byte lang       = grf_load_byte(&buf);
 
	byte message_id = grf_load_byte(&buf);
 
	len -= 4;
 

	
 
	/* Skip the error until the activation stage unless bit 7 of the severity
 
	 * is set. */
 
	if (!HASBIT(severity, 7) && _cur_stage < GLS_ACTIVATION) {
 
		grfmsg(7, "Skipping non-fatal GRFError in stage 1");
 
		grfmsg(7, "Skipping non-fatal GRFLoadError in stage 1");
 
		return;
 
	}
 
	CLRBIT(severity, 7);
 

	
 
	if (severity >= lengthof(sevstr)) {
 
		grfmsg(7, "GRFError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
 
		grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
 
		severity = 2;
 
	} else if (severity == 3) {
 
		/* This is a fatal error, so make sure the GRF is deactivated and no
 
		 * more of it gets loaded. */
 
		SETBIT(_cur_grfconfig->flags, GCF_DISABLED);
 
		CLRBIT(_cur_grfconfig->flags, GCF_ACTIVATED);
 

	
 
		_skip_sprites = -1;
 
	}
 

	
 
	if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
 
		grfmsg(7, "GRFError: Invalid message id.");
 
		grfmsg(7, "GRFLoadError: Invalid message id.");
 
		return;
 
	}
 

	
 
	if (len <= 1) {
 
		grfmsg(7, "GRFError: No message data supplied.");
 
		grfmsg(7, "GRFLoadError: No message data supplied.");
 
		return;
 
	}
 

	
 
	char message[512];
 
	snprintf(message, lengthof(message), msgstr[(message_id == 0xFF) ? lengthof(msgstr) - 1 : message_id], sevstr[severity], grf_load_string(&buf, len));
 

	
 
	if (_cur_grfconfig->error == NULL) {
 
		_cur_grfconfig->error = strdup(message);
 
	bool new_scheme = _cur_grffile->grf_version >= 7;
 
	GRFError *error = CallocT<GRFError>(1);
 

	
 
	error->severity = sevstr[severity];
 

	
 
	if (message_id == 0xFF) {
 
		/* This is a custom error message. */
 
		const char *message = grf_load_string(&buf, len);
 
		len -= (strlen(message) + 1);
 

	
 
		error->message = AddGRFString(_cur_grffile->grfid, MESSAGE_STRING_ID, lang, new_scheme, message, STR_UNDEFINED);
 
	} else {
 
		error->message = msgstr[message_id];
 
	}
 

	
 
	grfmsg(0, message);
 
	if (len > 0) {
 
		const char *data = grf_load_string(&buf, len);
 
		len -= (strlen(data) + 1);
 

	
 
		error->data = AddGRFString(_cur_grffile->grfid, MESSAGE_DATA_ID, lang, new_scheme, data, STR_UNDEFINED);
 
	}
 

	
 
	/* Only two parameter numbers can be used in the string. */
 
	uint i = 0;
 
	for (; i < 2 && len > 0; i++) {
 
		error->param_number[i] = grf_load_byte(&buf);
 
		len--;
 
	}
 
	error->num_params = i;
 

	
 
	_cur_grfconfig->error = error;
 
}
 

	
 
/* Action 0x0C */
 
static void GRFComment(byte *buf, int len)
 
{
 
	/* <0C> [<ignored...>]
 
@@ -3712,13 +3745,13 @@ static void DecodeSpecialSprite(uint num
 
		/* 0x05 */ { NULL,     NULL,      NULL,            NULL,       GraphicsNew, },
 
		/* 0x06 */ { NULL,     NULL,      NULL,            CfgApply,   CfgApply, },
 
		/* 0x07 */ { NULL,     NULL,      NULL,            NULL,       SkipIf, },
 
		/* 0x08 */ { ScanInfo, NULL,      NULL,            GRFInfo,    GRFInfo, },
 
		/* 0x09 */ { NULL,     NULL,      NULL,            SkipIf,     SkipIf, },
 
		/* 0x0A */ { NULL,     NULL,      NULL,            NULL,       SpriteReplace, },
 
		/* 0x0B */ { NULL,     NULL,      NULL,            GRFError,   GRFError, },
 
		/* 0x0B */ { NULL,     NULL,      NULL,            GRFLoadError, GRFLoadError, },
 
		/* 0x0C */ { NULL,     NULL,      NULL,            GRFComment, GRFComment, },
 
		/* 0x0D */ { NULL,     SafeParamSet, NULL,         ParamSet,   ParamSet, },
 
		/* 0x0E */ { NULL,     SafeGRFInhibit, NULL,       GRFInhibit, GRFInhibit, },
 
		/* 0x0F */ { NULL,     NULL,      NULL,            NULL,       NULL, },
 
		/* 0x10 */ { NULL,     NULL,      DefineGotoLabel, NULL,       NULL, },
 
		/* 0x11 */ { NULL,     GRFUnsafe, NULL,            NULL,       GRFSound, },
src/newgrf_config.cpp
Show inline comments
 
@@ -121,13 +121,16 @@ GRFConfig **CopyGRFConfigList(GRFConfig 
 
	for (; src != NULL; src = src->next) {
 
		GRFConfig *c = CallocT<GRFConfig>(1);
 
		*c = *src;
 
		if (src->filename != NULL) c->filename = strdup(src->filename);
 
		if (src->name     != NULL) c->name     = strdup(src->name);
 
		if (src->info     != NULL) c->info     = strdup(src->info);
 
		if (src->error    != NULL) c->error    = strdup(src->error);
 
		if (src->error    != NULL) {
 
			c->error = CallocT<GRFError>(1);
 
			memcpy(c->error, src->error, sizeof(GRFError));
 
		}
 

	
 
		*dst = c;
 
		dst = &c->next;
 
	}
 

	
 
	return dst;
src/newgrf_config.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef NEWGRF_CONFIG_H
 
#define NEWGRF_CONFIG_H
 

	
 
#include "openttd.h"
 

	
 
/* GRF config bit flags */
 
typedef enum {
 
	GCF_DISABLED,  ///< GRF file is disabled
 
	GCF_NOT_FOUND, ///< GRF file was not found in the local cache
 
	GCF_ACTIVATED, ///< GRF file is active
 
	GCF_SYSTEM,    ///< GRF file is an openttd-internal system grf
 
@@ -17,17 +19,25 @@ typedef enum {
 

	
 
typedef struct GRFIdentifier {
 
	uint32 grfid;
 
	uint8 md5sum[16];
 
} GRF;
 

	
 
typedef struct GRFError {
 
	StringID message;
 
	StringID data;
 
	StringID severity;
 
	uint8 num_params;
 
	uint8 param_number[2];
 
} GRFError;
 

	
 
typedef struct GRFConfig : public GRFIdentifier {
 
	char *filename;
 
	char *name;
 
	char *info;
 
	char *error;
 
	GRFError *error;
 

	
 
	uint8 flags;
 
	uint32 param[0x80];
 
	uint8 num_params;
 

	
 
	struct GRFConfig *next;
src/newgrf_gui.cpp
Show inline comments
 
@@ -8,12 +8,13 @@
 
#include "gui.h"
 
#include "window.h"
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
#include "newgrf.h"
 
#include "newgrf_config.h"
 
#include "strings.h"
 
#include "helpers.hpp"
 

	
 

	
 
/** Parse an integerlist string and set each found value
 
 * @param p the string to be parsed. Each element in the list is seperated by a
 
 * comma or a space character
 
@@ -41,14 +42,28 @@ static int parse_intlist(const char *p, 
 

	
 
static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params)
 
{
 
	char buff[256];
 

	
 
	if (c->error != NULL) {
 
		SetDParamStr(0, c->error);
 
		y += DrawStringMultiLine(x, y, STR_NEWGRF_ERROR_MSG, w);
 
		SetDParamStr(0, c->filename);
 
		SetDParam(1, c->error->data);
 
		for (uint i = 0; i < c->error->num_params; i++) {
 
			uint32 param = 0;
 
			byte param_number = c->error->param_number[i];
 

	
 
			if (param_number < c->num_params) param = c->param[param_number];
 

	
 
			SetDParam(2 + i, param);
 
		}
 

	
 
		char message[512];
 
		GetString(message, c->error->message, lastof(message));
 

	
 
		SetDParamStr(0, message);
 
		y += DrawStringMultiLine(x, y, c->error->severity, w);
 
	}
 

	
 
	/* Draw filename or not if it is not known (GRF sent over internet) */
 
	if (c->filename != NULL) {
 
		SetDParamStr(0, c->filename);
 
		y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w);
0 comments (0 inline, 0 general)