From 548f0496a949db7eeea13d2027e66ce286b8cc20 Mon Sep 17 00:00:00 2001 From: dP Date: Wed, 21 Sep 2022 13:42:29 +0300 Subject: [PATCH] Change: Make _tick_counter 64bit to avoid wrapping (#10035) --- src/date.cpp | 2 +- src/date_func.h | 2 +- src/gamelog_internal.h | 2 +- src/newgrf.cpp | 4 ++-- src/newgrf_animation_base.h | 2 +- src/newgrf_profiling.cpp | 4 ++-- src/newgrf_profiling.h | 4 ++-- src/saveload/gamelog_sl.cpp | 3 ++- src/saveload/misc_sl.cpp | 3 ++- src/saveload/oldloader_sl.cpp | 2 +- src/saveload/saveload.h | 1 + src/stdafx.h | 10 +++++++++- 12 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/date.cpp b/src/date.cpp index eac0c5f0ba..66ccc1444c 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -27,7 +27,7 @@ Year _cur_year; ///< Current year, starting at 0 Month _cur_month; ///< Current month (0..11) Date _date; ///< Current date in days (day counter) DateFract _date_fract; ///< Fractional part of the day. -uint16 _tick_counter; ///< Ever incrementing (and sometimes wrapping) tick counter for setting off various events +uint64 _tick_counter; ///< Ever incrementing tick counter for setting off various events /** * Set the date. diff --git a/src/date_func.h b/src/date_func.h index 58b16bafdc..e8ac6a7c77 100644 --- a/src/date_func.h +++ b/src/date_func.h @@ -16,7 +16,7 @@ extern Year _cur_year; extern Month _cur_month; extern Date _date; extern DateFract _date_fract; -extern uint16 _tick_counter; +extern uint64 _tick_counter; void SetDate(Date date, DateFract fract); void ConvertDateToYMD(Date date, YearMonthDay *ymd); diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h index fb7c88e48c..95e4404b7b 100644 --- a/src/gamelog_internal.h +++ b/src/gamelog_internal.h @@ -81,7 +81,7 @@ struct LoggedAction { LoggedChange *change; ///< First logged change in this action uint32 changes; ///< Number of changes in this action GamelogActionType at; ///< Type of action - uint16 tick; ///< Tick when it happened + uint64 tick; ///< Tick when it happened }; extern LoggedAction *_gamelog_action; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 81f36a0d02..1bc05c49b0 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -6313,7 +6313,7 @@ bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile) return true; case 0x0A: // animation counter - *value = _tick_counter; + *value = GB(_tick_counter, 0, 16); return true; case 0x0B: { // TTDPatch version @@ -9814,7 +9814,7 @@ void LoadNewGRF(uint load_index, uint num_baseset) Date date = _date; Year year = _cur_year; DateFract date_fract = _date_fract; - uint16 tick_counter = _tick_counter; + uint64 tick_counter = _tick_counter; byte display_opt = _display_opt; if (_networking) { diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index ee8622b56e..faffe95e4f 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -53,7 +53,7 @@ struct AnimationBase { * increasing this value by one doubles the wait. 0 is the minimum value * allowed for animation_speed, which corresponds to 30ms, and 16 is the * maximum, corresponding to around 33 minutes. */ - if (_tick_counter % (1 << animation_speed) != 0) return; + if (_tick_counter % (1ULL << animation_speed) != 0) return; uint8 frame = GetAnimationFrame(tile); uint8 num_frames = spec->animation.frames; diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp index c05489b9e1..7f93e1d765 100644 --- a/src/newgrf_profiling.cpp +++ b/src/newgrf_profiling.cpp @@ -109,7 +109,7 @@ uint32 NewGRFProfiler::Finish() fputs("Tick,Sprite,Feature,Item,CallbackID,Microseconds,Depth,Result\n", f); for (const Call &c : this->calls) { - fprintf(f, "%u,%u,0x%X,%u,0x%X,%u,%u,%u\n", c.tick, c.root_sprite, c.feat, c.item, (uint)c.cb, c.time, c.subs, c.result); + fprintf(f, OTTD_PRINTF64U ",%u,0x%X,%u,0x%X,%u,%u,%u\n", c.tick, c.root_sprite, c.feat, c.item, (uint)c.cb, c.time, c.subs, c.result); total_microseconds += c.time; } @@ -141,7 +141,7 @@ std::string NewGRFProfiler::GetOutputFilename() const uint32 NewGRFProfiler::FinishAll() { - int max_ticks = 0; + uint64 max_ticks = 0; uint32 total_microseconds = 0; for (NewGRFProfiler &pr : _newgrf_profilers) { if (pr.active) { diff --git a/src/newgrf_profiling.h b/src/newgrf_profiling.h index e5b2813f59..15adb87830 100644 --- a/src/newgrf_profiling.h +++ b/src/newgrf_profiling.h @@ -45,14 +45,14 @@ struct NewGRFProfiler { uint32 result; ///< Result of callback uint32 subs; ///< Sub-calls to other sprite groups uint32 time; ///< Time taken for resolution (microseconds) - uint16 tick; ///< Game tick + uint64 tick; ///< Game tick CallbackID cb; ///< Callback ID GrfSpecFeature feat; ///< GRF feature being resolved for }; const GRFFile *grffile; ///< Which GRF is being profiled bool active; ///< Is this profiler collecting data - uint16 start_tick; ///< Tick number this profiler was started on + uint64 start_tick; ///< Tick number this profiler was started on Call cur_call; ///< Data for current call in progress std::vector calls; ///< All calls collected so far }; diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index 72d3f3d852..c1f627f10c 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -344,7 +344,8 @@ public: static const SaveLoad _gamelog_desc[] = { SLE_CONDVAR(LoggedAction, at, SLE_UINT8, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION), - SLE_VAR(LoggedAction, tick, SLE_UINT16), + SLE_CONDVAR(LoggedAction, tick, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER), + SLE_CONDVAR(LoggedAction, tick, SLE_UINT64, SLV_U64_TICK_COUNTER, SL_MAX_VERSION), SLEG_STRUCTLIST("action", SlGamelogAction), }; diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index 779e100989..f50b03fe41 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -74,7 +74,8 @@ static const SaveLoad _date_desc[] = { SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR("date", _date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_VAR("date_fract", _date_fract, SLE_UINT16), - SLEG_VAR("tick_counter", _tick_counter, SLE_UINT16), + SLEG_CONDVAR("tick_counter", _tick_counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER), + SLEG_CONDVAR("tick_counter", _tick_counter, SLE_UINT64, SLV_U64_TICK_COUNTER, SL_MAX_VERSION), SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index bab302dc8d..a419e4b344 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1609,7 +1609,7 @@ static const OldChunks main_chunk[] = { OCL_NULL( 2 ), ///< land_code, no longer in use OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ), - OCL_VAR ( OC_UINT16, 1, &_tick_counter ), + OCL_VAR ( OC_FILE_U16 | OC_VAR_U64, 1, &_tick_counter ), OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ), OCL_ASSERT( OC_TTO, 0x3A2E ), diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 0d4e0fb984..c189407f67 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -340,6 +340,7 @@ enum SaveLoadVersion : uint16 { SLV_LINKGRAPH_TRAVEL_TIME, ///< 297 PR#9457 v12.0-RC1 Store travel time in the linkgraph. SLV_DOCK_DOCKINGTILES, ///< 298 PR#9578 All tiles around docks may be docking tiles. SLV_REPAIR_OBJECT_DOCKING_TILES, ///< 299 PR#9594 v12.0 Fixing issue with docking tiles overlapping objects. + SLV_U64_TICK_COUNTER, ///< 300 PR#10035 Make _tick_counter 64bit to avoid wrapping. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/stdafx.h b/src/stdafx.h index 5e5a18144a..395a3bf6e4 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -303,13 +303,21 @@ #define PACK(type_dec) PACK_N(type_dec, 1) /* MSVCRT of course has to have a different syntax for long long *sigh* */ -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_MSC_VER) +# define OTTD_PRINTF64 "%I64d" +# define OTTD_PRINTF64U "%I64u" +# define OTTD_PRINTFHEX64 "%I64x" +# define PRINTF_SIZE "%Iu" +# define PRINTF_SIZEX "%IX" +#elif defined(__MINGW32__) # define OTTD_PRINTF64 "%I64d" +# define OTTD_PRINTF64U "%I64llu" # define OTTD_PRINTFHEX64 "%I64x" # define PRINTF_SIZE "%Iu" # define PRINTF_SIZEX "%IX" #else # define OTTD_PRINTF64 "%lld" +# define OTTD_PRINTF64U "%llu" # define OTTD_PRINTFHEX64 "%llx" # define PRINTF_SIZE "%zu" # define PRINTF_SIZEX "%zX"