diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 4813bd044b..3681aa23c6 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -216,6 +216,8 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const FontCache::Get(FS_MONO)->GetFontName() ); + buffer += seprintf(buffer, last, "Map size: 0x%X (%u x %u)%s\n\n", MapSize(), MapSizeX(), MapSizeY(), (!_m || !_me) ? ", NO MAP ALLOCATED" : ""); + buffer += seprintf(buffer, last, "AI Configuration (local: %i) (current: %i):\n", (int)_local_company, (int)_current_company); const Company *c; FOR_ALL_COMPANIES(c) { diff --git a/src/map.cpp b/src/map.cpp index 302e1b95e2..f6a8280bdd 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -402,3 +402,43 @@ uint GetClosestWaterDistance(TileIndex tile, bool water) return max_dist; } + +char *DumpTileInfo(char *b, const char *last, TileIndex tile) +{ + static const char *tile_type_names[16] = { + "MP_CLEAR", + "MP_RAILWAY", + "MP_ROAD", + "MP_HOUSE", + "MP_TREES", + "MP_STATION", + "MP_WATER", + "MP_VOID", + "MP_INDUSTRY", + "MP_TUNNELBRIDGE", + "MP_OBJECT", + "INVALID_B", + "INVALID_C", + "INVALID_D", + "INVALID_E", + "INVALID_F", + }; + + if (tile == INVALID_TILE) { + b += seprintf(b, last, "tile: %X (INVALID_TILE)", tile); + } else { + b += seprintf(b, last, "tile: %X (%u x %u)", tile, TileX(tile), TileY(tile)); + } + if (!_m || !_me) { + b += seprintf(b, last, ", NO MAP ALLOCATED"); + } else { + if (tile >= MapSize()) { + b += seprintf(b, last, ", TILE OUTSIDE MAP"); + } else { + b += seprintf(b, last, ", type: %02X (%s), height: %02X, data: %02X %04X %02X %02X %02X %02X %02X", + _m[tile].type, tile_type_names[GB(_m[tile].type, 4, 4)], _m[tile].height, + _m[tile].m1, _m[tile].m2, _m[tile].m3, _m[tile].m4, _m[tile].m5, _me[tile].m6, _me[tile].m7); + } + } + return b; +} diff --git a/src/map_func.h b/src/map_func.h index 7d17d6bed6..65ad725dff 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -439,4 +439,6 @@ static inline TileIndex RandomTileSeed(uint32 r) uint GetClosestWaterDistance(TileIndex tile, bool water); +char *DumpTileInfo(char *b, const char *last, TileIndex tile); + #endif /* MAP_FUNC_H */ diff --git a/src/openttd.cpp b/src/openttd.cpp index 3c26a2fead..656e70f4cd 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -133,7 +133,7 @@ void CDECL error(const char *s, ...) abort(); } -void CDECL assert_msg_error(int line, const char *file, const char *expr, const char *str, ...) +void CDECL assert_msg_error(int line, const char *file, const char *expr, const char *extra, const char *str, ...) { va_list va; char buf[2048]; @@ -141,6 +141,10 @@ void CDECL assert_msg_error(int line, const char *file, const char *expr, const char *b = buf; b += seprintf(b, lastof(buf), "Assertion failed at line %i of %s: %s\n\t", line, file, expr); + if (extra != nullptr) { + b += seprintf(b, lastof(buf), "%s\n\t", extra); + } + va_start(va, str); vseprintf(b, lastof(buf), str, va); va_end(va); @@ -152,6 +156,12 @@ void CDECL assert_msg_error(int line, const char *file, const char *expr, const abort(); } +const char *assert_tile_info(uint32 tile) { + static char buffer[128]; + DumpTileInfo(buffer, lastof(buffer), tile); + return buffer; +} + /** * Shows some information on the console/a popup box depending on the OS. * @param str the text to show. diff --git a/src/scope_info.cpp b/src/scope_info.cpp index c0327ce429..5bbc7aa85e 100644 --- a/src/scope_info.cpp +++ b/src/scope_info.cpp @@ -17,6 +17,7 @@ #include "vehicle_base.h" #include "station_base.h" #include "waypoint_base.h" +#include "map_func.h" #include "table/strings.h" #include "safeguards.h" @@ -116,3 +117,8 @@ const char *scope_dumper::StationInfo(const BaseStation *st) } return this->buffer; } + +const char *scope_dumper::TileInfo(TileIndex tile) +{ + return DumpTileInfo(this->buffer, lastof(this->buffer), tile); +} diff --git a/src/scope_info.h b/src/scope_info.h index a908804c74..d5d7c402d0 100644 --- a/src/scope_info.h +++ b/src/scope_info.h @@ -12,6 +12,8 @@ #ifndef SCOPE_INFO_H #define SCOPE_INFO_H +#include "tile_type.h" + #include #include @@ -70,6 +72,7 @@ struct scope_dumper { const char *CompanyInfo(int company_id); const char *VehicleInfo(const Vehicle *v); const char *StationInfo(const BaseStation *st); + const char *TileInfo(TileIndex tile); private: char buffer[256]; diff --git a/src/stdafx.h b/src/stdafx.h index a017cb39cd..1e6e849c28 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -438,7 +438,8 @@ typedef uint64 unaligned_uint64; void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2); void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2); -void NORETURN CDECL assert_msg_error(int line, const char *file, const char *expr, const char *str, ...) WARN_FORMAT(4, 5); +void NORETURN CDECL assert_msg_error(int line, const char *file, const char *expr, const char *extra, const char *str, ...) WARN_FORMAT(5, 6); +const char *assert_tile_info(uint32 tile); #define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__) /* For non-debug builds with assertions enabled use the special assertion handler: @@ -453,9 +454,13 @@ void NORETURN CDECL assert_msg_error(int line, const char *file, const char *exp /* Asserts are enabled if NDEBUG isn't defined, or if we are using MSVC and WITH_ASSERT is defined. */ #if !defined(NDEBUG) || (defined(_MSC_VER) && defined(WITH_ASSERT)) #define OTTD_ASSERT - #define assert_msg(expression, ...) if (unlikely(!(expression))) assert_msg_error(__LINE__, __FILE__, #expression, __VA_ARGS__); + #define assert_msg(expression, ...) if (unlikely(!(expression))) assert_msg_error(__LINE__, __FILE__, #expression, nullptr, __VA_ARGS__); + #define assert_msg_tile(expression, tile, ...) if (unlikely(!(expression))) assert_msg_error(__LINE__, __FILE__, #expression, assert_tile_info(tile), __VA_ARGS__); + #define assert_tile(expression, tile) if (unlikely(!(expression))) error("Assertion failed at line %i of %s: %s\n\t%s", __LINE__, __FILE__, #expression, assert_tile_info(tile)); #else #define assert_msg(expression, ...) + #define assert_msg_tile(expression, tile, ...) + #define assert_tile(expression, tile) #endif #if defined(MORPHOS) || defined(__NDS__) || defined(__DJGPP__)