37 GLCT_GRFADD, ///< Removed GRF |
37 GLCT_GRFADD, ///< Removed GRF |
38 GLCT_GRFREM, ///< Added GRF |
38 GLCT_GRFREM, ///< Added GRF |
39 GLCT_GRFCOMPAT, ///< Loading compatible GRF |
39 GLCT_GRFCOMPAT, ///< Loading compatible GRF |
40 GLCT_GRFPARAM, ///< GRF parameter changed |
40 GLCT_GRFPARAM, ///< GRF parameter changed |
41 GLCT_GRFMOVE, ///< GRF order changed |
41 GLCT_GRFMOVE, ///< GRF order changed |
|
42 GLCT_GRFBUG, ///< GRF bug triggered |
42 GLCT_END, ///< So we know how many GLCTs are there |
43 GLCT_END, ///< So we know how many GLCTs are there |
43 GLCT_NONE = 0xFF, ///< In savegames, end of list |
44 GLCT_NONE = 0xFF, ///< In savegames, end of list |
44 }; |
45 }; |
45 |
46 |
46 |
47 |
77 struct { |
78 struct { |
78 char *name; ///< name of the patch |
79 char *name; ///< name of the patch |
79 int32 oldval; ///< old value |
80 int32 oldval; ///< old value |
80 int32 newval; ///< new value |
81 int32 newval; ///< new value |
81 } patch; |
82 } patch; |
|
83 struct { |
|
84 uint64 data; ///< additional data |
|
85 uint32 grfid; ///< ID of problematic GRF |
|
86 byte bug; ///< type of bug, @see enum GRFBugs |
|
87 } grfbug; |
82 }; |
88 }; |
83 }; |
89 }; |
84 |
90 |
85 |
91 |
86 /** Contains information about one logged action that caused at least one logged change */ |
92 /** Contains information about one logged action that caused at least one logged change */ |
298 case GLCT_GRFMOVE: |
305 case GLCT_GRFMOVE: |
299 AddDebugText(buf, "GRF order changed: %08X moved %d places %s", |
306 AddDebugText(buf, "GRF order changed: %08X moved %d places %s", |
300 BSWAP32(lc->grfmove.grfid), abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ? "down" : "up" ); |
307 BSWAP32(lc->grfmove.grfid), abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ? "down" : "up" ); |
301 PrintGrfFilename(buf, lc->grfmove.grfid); |
308 PrintGrfFilename(buf, lc->grfmove.grfid); |
302 break; |
309 break; |
|
310 |
|
311 case GLCT_GRFBUG: |
|
312 switch (lc->grfbug.bug) { |
|
313 default: NOT_REACHED(); |
|
314 case GBUG_VEH_LENGTH: |
|
315 AddDebugText(buf, "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc->grfbug.grfid), (uint)lc->grfbug.data); |
|
316 PrintGrfFilename(buf, lc->grfbug.grfid); |
|
317 break; |
|
318 } |
303 } |
319 } |
304 |
320 |
305 proc(buf); |
321 proc(buf); |
306 } |
322 } |
307 } |
323 } |
467 |
483 |
468 if (mode == NULL || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) GamelogMode(); |
484 if (mode == NULL || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) GamelogMode(); |
469 } |
485 } |
470 |
486 |
471 |
487 |
|
488 /** Logs triggered GRF bug. |
|
489 * @param grfid ID of problematic GRF |
|
490 * @param bug type of bug, @see enum GRFBugs |
|
491 * @param data additional data |
|
492 */ |
|
493 static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data) |
|
494 { |
|
495 assert(_gamelog_action_type == GLAT_GRFBUG); |
|
496 |
|
497 LoggedChange *lc = GamelogChange(GLCT_GRFBUG); |
|
498 if (lc == NULL) return; |
|
499 |
|
500 lc->grfbug.data = data; |
|
501 lc->grfbug.grfid = grfid; |
|
502 lc->grfbug.bug = bug; |
|
503 } |
|
504 |
|
505 /** Logs GRF bug - rail vehicle has different length after reversing. |
|
506 * Ensures this is logged only once for each GRF and engine type |
|
507 * This check takes some time, but it is called pretty seldom, so it |
|
508 * doesn't matter that much (ideally it shouldn't be called at all). |
|
509 * @param engine engine to log |
|
510 * @return true iff a unique record was done |
|
511 */ |
|
512 bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id) |
|
513 { |
|
514 const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; |
|
515 for (const LoggedAction *la = _gamelog_action; la != laend; la++) { |
|
516 const LoggedChange *lcend = &la->change[la->changes]; |
|
517 for (const LoggedChange *lc = la->change; lc != lcend; lc++) { |
|
518 if (lc->ct == GLCT_GRFBUG && lc->grfbug.grfid == grfid && |
|
519 lc->grfbug.bug == GBUG_VEH_LENGTH && lc->grfbug.data == internal_id) { |
|
520 return false; |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 GamelogStartAction(GLAT_GRFBUG); |
|
526 GamelogGRFBug(grfid, GBUG_VEH_LENGTH, internal_id); |
|
527 GamelogStopAction(); |
|
528 |
|
529 return true; |
|
530 } |
|
531 |
|
532 |
472 /** Decides if GRF should be logged |
533 /** Decides if GRF should be logged |
473 * @param g grf to determine |
534 * @param g grf to determine |
474 * @return true iff GRF is not static and is loaded |
535 * @return true iff GRF is not static and is loaded |
475 */ |
536 */ |
476 static inline bool IsLoggableGrfConfig(const GRFConfig *g) |
537 static inline bool IsLoggableGrfConfig(const GRFConfig *g) |
722 SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32), |
783 SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32), |
723 SLE_END() |
784 SLE_END() |
724 }; |
785 }; |
725 |
786 |
726 static const SaveLoad _glog_grfmove_desc[] = { |
787 static const SaveLoad _glog_grfmove_desc[] = { |
727 SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32), |
788 SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32), |
728 SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32), |
789 SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32), |
|
790 SLE_END() |
|
791 }; |
|
792 |
|
793 static const SaveLoad _glog_grfbug_desc[] = { |
|
794 SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64), |
|
795 SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32), |
|
796 SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8), |
729 SLE_END() |
797 SLE_END() |
730 }; |
798 }; |
731 |
799 |
732 static const SaveLoad *_glog_desc[] = { |
800 static const SaveLoad *_glog_desc[] = { |
733 _glog_mode_desc, |
801 _glog_mode_desc, |