mirror of https://github.com/OpenTTD/OpenTTD
(svn r8881) -Feature: Allow built-in newgrf error messages to be translated, and load custom error messages properly.
parent
8ac0e7be21
commit
8b6350d3a3
|
@ -2896,12 +2896,22 @@ STR_NEWGRF_APPLY_CHANGES :{BLACK}Apply ch
|
||||||
STR_NEWGRF_SET_PARAMETERS :{BLACK}Set parameters
|
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_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_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_FILENAME :{BLACK}Filename: {SILVER}{STRING}
|
||||||
STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
|
STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
|
||||||
STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {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_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 :{BLACK}Add
|
||||||
STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
|
STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
|
||||||
STR_NEWGRF_REMOVE :{BLACK}Remove
|
STR_NEWGRF_REMOVE :{BLACK}Remove
|
||||||
|
|
|
@ -2644,7 +2644,7 @@ static void SpriteReplace(byte *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Action 0x0B */
|
/* 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>]
|
/* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
|
||||||
*
|
*
|
||||||
|
@ -2659,44 +2659,54 @@ static void GRFError(byte *buf, int len)
|
||||||
* S message for custom messages (message-id FF), text of the message
|
* S message for custom messages (message-id FF), text of the message
|
||||||
* not present for built-in messages.
|
* not present for built-in messages.
|
||||||
* V data additional data for built-in (or custom) messages
|
* V data additional data for built-in (or custom) messages
|
||||||
* B parnum see action 6, only used with built-in message 03 */
|
* B parnum parameter numbers to be shown in the message (maximum of 2) */
|
||||||
/* TODO: For now we just show the message, sometimes incomplete and never translated. */
|
|
||||||
|
|
||||||
static const char *const msgstr[] = {
|
static const StringID msgstr[] = {
|
||||||
"%sRequires at least pseudo-TTDPatch version %s.",
|
STR_NEWGRF_ERROR_VERSION_NUMBER,
|
||||||
"%sThis file is for %s version of TTD.",
|
STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
|
||||||
"%sDesigned to be used with %s",
|
STR_NEWGRF_ERROR_UNSET_SWITCH,
|
||||||
"%sInvalid parameter %s.",
|
STR_NEWGRF_ERROR_INVALID_PARAMETER,
|
||||||
"%sMust be loaded before %s.",
|
STR_NEWGRF_ERROR_LOAD_BEFORE,
|
||||||
"%sMust be loaded after %s.",
|
STR_NEWGRF_ERROR_LOAD_AFTER
|
||||||
"%s%s"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const sevstr[] = {
|
static const StringID sevstr[] = {
|
||||||
"",
|
STR_NEWGRF_ERROR_MSG_INFO,
|
||||||
"Warning: ",
|
STR_NEWGRF_ERROR_MSG_WARNING,
|
||||||
"Error: ",
|
STR_NEWGRF_ERROR_MSG_ERROR,
|
||||||
"Fatal: ",
|
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. */
|
buf++; /* Skip the action byte. */
|
||||||
byte severity = grf_load_byte(&buf);
|
byte severity = grf_load_byte(&buf);
|
||||||
buf++; /* TODO: Language id. */
|
byte lang = grf_load_byte(&buf);
|
||||||
byte message_id = grf_load_byte(&buf);
|
byte message_id = grf_load_byte(&buf);
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
|
||||||
/* Skip the error until the activation stage unless bit 7 of the severity
|
/* Skip the error until the activation stage unless bit 7 of the severity
|
||||||
* is set. */
|
* is set. */
|
||||||
if (!HASBIT(severity, 7) && _cur_stage < GLS_ACTIVATION) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
CLRBIT(severity, 7);
|
CLRBIT(severity, 7);
|
||||||
|
|
||||||
if (severity >= lengthof(sevstr)) {
|
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;
|
severity = 2;
|
||||||
} else if (severity == 3) {
|
} else if (severity == 3) {
|
||||||
/* This is a fatal error, so make sure the GRF is deactivated and no
|
/* This is a fatal error, so make sure the GRF is deactivated and no
|
||||||
|
@ -2708,23 +2718,46 @@ static void GRFError(byte *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
|
if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
|
||||||
grfmsg(7, "GRFError: Invalid message id.");
|
grfmsg(7, "GRFLoadError: Invalid message id.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= 1) {
|
if (len <= 1) {
|
||||||
grfmsg(7, "GRFError: No message data supplied.");
|
grfmsg(7, "GRFLoadError: No message data supplied.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char message[512];
|
bool new_scheme = _cur_grffile->grf_version >= 7;
|
||||||
snprintf(message, lengthof(message), msgstr[(message_id == 0xFF) ? lengthof(msgstr) - 1 : message_id], sevstr[severity], grf_load_string(&buf, len));
|
GRFError *error = CallocT<GRFError>(1);
|
||||||
|
|
||||||
if (_cur_grfconfig->error == NULL) {
|
error->severity = sevstr[severity];
|
||||||
_cur_grfconfig->error = strdup(message);
|
|
||||||
|
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 */
|
/* Action 0x0C */
|
||||||
|
@ -3715,7 +3748,7 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
|
||||||
/* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, },
|
/* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, },
|
||||||
/* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, },
|
/* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, },
|
||||||
/* 0x0A */ { NULL, NULL, NULL, NULL, SpriteReplace, },
|
/* 0x0A */ { NULL, NULL, NULL, NULL, SpriteReplace, },
|
||||||
/* 0x0B */ { NULL, NULL, NULL, GRFError, GRFError, },
|
/* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, },
|
||||||
/* 0x0C */ { NULL, NULL, NULL, GRFComment, GRFComment, },
|
/* 0x0C */ { NULL, NULL, NULL, GRFComment, GRFComment, },
|
||||||
/* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, },
|
/* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, },
|
||||||
/* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, },
|
/* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, },
|
||||||
|
|
|
@ -124,7 +124,10 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src)
|
||||||
if (src->filename != NULL) c->filename = strdup(src->filename);
|
if (src->filename != NULL) c->filename = strdup(src->filename);
|
||||||
if (src->name != NULL) c->name = strdup(src->name);
|
if (src->name != NULL) c->name = strdup(src->name);
|
||||||
if (src->info != NULL) c->info = strdup(src->info);
|
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;
|
||||||
dst = &c->next;
|
dst = &c->next;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#ifndef NEWGRF_CONFIG_H
|
#ifndef NEWGRF_CONFIG_H
|
||||||
#define NEWGRF_CONFIG_H
|
#define NEWGRF_CONFIG_H
|
||||||
|
|
||||||
|
#include "openttd.h"
|
||||||
|
|
||||||
/* GRF config bit flags */
|
/* GRF config bit flags */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GCF_DISABLED, ///< GRF file is disabled
|
GCF_DISABLED, ///< GRF file is disabled
|
||||||
|
@ -20,11 +22,19 @@ typedef struct GRFIdentifier {
|
||||||
uint8 md5sum[16];
|
uint8 md5sum[16];
|
||||||
} GRF;
|
} GRF;
|
||||||
|
|
||||||
|
typedef struct GRFError {
|
||||||
|
StringID message;
|
||||||
|
StringID data;
|
||||||
|
StringID severity;
|
||||||
|
uint8 num_params;
|
||||||
|
uint8 param_number[2];
|
||||||
|
} GRFError;
|
||||||
|
|
||||||
typedef struct GRFConfig : public GRFIdentifier {
|
typedef struct GRFConfig : public GRFIdentifier {
|
||||||
char *filename;
|
char *filename;
|
||||||
char *name;
|
char *name;
|
||||||
char *info;
|
char *info;
|
||||||
char *error;
|
GRFError *error;
|
||||||
|
|
||||||
uint8 flags;
|
uint8 flags;
|
||||||
uint32 param[0x80];
|
uint32 param[0x80];
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "newgrf.h"
|
#include "newgrf.h"
|
||||||
#include "newgrf_config.h"
|
#include "newgrf_config.h"
|
||||||
|
#include "strings.h"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,8 +45,22 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show
|
||||||
char buff[256];
|
char buff[256];
|
||||||
|
|
||||||
if (c->error != NULL) {
|
if (c->error != NULL) {
|
||||||
SetDParamStr(0, c->error);
|
SetDParamStr(0, c->filename);
|
||||||
y += DrawStringMultiLine(x, y, STR_NEWGRF_ERROR_MSG, w);
|
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) */
|
/* Draw filename or not if it is not known (GRF sent over internet) */
|
||||||
|
|
Loading…
Reference in New Issue