OpenTTD Source 20250331-master-g3c15e0c889
newgrf_act8.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../string_func.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
15
16#include "../table/strings.h"
17
18#include "../safeguards.h"
19
20/* Action 0x08 (GLS_FILESCAN) */
21static void ScanInfo(ByteReader &buf)
22{
23 uint8_t grf_version = buf.ReadByte();
24 uint32_t grfid = buf.ReadDWord();
25 std::string_view name = buf.ReadString();
26
27 _cur.grfconfig->ident.grfid = grfid;
28
29 if (grf_version < 2 || grf_version > 8) {
31 Debug(grf, 0, "{}: NewGRF \"{}\" (GRFID {:08X}) uses GRF version {}, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, StrMakeValid(name), std::byteswap(grfid), grf_version);
32 }
33
34 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
35 if (GB(grfid, 0, 8) == 0xFF) _cur.grfconfig->flags.Set(GRFConfigFlag::System);
36
37 AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name);
38
39 if (buf.HasData()) {
40 std::string_view info = buf.ReadString();
41 AddGRFTextToList(_cur.grfconfig->info, 0x7F, grfid, true, info);
42 }
43
44 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
45 _cur.skip_sprites = -1;
46}
47
48/* Action 0x08 */
49static void GRFInfo(ByteReader &buf)
50{
51 /* <08> <version> <grf-id> <name> <info>
52 *
53 * B version newgrf version, currently 06
54 * 4*B grf-id globally unique ID of this .grf file
55 * S name name of this .grf set
56 * S info string describing the set, and e.g. author and copyright */
57
58 uint8_t version = buf.ReadByte();
59 uint32_t grfid = buf.ReadDWord();
60 std::string_view name = buf.ReadString();
61
62 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
63 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
64 return;
65 }
66
67 if (_cur.grffile->grfid != grfid) {
68 Debug(grf, 0, "GRFInfo: GRFID {:08X} in FILESCAN stage does not match GRFID {:08X} in INIT/RESERVE/ACTIVATION stage", std::byteswap(_cur.grffile->grfid), std::byteswap(grfid));
69 _cur.grffile->grfid = grfid;
70 }
71
72 _cur.grffile->grf_version = version;
73 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
74
75 /* Do swap the GRFID for displaying purposes since people expect that */
76 Debug(grf, 1, "GRFInfo: Loaded GRFv{} set {:08X} - {} (palette: {}, version: {})", version, std::byteswap(grfid), StrMakeValid(name), (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
77}
78
79template <> void GrfActionHandler<0x08>::FileScan(ByteReader &buf) { ScanInfo(buf); }
82template <> void GrfActionHandler<0x08>::Init(ByteReader &buf) { GRFInfo(buf); }
83template <> void GrfActionHandler<0x08>::Reserve(ByteReader &buf) { GRFInfo(buf); }
84template <> void GrfActionHandler<0x08>::Activation(ByteReader &buf) { GRFInfo(buf); }
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr Timpl & Set()
Set all bits.
Class to read from a NewGRF file.
uint32_t ReadDWord()
Read a single DWord (32 bits).
std::string_view ReadString()
Read a string.
uint8_t ReadByte()
Read a single byte (8 bits).
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:131
NewGRF buffer reader definition.
@ GCS_INITIALISED
GRF file has been initialised.
@ GCS_UNKNOWN
The status of this grf file is unknown.
@ GCS_ACTIVATED
GRF file has been activated.
@ System
GRF file is an openttd-internal system grf.
@ Invalid
GRF is unusable with this version of OpenTTD.
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
NewGRF internal processing state.
static void AddGRFTextToList(GRFTextList &list, uint8_t langid, std::string_view text_to_add)
Add a new text to a GRFText list.
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:125
uint8_t palette
GRFPalette, bitset.
GRFTextWrapper info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
GRFTextWrapper name
NOSAVE: GRF name (Action 0x08)
GRFStatus status
NOSAVE: GRFStatus, enum.
GRFConfigFlags flags
NOSAVE: GCF_Flags, bitset.
std::string filename
Filename - either with or without full path.
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
uint32_t grfid
GRF ID (defined by Action 0x08)
GRF action handler.
GRFFile * grffile
Currently processed GRF file.
GRFConfig * grfconfig
Config of the currently processed GRF file.
GrfLoadingStage stage
Current loading stage.
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)