diff --git a/src/debug.h b/src/debug.h index b009b692889..51232533fae 100644 --- a/src/debug.h +++ b/src/debug.h @@ -10,12 +10,12 @@ #ifndef DEBUG_H #define DEBUG_H -#include "core/format.hpp" -#include +#include "cpu.h" +#include #include /* Debugging messages policy: - * These should be the severities used for direct Debug() calls + * These should be the severities used for direct DEBUG() calls * maximum debugging level should be 10 if really deep, deep * debugging is needed. * (there is room for exceptions, but you have to have a good cause): @@ -28,78 +28,92 @@ * 6.. - extremely detailed spamming */ -enum class DebugLevelID : uint8_t { - driver, - grf, - map, - misc, - net, - sprite, - oldloader, - yapf, - fontcache, - script, - sl, - gamelog, - desync, - yapfdesync, - console, - linkgraph, - sound, - command, -#ifdef RANDOM_DEBUG - random, - statecsum, -#endif - END, -}; -static constexpr uint DebugLevelCount = static_cast(DebugLevelID::END); - -extern std::array _debug_levels; - -inline int8_t GetDebugLevel(DebugLevelID id) { - return _debug_levels[static_cast(id)]; -} - -const char *GetDebugLevelName(DebugLevelID id); - -template -void DebugIntl(DebugLevelID dbg, int8_t level, fmt::format_string msg, T&&... args) -{ - extern void DebugIntlVFmt(DebugLevelID dbg, int8_t level, fmt::string_view msg, fmt::format_args args); - DebugIntlVFmt(dbg, level, msg, fmt::make_format_args(args...)); -} - /** - * Ouptut a line of debugging information. - * @param name The category of debug information. - * @param level The maximum debug level this message should be shown at. When the debug level for this category is set lower, then the message will not be shown. - * @param format_string The formatting string of the message. + * Output a line of debugging information. + * @param name Category + * @param level Debugging level, higher levels means more detailed information. */ -#define Debug(name, level, format_string, ...) do { if ((level) == 0 || GetDebugLevel(DebugLevelID::name) >= (level)) DebugIntl(DebugLevelID::name, level, FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__); } while (false) +#define DEBUG(name, level, ...) do { if ((level) == 0 || _debug_ ## name ## _level >= (level)) debug(#name, level, __VA_ARGS__); } while (false) + +extern int _debug_driver_level; +extern int _debug_grf_level; +extern int _debug_map_level; +extern int _debug_misc_level; +extern int _debug_net_level; +extern int _debug_sprite_level; +extern int _debug_oldloader_level; +extern int _debug_npf_level; +extern int _debug_yapf_level; +extern int _debug_fontcache_level; +extern int _debug_script_level; +extern int _debug_sl_level; +extern int _debug_gamelog_level; +extern int _debug_desync_level; +extern int _debug_yapfdesync_level; +extern int _debug_console_level; +extern int _debug_linkgraph_level; +extern int _debug_sound_level; +extern int _debug_command_level; +#ifdef RANDOM_DEBUG +extern int _debug_random_level; +extern int _debug_statecsum_level; +#endif extern const char *_savegame_DBGL_data; extern std::string _loadgame_DBGL_data; extern bool _save_DBGC_data; extern std::string _loadgame_DBGC_data; -void CDECL debug(DebugLevelID dbg, int8_t level, const char *format, ...) WARN_FORMAT(3, 4); -void debug_print(DebugLevelID dbg, int8_t level, std::string_view msg); +void CDECL debug(const char *dbg, int level, const char *format, ...) WARN_FORMAT(3, 4); +void debug_print(const char *dbg, int level, const char *buf); -void DumpDebugFacilityNames(struct format_target &output); -void SetDebugString(const char *s, void (*error_func)(std::string)); +char *DumpDebugFacilityNames(char *buf, char *last); +void SetDebugString(const char *s, void (*error_func)(const char *)); std::string GetDebugString(); /* Shorter form for passing filename and linenumber */ #define FILE_LINE __FILE__, __LINE__ -void ShowInfoI(std::string_view str); +/** TicToc profiling. + * Usage: + * static TicToc::State state("A name", 1); + * TicToc tt(state); + * --Do your code-- + */ +struct TicToc { + /** Persistent state for TicToc profiling. */ + struct State { + const std::string_view name; + const uint32_t max_count; + uint32_t count = 0; + uint64_t chrono_sum = 0; + + constexpr State(std::string_view name, uint32_t max_count) : name(name), max_count(max_count) { } + }; + + State &state; + std::chrono::high_resolution_clock::time_point chrono_start; ///< real time count. + + inline TicToc(State &state) : state(state), chrono_start(std::chrono::high_resolution_clock::now()) { } + + inline ~TicToc() + { + this->state.chrono_sum += (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->chrono_start)).count(); + if (++this->state.count == this->state.max_count) { + this->PrintAndReset(); + } + } + +private: + void PrintAndReset(); +}; -template -void ShowInfo(fmt::format_string msg, T&&... args) +void ShowInfoI(const char *str); +void CDECL ShowInfoF(const char *str, ...) WARN_FORMAT(1, 2); + +inline void ShowInfoI(const std::string &str) { - extern void ShowInfoVFmt(fmt::string_view msg, fmt::format_args args); - ShowInfoVFmt(msg, fmt::make_format_args(args...)); + ShowInfoI(str.c_str()); } struct log_prefix { @@ -109,32 +123,13 @@ struct log_prefix { char buffer[24]; }; +const char *GetLogPrefix(); + void ClearDesyncMsgLog(); void LogDesyncMsg(std::string msg); -void DumpDesyncMsgLog(struct format_target &buffer); +char *DumpDesyncMsgLog(char *buffer, const char *last); void DebugSendRemoteMessages(); void DebugReconsiderSendRemoteMessages(); -template -[[noreturn]] void AssertMsgError(int line, const char *file, const char *expr, fmt::format_string msg, T&&... args) -{ - [[noreturn]] extern void AssertMsgErrorVFmt(int line, const char *file, const char *expr, fmt::string_view msg, fmt::format_args args); - AssertMsgErrorVFmt(line, file, expr, msg, fmt::make_format_args(args...)); -} -template -[[noreturn]] void AssertMsgTileError(int line, const char *file, const char *expr, uint32_t tile, fmt::format_string msg, T&&... args) -{ - [[noreturn]] extern void AssertMsgTileErrorVFmt(int line, const char *file, const char *expr, uint32_t tile, fmt::string_view msg, fmt::format_args args); - AssertMsgTileErrorVFmt(line, file, expr, tile, msg, fmt::make_format_args(args...)); -} - -#if !defined(NDEBUG) || defined(WITH_ASSERT) -# define assert_msg(expression, ...) do { if (unlikely(!(expression))) AssertMsgError(__LINE__, __FILE__, #expression, __VA_ARGS__); } while (false) -# define assert_msg_tile(expression, tile, ...) do { if (unlikely(!(expression))) AssertMsgTileError(__LINE__, __FILE__, #expression, tile, __VA_ARGS__); } while (false) -#else -# define assert_msg(expression, ...) -# define assert_msg_tile(expression, tile, ...) -#endif - #endif /* DEBUG_H */ diff --git a/src/engine_type.h b/src/engine_type.h index bb426bb9113..ed84fa3d0c4 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -24,14 +24,14 @@ typedef uint16_t EngineID; ///< Unique identification number of an engine. struct Engine; /** Available types of rail vehicles. */ -enum RailVehicleTypes : uint8_t { +enum RailVehicleTypes { RAILVEH_SINGLEHEAD, ///< indicates a "standalone" locomotive RAILVEH_MULTIHEAD, ///< indicates a combination of two locomotives RAILVEH_WAGON, ///< simple wagon, not motorized }; /** Type of rail engine. */ -enum EngineClass : uint8_t { +enum EngineClass { EC_STEAM, ///< Steam rail engine. EC_DIESEL, ///< Diesel rail engine. EC_ELECTRIC, ///< Electric rail engine. @@ -41,42 +41,42 @@ enum EngineClass : uint8_t { /** Information about a rail vehicle. */ struct RailVehicleInfo { - uint8_t image_index; + byte image_index; RailVehicleTypes railveh_type; - uint8_t cost_factor; ///< Purchase cost factor; For multiheaded engines the sum of both engine prices. + byte cost_factor; ///< Purchase cost factor; For multiheaded engines the sum of both engine prices. RailType railtype; ///< Railtype, mangled if elrail is disabled. RailType intended_railtype; ///< Intended railtype, regardless of elrail being enabled or disabled. - uint8_t ai_passenger_only; ///< Bit value to tell AI that this engine is for passenger use only uint16_t max_speed; ///< Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h) uint16_t power; ///< Power of engine (hp); For multiheaded engines the sum of both engine powers. uint16_t weight; ///< Weight of vehicle (tons); For multiheaded engines the weight of each single engine. - uint8_t running_cost; ///< Running cost of engine; For multiheaded engines the sum of both running costs. + byte running_cost; ///< Running cost of engine; For multiheaded engines the sum of both running costs. Price running_cost_class; EngineClass engclass; ///< Class of engine for this vehicle - uint8_t capacity; ///< Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine. + byte capacity; ///< Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine. + byte ai_passenger_only; ///< Bit value to tell AI that this engine is for passenger use only uint16_t pow_wag_power; ///< Extra power applied to consist if wagon should be powered - uint8_t pow_wag_weight; ///< Extra weight applied to consist if wagon should be powered - uint8_t visual_effect; ///< Bitstuffed NewGRF visual effect data - uint8_t shorten_factor; ///< length on main map for this type is 8 - shorten_factor - uint8_t tractive_effort; ///< Tractive effort coefficient - uint8_t air_drag; ///< Coefficient of air drag - uint8_t user_def_data; ///< Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles + byte pow_wag_weight; ///< Extra weight applied to consist if wagon should be powered + byte visual_effect; ///< Bitstuffed NewGRF visual effect data + byte shorten_factor; ///< length on main map for this type is 8 - shorten_factor + byte tractive_effort; ///< Tractive effort coefficient + byte air_drag; ///< Coefficient of air drag + byte user_def_data; ///< Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles int16_t curve_speed_mod; ///< Modifier to maximum speed in curves (fixed-point binary with 8 fractional bits) }; /** Information about a ship vehicle. */ struct ShipVehicleInfo { - uint8_t image_index; - uint8_t cost_factor; - uint8_t running_cost; - uint8_t acceleration; ///< Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) - uint16_t max_speed; ///< Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) + byte image_index; + byte cost_factor; + uint8_t acceleration; ///< Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) + uint16_t max_speed; ///< Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) uint16_t capacity; + byte running_cost; SoundID sfx; - bool old_refittable; ///< Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask. - uint8_t visual_effect; ///< Bitstuffed NewGRF visual effect data - uint8_t ocean_speed_frac; ///< Fraction of maximum speed for ocean tiles. - uint8_t canal_speed_frac; ///< Fraction of maximum speed for canal/river tiles. + bool old_refittable; ///< Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask. + byte visual_effect; ///< Bitstuffed NewGRF visual effect data + byte ocean_speed_frac; ///< Fraction of maximum speed for ocean tiles. + byte canal_speed_frac; ///< Fraction of maximum speed for canal/river tiles. /** Apply ocean/canal speed fraction to a velocity */ uint ApplyWaterClassSpeedFrac(uint raw_speed, bool is_ocean) const @@ -99,40 +99,36 @@ enum AircraftSubTypeBits { /** Information about a aircraft vehicle. */ struct AircraftVehicleInfo { - uint8_t image_index; - uint8_t cost_factor; - uint8_t running_cost; - uint8_t subtype; ///< Type of aircraft. @see AircraftSubTypeBits + byte image_index; + byte cost_factor; + byte running_cost; + byte subtype; ///< Type of aircraft. @see AircraftSubTypeBits SoundID sfx; + byte acceleration; uint16_t max_speed; ///< Maximum speed (1 unit = 8 mph = 12.8 km-ish/h) - uint8_t acceleration; - uint8_t mail_capacity; ///< Mail capacity (bags). + byte mail_capacity; ///< Mail capacity (bags). uint16_t passenger_capacity; ///< Passenger capacity (persons). uint16_t max_range; ///< Maximum range of this aircraft. }; /** Information about a road vehicle. */ struct RoadVehicleInfo { - uint8_t image_index; - uint8_t cost_factor; - uint8_t running_cost; + byte image_index; + byte cost_factor; + byte running_cost; Price running_cost_class; SoundID sfx; uint16_t max_speed; ///< Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) - uint8_t capacity; + byte capacity; uint8_t weight; ///< Weight in 1/4t units uint8_t power; ///< Power in 10hp units uint8_t tractive_effort; ///< Coefficient of tractive effort uint8_t air_drag; ///< Coefficient of air drag - uint8_t visual_effect; ///< Bitstuffed NewGRF visual effect data - uint8_t shorten_factor; ///< length on main map for this type is 8 - shorten_factor + byte visual_effect; ///< Bitstuffed NewGRF visual effect data + byte shorten_factor; ///< length on main map for this type is 8 - shorten_factor RoadType roadtype; ///< Road type }; -/** - * Extra engine flags for NewGRF features. - * This is defined in the specification a 32 bit value, but most bits are not currently used. - */ enum class ExtraEngineFlags : uint8_t { None = 0, NoNews = (1U << 0), ///< No 'new vehicle' news will be generated. @@ -147,23 +143,23 @@ DECLARE_ENUM_AS_BIT_SET(ExtraEngineFlags); * @see table/engines.h */ struct EngineInfo { - CalTime::Date base_intro; ///< Basic date of engine introduction (without random parts). - YearDelta lifelength; ///< Lifetime of a single vehicle - YearDelta base_life; ///< Basic duration of engine availability (without random parts). \c 0xFF means infinite life. - uint8_t decay_speed; - uint8_t load_amount; - uint8_t climates; ///< Climates supported by the engine. + CalTime::Date base_intro; ///< Basic date of engine introduction (without random parts). + YearDelta lifelength; ///< Lifetime of a single vehicle + YearDelta base_life; ///< Basic duration of engine availability (without random parts). \c 0xFF means infinite life. + byte decay_speed; + byte load_amount; + byte climates; ///< Climates supported by the engine. CargoID cargo_type; std::variant cargo_label; CargoTypes refit_mask; - uint8_t refit_cost; - uint8_t misc_flags; ///< Miscellaneous flags. @see EngineMiscFlags + byte refit_cost; + byte misc_flags; ///< Miscellaneous flags. @see EngineMiscFlags uint16_t callback_mask; ///< Bitmask of vehicle callbacks that have to be called int8_t retire_early; ///< Number of years early to retire vehicle - ExtraEngineFlags extra_flags; StringID string_id; ///< Default name of engine uint16_t cargo_age_period; ///< Number of ticks before carried cargo is aged. EngineID variant_id; ///< Engine variant ID. If set, will be treated specially in purchase lists. + ExtraEngineFlags extra_flags; }; /**