diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -36,6 +36,8 @@ #include "newgrf_profiling.h" #include "console_func.h" #include "engine_base.h" +#include "road.h" +#include "rail.h" #include "game/game.hpp" #include "table/strings.h" #include @@ -2112,6 +2114,159 @@ DEF_CONSOLE_CMD(ConFramerateWindow) return true; } +static void ConDumpRoadTypes() +{ + IConsolePrintF(CC_DEFAULT, " Flags:"); + IConsolePrintF(CC_DEFAULT, " c = catenary"); + IConsolePrintF(CC_DEFAULT, " l = no level crossings"); + IConsolePrintF(CC_DEFAULT, " X = no houses"); + IConsolePrintF(CC_DEFAULT, " h = hidden"); + IConsolePrintF(CC_DEFAULT, " T = buildable by towns"); + + std::map grfs; + for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + if (rti->label == 0) continue; + uint32 grfid = 0; + const GRFFile *grf = rti->grffile[ROTSG_GROUND]; + if (grf != nullptr) { + grfid = grf->grfid; + grfs.emplace(grfid, grf); + } + IConsolePrintF(CC_DEFAULT, " %02u %s %c%c%c%c, Flags: %c%c%c%c%c, GRF: %08X, %s", + (uint) rt, + RoadTypeIsTram(rt) ? "Tram" : "Road", + rti->label >> 24, rti->label >> 16, rti->label >> 8, rti->label, + HasBit(rti->flags, ROTF_CATENARY) ? 'c' : '-', + HasBit(rti->flags, ROTF_NO_LEVEL_CROSSING) ? 'l' : '-', + HasBit(rti->flags, ROTF_NO_HOUSES) ? 'X' : '-', + HasBit(rti->flags, ROTF_HIDDEN) ? 'h' : '-', + HasBit(rti->flags, ROTF_TOWN_BUILD) ? 'T' : '-', + BSWAP32(grfid), + GetStringPtr(rti->strings.name) + ); + } + for (const auto &grf : grfs) { + IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename); + } +} + +static void ConDumpRailTypes() +{ + IConsolePrintF(CC_DEFAULT, " Flags:"); + IConsolePrintF(CC_DEFAULT, " c = catenary"); + IConsolePrintF(CC_DEFAULT, " l = no level crossings"); + IConsolePrintF(CC_DEFAULT, " h = hidden"); + IConsolePrintF(CC_DEFAULT, " s = no sprite combine"); + IConsolePrintF(CC_DEFAULT, " a = always allow 90 degree turns"); + IConsolePrintF(CC_DEFAULT, " d = always disallow 90 degree turns"); + + std::map grfs; + for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) { + const RailtypeInfo *rti = GetRailTypeInfo(rt); + if (rti->label == 0) continue; + uint32 grfid = 0; + const GRFFile *grf = rti->grffile[RTSG_GROUND]; + if (grf != nullptr) { + grfid = grf->grfid; + grfs.emplace(grfid, grf); + } + IConsolePrintF(CC_DEFAULT, " %02u %c%c%c%c, Flags: %c%c%c%c%c%c, GRF: %08X, %s", + (uint) rt, + rti->label >> 24, rti->label >> 16, rti->label >> 8, rti->label, + HasBit(rti->flags, RTF_CATENARY) ? 'c' : '-', + HasBit(rti->flags, RTF_NO_LEVEL_CROSSING) ? 'l' : '-', + HasBit(rti->flags, RTF_HIDDEN) ? 'h' : '-', + HasBit(rti->flags, RTF_NO_SPRITE_COMBINE) ? 's' : '-', + HasBit(rti->flags, RTF_ALLOW_90DEG) ? 'a' : '-', + HasBit(rti->flags, RTF_DISALLOW_90DEG) ? 'd' : '-', + BSWAP32(grfid), + GetStringPtr(rti->strings.name) + ); + } + for (const auto &grf : grfs) { + IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename); + } +} + +static void ConDumpCargoTypes() +{ + IConsolePrintF(CC_DEFAULT, " Cargo classes:"); + IConsolePrintF(CC_DEFAULT, " p = passenger"); + IConsolePrintF(CC_DEFAULT, " m = mail"); + IConsolePrintF(CC_DEFAULT, " x = express"); + IConsolePrintF(CC_DEFAULT, " a = armoured"); + IConsolePrintF(CC_DEFAULT, " b = bulk"); + IConsolePrintF(CC_DEFAULT, " g = piece goods"); + IConsolePrintF(CC_DEFAULT, " l = liquid"); + IConsolePrintF(CC_DEFAULT, " r = refrigerated"); + IConsolePrintF(CC_DEFAULT, " h = hazardous"); + IConsolePrintF(CC_DEFAULT, " c = covered/sheltered"); + IConsolePrintF(CC_DEFAULT, " S = special"); + + std::map grfs; + for (CargoID i = 0; i < NUM_CARGO; i++) { + const CargoSpec *spec = CargoSpec::Get(i); + if (!spec->IsValid()) continue; + uint32 grfid = 0; + const GRFFile *grf = spec->grffile; + if (grf != nullptr) { + grfid = grf->grfid; + grfs.emplace(grfid, grf); + } + IConsolePrintF(CC_DEFAULT, " %02u Bit: %2u, Label: %c%c%c%c, Callback mask: 0x%02X, Cargo class: %c%c%c%c%c%c%c%c%c%c%c, GRF: %08X, %s", + (uint) i, + spec->bitnum, + spec->label >> 24, spec->label >> 16, spec->label >> 8, spec->label, + spec->callback_mask, + (spec->classes & CC_PASSENGERS) != 0 ? 'p' : '-', + (spec->classes & CC_MAIL) != 0 ? 'm' : '-', + (spec->classes & CC_EXPRESS) != 0 ? 'x' : '-', + (spec->classes & CC_ARMOURED) != 0 ? 'a' : '-', + (spec->classes & CC_BULK) != 0 ? 'b' : '-', + (spec->classes & CC_PIECE_GOODS) != 0 ? 'g' : '-', + (spec->classes & CC_LIQUID) != 0 ? 'l' : '-', + (spec->classes & CC_REFRIGERATED) != 0 ? 'r' : '-', + (spec->classes & CC_HAZARDOUS) != 0 ? 'h' : '-', + (spec->classes & CC_COVERED) != 0 ? 'c' : '-', + (spec->classes & CC_SPECIAL) != 0 ? 'S' : '-', + BSWAP32(grfid), + GetStringPtr(spec->name) + ); + } + for (const auto &grf : grfs) { + IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename); + } +} + + +DEF_CONSOLE_CMD(ConDumpInfo) +{ + if (argc != 2) { + IConsoleHelp("Dump debugging information."); + IConsoleHelp("Usage: dump_info roadtypes|railtypes|cargotypes"); + IConsoleHelp(" Show information about road/tram types, rail types or cargo types."); + return true; + } + + if (strcasecmp(argv[1], "roadtypes") == 0) { + ConDumpRoadTypes(); + return true; + } + + if (strcasecmp(argv[1], "railtypes") == 0) { + ConDumpRailTypes(); + return true; + } + + if (strcasecmp(argv[1], "cargotypes") == 0) { + ConDumpCargoTypes(); + return true; + } + + return false; +} + /******************************* * console command registration *******************************/ @@ -2249,4 +2404,6 @@ void IConsoleStdLibRegister() /* NewGRF development stuff */ IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool); IConsoleCmdRegister("newgrf_profile", ConNewGRFProfile, ConHookNewGRFDeveloperTool); + + IConsoleCmdRegister("dump_info", ConDumpInfo); }