47 static char gamelog_revision[48] = { 0 };
48 assert_compile(
lengthof(gamelog_revision) > GAMELOG_REVISION_LENGTH);
50 if (IsReleasedVersion()) {
51 return _openttd_revision;
52 }
else if (gamelog_revision[0] == 0) {
54 assert(_openttd_revision_modified < 3);
55 gamelog_revision[0] =
"gum"[_openttd_revision_modified];
57 strecat(gamelog_revision, _openttd_revision_hash,
lastof(gamelog_revision));
59 gamelog_revision[GAMELOG_REVISION_LENGTH - 1] =
'\0';
61 return gamelog_revision;
82 bool print = _current_action !=
nullptr;
84 _current_action =
nullptr;
95 for (uint i = 0; i < gamelog_actions; i++) {
97 for (uint j = 0; j < la->
changes; j++) {
104 free(gamelog_action);
115 _gamelog_action =
nullptr;
117 _current_action =
nullptr;
133 if (md5sum !=
nullptr) {
135 buf +=
seprintf(buf, last,
"GRF ID %08X, checksum %s",
BSWAP32(grfid), txt);
141 buf +=
seprintf(buf, last,
", filename: %s (md5sum matches)", gc->
filename);
145 buf +=
seprintf(buf, last,
", filename: %s (matches GRFID only)", gc->
filename);
147 buf +=
seprintf(buf, last,
", unknown GRF");
158 "GRF config changed",
162 "emergency savegame",
192 proc(
"---- gamelog start ----");
196 for (
const LoggedAction *la = _gamelog_action; la != laend; la++) {
204 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
208 default: NOT_REACHED();
210 buf +=
seprintf(buf,
lastof(buffer),
"New game mode: %u landscape: %u",
211 (uint)lc->mode.mode, (uint)lc->mode.landscape);
215 buf +=
seprintf(buf,
lastof(buffer),
"Revision text changed to %s, savegame version %u, ",
216 lc->revision.text, lc->revision.slver);
218 switch (lc->revision.modified) {
224 buf +=
seprintf(buf,
lastof(buffer),
"modified, _openttd_newgrf_version = 0x%08x", lc->revision.newgrf);
229 switch (lc->oldver.type) {
230 default: NOT_REACHED();
232 buf +=
seprintf(buf,
lastof(buffer),
"OTTD savegame without gamelog: version %u, %u",
233 GB(lc->oldver.version, 8, 16),
GB(lc->oldver.version, 0, 8));
247 lc->oldver.type ==
SGT_TTDP1 ?
"old" :
"new");
248 if (lc->oldver.version != 0) {
249 buf +=
seprintf(buf,
lastof(buffer),
", TTDP version %u.%u.%u.%u",
250 GB(lc->oldver.version, 24, 8),
GB(lc->oldver.version, 20, 4),
251 GB(lc->oldver.version, 16, 4),
GB(lc->oldver.version, 0, 16));
258 buf +=
seprintf(buf,
lastof(buffer),
"Setting changed: %s : %d -> %d", lc->setting.name, lc->setting.oldval, lc->setting.newval);
266 if (gm != grf_names.End() && !gm->second.was_missing) buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was already added!");
267 grf_names[lc->grfadd.grfid] =
gc;
274 buf =
PrintGrfInfo(buf,
lastof(buffer), lc->grfrem.grfid,
nullptr, gm != grf_names.End() ? gm->second.gc :
nullptr);
275 if (gm == grf_names.End()) {
276 buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was never added!");
280 gm->second.was_missing =
true;
290 buf +=
seprintf(buf,
lastof(buffer),
"Compatible NewGRF loaded: ");
291 buf =
PrintGrfInfo(buf,
lastof(buffer), lc->grfcompat.grfid, lc->grfcompat.md5sum, gc);
292 if (!grf_names.
Contains(lc->grfcompat.grfid)) buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was never added!");
293 grf_names[lc->grfcompat.grfid] =
gc;
300 buf =
PrintGrfInfo(buf,
lastof(buffer), lc->grfparam.grfid,
nullptr, gm != grf_names.End() ? gm->second.gc :
nullptr);
301 if (gm == grf_names.End()) buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was never added!");
307 buf +=
seprintf(buf,
lastof(buffer),
"GRF order changed: %08X moved %d places %s",
308 BSWAP32(lc->grfmove.grfid),
abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ?
"down" :
"up" );
309 buf =
PrintGrfInfo(buf,
lastof(buffer), lc->grfmove.grfid,
nullptr, gm != grf_names.End() ? gm->second.gc :
nullptr);
310 if (gm == grf_names.End()) buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was never added!");
316 switch (lc->grfbug.bug) {
317 default: NOT_REACHED();
319 buf +=
seprintf(buf,
lastof(buffer),
"Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X",
BSWAP32(lc->grfbug.grfid), (uint)lc->grfbug.data);
322 buf =
PrintGrfInfo(buf,
lastof(buffer), lc->grfbug.grfid,
nullptr, gm != grf_names.End() ? gm->second.gc :
nullptr);
323 if (gm == grf_names.End()) buf +=
seprintf(buf,
lastof(buffer),
". Gamelog inconsistency: GrfID was never added!");
335 proc(
"---- gamelog end ----");
339 static void GamelogPrintConsoleProc(
const char *s)
352 static void GamelogPrintDebugProc(
const char *s)
379 if (_current_action ==
nullptr) {
387 _current_action->
change =
nullptr;
420 for (
const LoggedAction *la = _gamelog_action; la != laend; la++) {
422 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
427 return (emergency !=
nullptr);
438 if (lc ==
nullptr)
return;
440 memset(lc->revision.text, 0,
sizeof(lc->revision.text));
443 lc->revision.modified = _openttd_revision_modified;
444 lc->revision.newgrf = _openttd_newgrf_version;
455 if (lc ==
nullptr)
return;
457 lc->
mode.mode = _game_mode;
469 if (lc ==
nullptr)
return;
486 if (lc ==
nullptr)
return;
488 lc->setting.name =
stredup(name);
489 lc->setting.oldval = oldval;
490 lc->setting.newval = newval;
503 for (
const LoggedAction *la = _gamelog_action; la != laend; la++) {
505 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
511 rev->revision.modified != _openttd_revision_modified ||
512 rev->revision.newgrf != _openttd_newgrf_version) {
526 for (
const LoggedAction *la = _gamelog_action; la != laend; la++) {
528 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
548 if (lc ==
nullptr)
return;
550 lc->grfbug.data = data;
551 lc->grfbug.grfid = grfid;
552 lc->grfbug.bug = bug;
567 for (
const LoggedAction *la = _gamelog_action; la != laend; la++) {
569 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
570 if (lc->ct ==
GLCT_GRFBUG && lc->grfbug.grfid == grfid &&
604 if (lc ==
nullptr)
return;
606 lc->grfrem.grfid = grfid;
620 if (lc ==
nullptr)
return;
635 if (lc ==
nullptr)
return;
650 if (lc ==
nullptr)
return;
652 lc->grfmove.grfid = grfid;
653 lc->grfmove.offset = offset;
666 if (lc ==
nullptr)
return;
668 lc->grfparam.grfid = grfid;
680 for (; newg !=
nullptr; newg = newg->
next) {
724 while (o < ol->n && n < nl->n) {
730 for (oi = 0; oi < ol->n; oi++) {
743 for (ni = 0; ni < nl->n; ni++) {
759 assert(ni > n && ni < nl->n);
760 assert(oi > o && oi < ol->n);
801 void GamelogInfo(
LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified,
bool *removed_newgrfs)
803 const LoggedAction *laend = &gamelog_action[gamelog_actions];
804 for (
const LoggedAction *la = gamelog_action; la != laend; la++) {
806 for (
const LoggedChange *lc = la->change; lc != lcend; lc++) {
811 *last_ottd_rev = lc->revision.newgrf;
812 *ever_modified =
max(*ever_modified, lc->revision.modified);
816 *removed_newgrfs =
true;
void GamelogPrint(GamelogPrintProc *proc)
Prints active gamelog.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
bool GamelogTestEmergency()
Finds out if current game is a loaded emergency savegame.
Loaded from savegame without logged data.
static GamelogActionType _gamelog_action_type
action to record if anything changes
static LoggedAction * _current_action
current action we are logging, nullptr when there is no action active
static void GamelogGRFParameters(uint32 grfid)
Logs change in GRF parameters.
void GamelogEmergency()
Logs a emergency savegame.
byte landscape
the landscape we're currently in
GamelogChangeType ct
Type of change logged in this struct.
static char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
SaveLoadVersion
SaveLoad versions Previous savegame versions, the trunk revision where they were introduced and the r...
Functions related to dates.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Functions related to debugging.
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
static void GamelogGRFMove(uint32 grfid, int32 offset)
Logs changing GRF order.
void GamelogStartAction(GamelogActionType at)
Stores information about new action, but doesn't allocate it Action is allocated only when there is a...
Implementation of simple mapping class.
GRFStatus status
NOSAVE: GRFStatus, enum.
char * md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
Convert the md5sum to a hexadecimal string representation.
SaveLoadVersion _sl_version
the major savegame version identifier
static bool IsLoggableGrfConfig(const GRFConfig *g)
Decides if GRF should be logged.
uint32 changes
Number of changes in this action.
void GamelogRevision()
Logs a change in game revision.
GRF file is used statically (can be used in any MP game)
TTD savegame (can be detected incorrectly)
List of GRFs using array of pointers instead of linked list.
#define lastof(x)
Get the last element of an fixed size array.
void GamelogPrintDebug(int level)
Prints gamelog to debug output.
GRF file was not found in the local cache.
void GamelogOldver()
Logs loading from savegame without gamelog.
SavegameType
Types of save games.
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
Non-networksafe setting value changed.
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
static T max(const T a, const T b)
Returns the maximum of two values.
GRFIdentifier grfcompat
ID and new md5sum of changed GRF.
static LoggedChange * GamelogChange(GamelogChangeType ct)
Allocates new LoggedChange and new LoggedAction if needed.
Basic data to distinguish a GRF.
uint _gamelog_actions
number of actions
static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data)
Logs triggered GRF bug.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
GamelogActionType
The actions we log.
GRFIdentifier grfadd
ID and md5sum of added GRF.
void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs)
Get some basic information from the given gamelog.
Functions related to low-level strings.
void GamelogSetting(const char *name, int32 oldval, int32 newval)
Logs change in game settings.
void GamelogReset()
Resets and frees all memory allocated - used before loading or starting a new game.
Functions/types related to saving and loading games.
uint8 num_params
Number of used parameters.
static int _gamelog_print_level
gamelog debug level we need to print stuff
Contains information about one logged action that caused at least one logged change.
void GamelogPrintConsole()
Print the gamelog data to the console.
void GamelogFree(LoggedAction *gamelog_action, uint gamelog_actions)
Frees the memory allocated by a gamelog.
Information about GRF, used in the game and (part of it) in savegames.
void IConsolePrint(TextColour colour_code, const char *string)
Handle the printing of text entered into the console or redirected there by any other means...
bool Contains(const T &key) const
Tests whether a key is assigned in this map.
Types related to global configuration settings.
void GamelogGRFAdd(const GRFConfig *newg)
Logs adding of a GRF.
void GamelogMode()
Logs a change in game mode (scenario editor or game)
Definition of base types and functions in a cross-platform compatible way.
byte _sl_minor_version
the minor savegame version, DO NOT USE!
Information about the presence of a Grf at a certain point during gamelog history Note about missing ...
A number of safeguards to prevent using unsafe methods.
byte mode
new game mode - Editor x Game
bool was_missing
Grf was missing during some gameload in the past.
TTDP savegame in new format (data at SE border)
uint8 flags
NOSAVE: GCF_Flags, bitset.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type...
Console functions used outside of the console code.
uint16 tick
Tick when it happened.
SavegameType _savegame_type
type of savegame we are loading
void GamelogGRFAddList(const GRFConfig *newg)
Logs adding of list of GRFs.
Scenario editor x Game, different landscape.
So we know how many GLATs are there.
void GamelogGRFCompatible(const GRFIdentifier *newg)
Logs loading compatible GRF (the same ID, but different MD5 hash)
const SaveLoadVersion SAVEGAME_VERSION
current savegame version
#define lengthof(x)
Return the length of an fixed size array.
void GamelogTestRevision()
Finds out if current revision is different than last revision stored in the savegame.
uint32 _ttdp_version
version of TTDP savegame (if applicable)
Changed game revision string.
void Erase(Pair *pair)
Removes given pair from this map.
void GamelogStopAction()
Stops logging of any changes.
#define DEBUG(name, level,...)
Output a line of debugging information.
LoggedAction * _gamelog_action
first logged action
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
static char * PrintGrfInfo(char *buf, const char *last, uint grfid, const uint8 *md5sum, const GRFConfig *gc)
Prints GRF ID, checksum and filename if found.
GamelogActionType at
Type of action.
TTDP savegame ( -//- ) (data at NW border)
GamelogChangeType
Type of logged change.
LoggedChange * change
First logged change in this action.
Contains information about one logged change.
static T abs(const T a)
Returns the absolute value of (scalar) variable.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id)
Logs GRF bug - rail vehicle has different length after reversing.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
char * filename
Filename - either with or without full path.
const GRFConfig * gc
GRFConfig, if known.
void GamelogGRFRemove(uint32 grfid)
Logs removal of a GRF.
uint32 grfid
GRF ID (defined by Action 0x08)
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
declaration of OTTD revision dependent variables
Declaration shared among gamelog.cpp and saveload/gamelog_sl.cpp.
uint32 param[0x80]
GRF parameters.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
No logging active; in savegames, end of list.
GameCreationSettings game_creation
settings used during the creation of a game (map)
void GamelogTestMode()
Finds last stored game mode or landscape.
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Length of rail vehicle changes when not inside a depot.
void GamelogPrintProc(const char *s)
Callback for printing text.
uint8 md5sum[16]
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF) ...
Only find Grfs matching md5sum.
static const char * GetGamelogRevisionString()
Return the revision string for the current client version, for use in gamelog.
void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc)
Compares two NewGRF lists and logs any change.
static const TextColour CC_WARNING
Colour for warning lines.
static const char *const la_text[]
Text messages for various logged actions.
static GRFList * GenerateGRFList(const GRFConfig *grfc)
Generates GRFList.