src/newgrf.cpp
changeset 6139 cd42df0c1f0f
parent 6128 e4a3586c6ca6
child 6142 80f876e7bb9f
equal deleted inserted replaced
6138:f1196498ef66 6139:cd42df0c1f0f
  2642 		}
  2642 		}
  2643 	}
  2643 	}
  2644 }
  2644 }
  2645 
  2645 
  2646 /* Action 0x0B */
  2646 /* Action 0x0B */
  2647 static void GRFError(byte *buf, int len)
  2647 static void GRFLoadError(byte *buf, int len)
  2648 {
  2648 {
  2649 	/* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
  2649 	/* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
  2650 	 *
  2650 	 *
  2651 	 * B severity      00: notice, contine loading grf file
  2651 	 * B severity      00: notice, contine loading grf file
  2652 	 *                 01: warning, continue loading grf file
  2652 	 *                 01: warning, continue loading grf file
  2657 	 * B language-id   see action 4, use 1F for built-in error messages
  2657 	 * B language-id   see action 4, use 1F for built-in error messages
  2658 	 * B message-id    message to show, see below
  2658 	 * B message-id    message to show, see below
  2659 	 * S message       for custom messages (message-id FF), text of the message
  2659 	 * S message       for custom messages (message-id FF), text of the message
  2660 	 *                 not present for built-in messages.
  2660 	 *                 not present for built-in messages.
  2661 	 * V data          additional data for built-in (or custom) messages
  2661 	 * V data          additional data for built-in (or custom) messages
  2662 	 * B parnum        see action 6, only used with built-in message 03 */
  2662 	 * B parnum        parameter numbers to be shown in the message (maximum of 2) */
  2663 	/* TODO: For now we just show the message, sometimes incomplete and never translated. */
  2663 
  2664 
  2664 	static const StringID msgstr[] = {
  2665 	static const char *const msgstr[] = {
  2665 		STR_NEWGRF_ERROR_VERSION_NUMBER,
  2666 		"%sRequires at least pseudo-TTDPatch version %s.",
  2666 		STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
  2667 		"%sThis file is for %s version of TTD.",
  2667 		STR_NEWGRF_ERROR_UNSET_SWITCH,
  2668 		"%sDesigned to be used with %s",
  2668 		STR_NEWGRF_ERROR_INVALID_PARAMETER,
  2669 		"%sInvalid parameter %s.",
  2669 		STR_NEWGRF_ERROR_LOAD_BEFORE,
  2670 		"%sMust be loaded before %s.",
  2670 		STR_NEWGRF_ERROR_LOAD_AFTER
  2671 		"%sMust be loaded after %s.",
       
  2672 		"%s%s"
       
  2673 	};
  2671 	};
  2674 
  2672 
  2675 	static const char *const sevstr[] = {
  2673 	static const StringID sevstr[] = {
  2676 		"",
  2674 		STR_NEWGRF_ERROR_MSG_INFO,
  2677 		"Warning: ",
  2675 		STR_NEWGRF_ERROR_MSG_WARNING,
  2678 		"Error: ",
  2676 		STR_NEWGRF_ERROR_MSG_ERROR,
  2679 		"Fatal: ",
  2677 		STR_NEWGRF_ERROR_MSG_FATAL
  2680 	};
  2678 	};
  2681 
  2679 
  2682 	if (!check_length(len, 6, "GRFError")) return;
  2680 	/* AddGRFString expects the string to be referred to by an id in the newgrf
       
  2681 	 * file. Errors messages are never referred to however, so invent ids that
       
  2682 	 * are unlikely to be reached in a newgrf file so they don't overwrite
       
  2683 	 * anything else. */
       
  2684 	enum {
       
  2685 		MESSAGE_STRING_ID = MAX_UVALUE(StringID) - 1,
       
  2686 		MESSAGE_DATA_ID   = MAX_UVALUE(StringID)
       
  2687 	};
       
  2688 
       
  2689 	if (!check_length(len, 6, "GRFLoadError")) return;
       
  2690 
       
  2691 	/* For now we can only show one message per newgrf file. */
       
  2692 	if (_cur_grfconfig->error != NULL) return;
  2683 
  2693 
  2684 	buf++; /* Skip the action byte. */
  2694 	buf++; /* Skip the action byte. */
  2685 	byte severity   = grf_load_byte(&buf);
  2695 	byte severity   = grf_load_byte(&buf);
  2686 	buf++; /* TODO: Language id. */
  2696 	byte lang       = grf_load_byte(&buf);
  2687 	byte message_id = grf_load_byte(&buf);
  2697 	byte message_id = grf_load_byte(&buf);
  2688 	len -= 4;
  2698 	len -= 4;
  2689 
  2699 
  2690 	/* Skip the error until the activation stage unless bit 7 of the severity
  2700 	/* Skip the error until the activation stage unless bit 7 of the severity
  2691 	 * is set. */
  2701 	 * is set. */
  2692 	if (!HASBIT(severity, 7) && _cur_stage < GLS_ACTIVATION) {
  2702 	if (!HASBIT(severity, 7) && _cur_stage < GLS_ACTIVATION) {
  2693 		grfmsg(7, "Skipping non-fatal GRFError in stage 1");
  2703 		grfmsg(7, "Skipping non-fatal GRFLoadError in stage 1");
  2694 		return;
  2704 		return;
  2695 	}
  2705 	}
  2696 	CLRBIT(severity, 7);
  2706 	CLRBIT(severity, 7);
  2697 
  2707 
  2698 	if (severity >= lengthof(sevstr)) {
  2708 	if (severity >= lengthof(sevstr)) {
  2699 		grfmsg(7, "GRFError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
  2709 		grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
  2700 		severity = 2;
  2710 		severity = 2;
  2701 	} else if (severity == 3) {
  2711 	} else if (severity == 3) {
  2702 		/* This is a fatal error, so make sure the GRF is deactivated and no
  2712 		/* This is a fatal error, so make sure the GRF is deactivated and no
  2703 		 * more of it gets loaded. */
  2713 		 * more of it gets loaded. */
  2704 		SETBIT(_cur_grfconfig->flags, GCF_DISABLED);
  2714 		SETBIT(_cur_grfconfig->flags, GCF_DISABLED);
  2706 
  2716 
  2707 		_skip_sprites = -1;
  2717 		_skip_sprites = -1;
  2708 	}
  2718 	}
  2709 
  2719 
  2710 	if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
  2720 	if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
  2711 		grfmsg(7, "GRFError: Invalid message id.");
  2721 		grfmsg(7, "GRFLoadError: Invalid message id.");
  2712 		return;
  2722 		return;
  2713 	}
  2723 	}
  2714 
  2724 
  2715 	if (len <= 1) {
  2725 	if (len <= 1) {
  2716 		grfmsg(7, "GRFError: No message data supplied.");
  2726 		grfmsg(7, "GRFLoadError: No message data supplied.");
  2717 		return;
  2727 		return;
  2718 	}
  2728 	}
  2719 
  2729 
  2720 	char message[512];
  2730 	bool new_scheme = _cur_grffile->grf_version >= 7;
  2721 	snprintf(message, lengthof(message), msgstr[(message_id == 0xFF) ? lengthof(msgstr) - 1 : message_id], sevstr[severity], grf_load_string(&buf, len));
  2731 	GRFError *error = CallocT<GRFError>(1);
  2722 
  2732 
  2723 	if (_cur_grfconfig->error == NULL) {
  2733 	error->severity = sevstr[severity];
  2724 		_cur_grfconfig->error = strdup(message);
  2734 
  2725 	}
  2735 	if (message_id == 0xFF) {
  2726 
  2736 		/* This is a custom error message. */
  2727 	grfmsg(0, message);
  2737 		const char *message = grf_load_string(&buf, len);
       
  2738 		len -= (strlen(message) + 1);
       
  2739 
       
  2740 		error->message = AddGRFString(_cur_grffile->grfid, MESSAGE_STRING_ID, lang, new_scheme, message, STR_UNDEFINED);
       
  2741 	} else {
       
  2742 		error->message = msgstr[message_id];
       
  2743 	}
       
  2744 
       
  2745 	if (len > 0) {
       
  2746 		const char *data = grf_load_string(&buf, len);
       
  2747 		len -= (strlen(data) + 1);
       
  2748 
       
  2749 		error->data = AddGRFString(_cur_grffile->grfid, MESSAGE_DATA_ID, lang, new_scheme, data, STR_UNDEFINED);
       
  2750 	}
       
  2751 
       
  2752 	/* Only two parameter numbers can be used in the string. */
       
  2753 	uint i = 0;
       
  2754 	for (; i < 2 && len > 0; i++) {
       
  2755 		error->param_number[i] = grf_load_byte(&buf);
       
  2756 		len--;
       
  2757 	}
       
  2758 	error->num_params = i;
       
  2759 
       
  2760 	_cur_grfconfig->error = error;
  2728 }
  2761 }
  2729 
  2762 
  2730 /* Action 0x0C */
  2763 /* Action 0x0C */
  2731 static void GRFComment(byte *buf, int len)
  2764 static void GRFComment(byte *buf, int len)
  2732 {
  2765 {
  3713 		/* 0x06 */ { NULL,     NULL,      NULL,            CfgApply,   CfgApply, },
  3746 		/* 0x06 */ { NULL,     NULL,      NULL,            CfgApply,   CfgApply, },
  3714 		/* 0x07 */ { NULL,     NULL,      NULL,            NULL,       SkipIf, },
  3747 		/* 0x07 */ { NULL,     NULL,      NULL,            NULL,       SkipIf, },
  3715 		/* 0x08 */ { ScanInfo, NULL,      NULL,            GRFInfo,    GRFInfo, },
  3748 		/* 0x08 */ { ScanInfo, NULL,      NULL,            GRFInfo,    GRFInfo, },
  3716 		/* 0x09 */ { NULL,     NULL,      NULL,            SkipIf,     SkipIf, },
  3749 		/* 0x09 */ { NULL,     NULL,      NULL,            SkipIf,     SkipIf, },
  3717 		/* 0x0A */ { NULL,     NULL,      NULL,            NULL,       SpriteReplace, },
  3750 		/* 0x0A */ { NULL,     NULL,      NULL,            NULL,       SpriteReplace, },
  3718 		/* 0x0B */ { NULL,     NULL,      NULL,            GRFError,   GRFError, },
  3751 		/* 0x0B */ { NULL,     NULL,      NULL,            GRFLoadError, GRFLoadError, },
  3719 		/* 0x0C */ { NULL,     NULL,      NULL,            GRFComment, GRFComment, },
  3752 		/* 0x0C */ { NULL,     NULL,      NULL,            GRFComment, GRFComment, },
  3720 		/* 0x0D */ { NULL,     SafeParamSet, NULL,         ParamSet,   ParamSet, },
  3753 		/* 0x0D */ { NULL,     SafeParamSet, NULL,         ParamSet,   ParamSet, },
  3721 		/* 0x0E */ { NULL,     SafeGRFInhibit, NULL,       GRFInhibit, GRFInhibit, },
  3754 		/* 0x0E */ { NULL,     SafeGRFInhibit, NULL,       GRFInhibit, GRFInhibit, },
  3722 		/* 0x0F */ { NULL,     NULL,      NULL,            NULL,       NULL, },
  3755 		/* 0x0F */ { NULL,     NULL,      NULL,            NULL,       NULL, },
  3723 		/* 0x10 */ { NULL,     NULL,      DefineGotoLabel, NULL,       NULL, },
  3756 		/* 0x10 */ { NULL,     NULL,      DefineGotoLabel, NULL,       NULL, },