Merge branch 'master' into jgrpp

# Conflicts:
#	src/company_gui.cpp
#	src/group_gui.cpp
#	src/newgrf.cpp
#	src/newgrf_debug_gui.cpp
#	src/saveload/saveload.cpp
pull/590/head
Jonathan G Rennison 9 months ago
commit 5a28405ced

@ -204,6 +204,7 @@ add_files(
group_cmd.cpp
group_gui.cpp
group_gui.h
group_gui_list.h
group_type.h
gui.h
guitimer_func.h

@ -275,19 +275,18 @@ static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
*/
static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
static char last_name[2][64] = { "", "" };
static std::string last_name[2] = { {}, {} };
if (a.engine_id != _last_engine[0]) {
_last_engine[0] = a.engine_id;
SetDParam(0, PackEngineNameDParam(a.engine_id, EngineNameContext::PurchaseList));
GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0]));
last_name[0] = GetString(STR_ENGINE_NAME);
}
if (b.engine_id != _last_engine[1]) {
_last_engine[1] = b.engine_id;
SetDParam(0, PackEngineNameDParam(b.engine_id, EngineNameContext::PurchaseList));
GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1]));
last_name[1] = GetString(STR_ENGINE_NAME);
}
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).

@ -37,6 +37,7 @@
#include "station_func.h"
#include "zoom_func.h"
#include "sortlist_type.h"
#include "group_gui_list.h"
#include "core/backup_type.hpp"
#include "widgets/company_widget.h"
@ -671,11 +672,6 @@ public:
}
};
typedef GUIList<const Group*> GUIGroupList;
/* cached values for GroupNameSorter to spare many GetString() calls */
static const Group *_last_group[2] = { nullptr, nullptr };
/** Company livery colour scheme window. */
struct SelectCompanyLiveryWindow : public Window {
private:
@ -738,27 +734,6 @@ private:
ShowDropDownList(this, std::move(list), sel, widget);
}
static bool GroupNameSorter(const Group * const &a, const Group * const &b)
{
static char last_name[2][64] = { "", "" };
if (a != _last_group[0]) {
_last_group[0] = a;
SetDParam(0, a->index);
GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
}
if (b != _last_group[1]) {
_last_group[1] = b;
SetDParam(0, b->index);
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
}
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
if (r == 0) return a->index < b->index;
return r < 0;
}
void AddChildren(GUIGroupList &source, GroupID parent, int indent)
{
for (const Group *g : source) {
@ -787,11 +762,7 @@ private:
}
list.ForceResort();
/* invalidate cached values for name sorter - group names could change */
_last_group[0] = _last_group[1] = nullptr;
list.Sort(&GroupNameSorter);
SortGUIGroupList(list);
AddChildren(list, INVALID_GROUP, 0);
}

@ -598,8 +598,6 @@ DEF_CONSOLE_CMD(ConChangeDirectory)
DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
{
const char *path;
if (argc == 0) {
IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
return true;
@ -609,8 +607,7 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
_console_file_list.ValidateFileList(true);
_console_file_list.InvalidateFileList();
FiosGetDescText(&path, nullptr);
IConsolePrint(CC_DEFAULT, path);
IConsolePrint(CC_DEFAULT, FiosGetCurrentPath().c_str());
return true;
}

@ -42,7 +42,6 @@ extern bool FiosIsRoot(const char *path);
extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
extern bool FiosIsHiddenFile(const struct dirent *ent);
extern void FiosGetDrives(FileList &file_list);
extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot);
/* get the name of an oldstyle savegame */
extern void GetOldSaveGameName(const std::string &file, char *title, const char *last);
@ -131,16 +130,11 @@ const FiosItem *FileList::FindItem(const std::string_view file)
}
/**
* Get descriptive texts. Returns the path and free space
* left on the device
* @param path string describing the path
* @param total_free total free space in megabytes, optional (can be nullptr)
* @return StringID describing the path (free space or failure)
* Get the current path/working directory.
*/
StringID FiosGetDescText(const char **path, uint64 *total_free)
std::string FiosGetCurrentPath()
{
*path = _fios_path->c_str();
return FiosGetDiskFreeSpace(*path, total_free) ? STR_SAVELOAD_BYTES_FREE : STR_ERROR_UNABLE_TO_READ_DRIVE;
return *_fios_path;
}
/**

@ -59,7 +59,8 @@ void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list);
bool FiosBrowseTo(const FiosItem *item);
StringID FiosGetDescText(const char **path, uint64 *total_free);
std::string FiosGetCurrentPath();
std::optional<uint64_t> FiosGetDiskFreeSpace(const std::string &path);
bool FiosDelete(const char *name);
std::string FiosMakeHeightmapName(const char *name);
std::string FiosMakeSavegameName(const char *name);

@ -427,19 +427,19 @@ public:
break;
case WID_SL_BACKGROUND: {
static const char *path = nullptr;
static StringID str = STR_ERROR_UNABLE_TO_READ_DRIVE;
static uint64 tot = 0;
static std::string path;
static std::optional<uint64_t> free_space = std::nullopt;
if (_fios_path_changed) {
str = FiosGetDescText(&path, &tot);
path = FiosGetCurrentPath();
free_space = FiosGetDiskFreeSpace(path);
_fios_path_changed = false;
}
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, str);
if (free_space.has_value()) SetDParam(0, free_space.value());
DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, free_space.has_value() ? STR_SAVELOAD_BYTES_FREE : STR_ERROR_UNABLE_TO_READ_DRIVE);
DrawString(ir.left, ir.right, ir.top, path, TC_BLACK);
break;
}

@ -29,6 +29,7 @@
#include "gfx_func.h"
#include "tbtr_template_gui_main.h"
#include "newgrf_debug.h"
#include "group_gui_list.h"
#include "widgets/group_widget.h"
@ -36,8 +37,6 @@
#include "safeguards.h"
typedef GUIList<const Group*> GUIGroupList;
static const NWidgetPart _nested_group_widgets[] = {
NWidget(NWID_HORIZONTAL), // Window header
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
@ -117,29 +116,28 @@ static const NWidgetPart _nested_group_widgets[] = {
EndContainer(),
};
/* cached values for GroupNameSorter to spare many GetString() calls */
static const Group *_last_group[2] = { nullptr, nullptr };
/** Sort the groups by their name */
bool GroupNameSorter(const Group * const &a, const Group * const &b)
void SortGUIGroupList(GUIGroupList &list)
{
static char last_name[2][64] = { "", "" };
if (a != _last_group[0]) {
_last_group[0] = a;
SetDParam(0, a->index);
GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
}
/* Sort the groups by their name */
const Group *last_group[2] = { nullptr, nullptr };
std::string last_name[2] = { {}, {} };
list.Sort([&](const Group * const &a, const Group * const &b) {
if (a != last_group[0]) {
last_group[0] = a;
SetDParam(0, a->index);
last_name[0] = GetString(STR_GROUP_NAME);
}
if (b != _last_group[1]) {
_last_group[1] = b;
SetDParam(0, b->index);
GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
}
if (b != last_group[1]) {
last_group[1] = b;
SetDParam(0, b->index);
last_name[1] = GetString(STR_GROUP_NAME);
}
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
if (r == 0) return a->index < b->index;
return r < 0;
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
if (r == 0) return a->index < b->index;
return r < 0;
});
}
class VehicleGroupWindow : public BaseVehicleListWindow {
@ -222,11 +220,7 @@ private:
this->SetWidgetDisabledState(WID_GL_COLLAPSE_ALL_GROUPS, !enable_collapse_all);
list.ForceResort();
/* invalidate cached values for name sorter - group names could change */
_last_group[0] = _last_group[1] = nullptr;
list.Sort(&GroupNameSorter);
SortGUIGroupList(list);
AddChildren(list, INVALID_GROUP, 0);

@ -0,0 +1,19 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file group_gui_list.h Group GUI lists. */
#ifndef GROUP_GUI_LIST_H
#define GROUP_GUI_LIST_H
#include "group.h"
#include "sortlist_type.h"
typedef GUIList<const Group*> GUIGroupList;
void SortGUIGroupList(GUIGroupList &list);
#endif /* GROUP_GUI_LIST_H */

@ -344,7 +344,7 @@ class NetworkContentListWindow : public Window, ContentCallback {
uint filesize_sum; ///< The sum of all selected file sizes
Scrollbar *vscroll; ///< Cache of the vertical scrollbar
static char content_type_strs[CONTENT_TYPE_END][64]; ///< Cached strings for all content types.
static std::string content_type_strs[CONTENT_TYPE_END]; ///< Cached strings for all content types.
/** Search external websites for content */
void OpenExternalSearch()
@ -1021,7 +1021,7 @@ NetworkContentListWindow::GUIContentList::FilterFunction * const NetworkContentL
&TypeOrSelectedFilter,
};
char NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END][64];
std::string NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END];
/**
* Build array of all strings corresponding to the content types.
@ -1029,7 +1029,7 @@ char NetworkContentListWindow::content_type_strs[CONTENT_TYPE_END][64];
void BuildContentTypeStringList()
{
for (int i = CONTENT_TYPE_BEGIN; i < CONTENT_TYPE_END; i++) {
GetString(NetworkContentListWindow::content_type_strs[i], STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS, lastof(NetworkContentListWindow::content_type_strs[i]));
NetworkContentListWindow::content_type_strs[i] = GetString(STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS);
}
}

@ -6306,15 +6306,6 @@ static void NewSpriteGroup(ByteReader *buf)
static CargoID TranslateCargo(uint8 feature, uint8 ctype)
{
if (feature == GSF_OBJECTS) {
switch (ctype) {
case 0: return 0;
case 0xFF: return CT_PURCHASE_OBJECT;
default:
grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
return CT_INVALID;
}
}
/* Special cargo types for purchase list and stations */
if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CT_DEFAULT_NA;
if (ctype == 0xFF) return CT_PURCHASE;
@ -6710,8 +6701,11 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
uint16 groupid = buf->ReadWord();
if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
ctype = TranslateCargo(GSF_OBJECTS, ctype);
if (ctype == CT_INVALID) continue;
/* The only valid option here is purchase list sprite groups. */
if (ctype != 0xFF) {
grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype);
continue;
}
for (uint i = 0; i < idcount; i++) {
ObjectSpec *spec = (objects[i] >= _cur.grffile->objectspec.size()) ? nullptr : _cur.grffile->objectspec[objects[i]].get();
@ -6721,7 +6715,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
continue;
}
spec->grf_prop.spritegroup[ctype] = GetGroupByID(groupid);
spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] = GetGroupByID(groupid);
}
}
@ -6741,9 +6735,9 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
continue;
}
spec->grf_prop.spritegroup[0] = GetGroupByID(groupid);
spec->grf_prop.grffile = _cur.grffile;
spec->grf_prop.local_id = objects[i];
spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_DEFAULT] = GetGroupByID(groupid);
spec->grf_prop.grffile = _cur.grffile;
spec->grf_prop.local_id = objects[i];
}
}

@ -72,14 +72,13 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params)
{
Rect tr = r.Shrink(WidgetDimensions::scaled.frametext);
if (c->error != nullptr) {
char message[512];
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages
SetDParamStr(1, c->filename);
SetDParamStr(2, c->error->data);
for (uint i = 0; i < c->error->param_value.size(); i++) {
SetDParam(3 + i, c->error->param_value[i]);
}
GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
std::string message = GetString(c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING);
SetDParamStr(0, message);
tr.top = DrawStringMultiLine(tr, c->error->severity);

@ -403,8 +403,8 @@ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj,
: ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, spec, tile, view)
{
this->town_scope = nullptr;
this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] != nullptr) ?
spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] : spec->grf_prop.spritegroup[0];
this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] != nullptr) ?
spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] : spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_DEFAULT];
}
ObjectResolverObject::~ObjectResolverObject()

@ -202,8 +202,8 @@ private:
/** Struct containing information relating to object classes. */
typedef NewGRFClass<ObjectSpec, ObjectClassID, OBJECT_CLASS_MAX> ObjectClass;
/** Mapping of purchase for objects. */
static const CargoID CT_PURCHASE_OBJECT = 1;
static const size_t OBJECT_SPRITE_GROUP_DEFAULT = 0;
static const size_t OBJECT_SPRITE_GROUP_PURCHASE = 1;
uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8 view = 0);

@ -95,32 +95,21 @@ void FiosGetDrives(FileList &file_list)
#endif
}
bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
std::optional<uint64_t> FiosGetDiskFreeSpace(const std::string &path)
{
#ifndef __INNOTEK_LIBC__
struct diskfree_t free;
char drive = path[0] - 'A' + 1;
if (tot != nullptr && _getdiskfree(drive, &free) == 0) {
*tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector;
return true;
if (_getdiskfree(drive, &free) == 0) {
return free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector;
}
#elif defined(HAS_STATVFS)
struct statvfs s;
return false;
#else
uint64 free = 0;
#ifdef HAS_STATVFS
{
struct statvfs s;
if (statvfs(path, &s) != 0) return false;
free = (uint64)s.f_frsize * s.f_bavail;
}
#endif
if (tot != nullptr) *tot = free;
return true;
if (statvfs(path.c_str(), &s) == 0) return static_cast<uint64_t>(s.f_frsize) * s.f_bavail;
#endif
return std::nullopt;
}
bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)

@ -75,23 +75,18 @@ void FiosGetDrives(FileList &file_list)
return;
}
bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
std::optional<uint64_t> FiosGetDiskFreeSpace(const std::string &path)
{
uint64 free = 0;
#ifdef __APPLE__
struct statfs s;
if (statfs(path, &s) != 0) return false;
free = (uint64)s.f_bsize * s.f_bavail;
if (statfs(path.c_str(), &s) == 0) return static_cast<uint64_t>(s.f_bsize) * s.f_bavail;
#elif defined(HAS_STATVFS)
struct statvfs s;
if (statvfs(path, &s) != 0) return false;
free = (uint64)s.f_frsize * s.f_bavail;
if (statvfs(path.c_str(), &s) == 0) return static_cast<uint64_t>(s.f_frsize) * s.f_bavail;
#endif
if (tot != nullptr) *tot = free;
return true;
return std::nullopt;
}
bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)

@ -256,16 +256,17 @@ bool FiosIsHiddenFile(const struct dirent *ent)
return (ent->dir->fd.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0;
}
bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
std::optional<uint64_t> FiosGetDiskFreeSpace(const std::string &path)
{
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
ULARGE_INTEGER bytes_free;
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr);
if (retval && tot != nullptr) *tot = bytes_free.QuadPart;
SetErrorMode(sem); // reset previous setting
return retval;
if (retval) return bytes_free.QuadPart;
return std::nullopt;
}
static int ParseCommandLine(char *line, char **argv, int max_argc)

@ -347,27 +347,18 @@ static WindowDesc _osk_desc(
*/
void GetKeyboardLayout()
{
char keyboard[2][OSK_KEYBOARD_ENTRIES * 4 + 1];
char errormark[2][OSK_KEYBOARD_ENTRIES + 1]; // used for marking invalid chars
std::string keyboard[2];
std::string errormark[2]; // used for marking invalid chars
bool has_error = false; // true when an invalid char is detected
if (_keyboard_opt[0].empty()) {
GetString(keyboard[0], STR_OSK_KEYBOARD_LAYOUT, lastof(keyboard[0]));
} else {
strecpy(keyboard[0], _keyboard_opt[0].c_str(), lastof(keyboard[0]));
}
if (_keyboard_opt[1].empty()) {
GetString(keyboard[1], STR_OSK_KEYBOARD_LAYOUT_CAPS, lastof(keyboard[1]));
} else {
strecpy(keyboard[1], _keyboard_opt[1].c_str(), lastof(keyboard[1]));
}
keyboard[0] = _keyboard_opt[0].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT) : _keyboard_opt[0];
keyboard[1] = _keyboard_opt[1].empty() ? GetString(STR_OSK_KEYBOARD_LAYOUT_CAPS) : _keyboard_opt[1];
for (uint j = 0; j < 2; j++) {
const char *kbd = keyboard[j];
auto kbd = keyboard[j].begin();
bool ended = false;
for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) {
_keyboard[j][i] = Utf8Consume(&kbd);
_keyboard[j][i] = Utf8Consume(kbd);
/* Be lenient when the last characters are missing (is quite normal) */
if (_keyboard[j][i] == '\0' || ended) {
@ -377,10 +368,10 @@ void GetKeyboardLayout()
}
if (IsPrintable(_keyboard[j][i])) {
errormark[j][i] = ' ';
errormark[j] += ' ';
} else {
has_error = true;
errormark[j][i] = '^';
errormark[j] += '^';
_keyboard[j][i] = ' ';
}
}
@ -388,10 +379,10 @@ void GetKeyboardLayout()
if (has_error) {
ShowInfoF("The keyboard layout you selected contains invalid chars. Please check those chars marked with ^.");
ShowInfoF("Normal keyboard: %s", keyboard[0]);
ShowInfoF(" %s", errormark[0]);
ShowInfoF("Caps Lock: %s", keyboard[1]);
ShowInfoF(" %s", errormark[1]);
ShowInfoF("Normal keyboard: %s", keyboard[0].c_str());
ShowInfoF(" %s", errormark[0].c_str());
ShowInfoF("Caps Lock: %s", keyboard[1].c_str());
ShowInfoF(" %s", errormark[1].c_str());
}
}

@ -39,6 +39,7 @@
#include "window_func.h"
#include "window_gui.h"
#include "zoom_func.h"
#include "group_gui_list.h"
#include "tbtr_template_gui_main.h"
#include "tbtr_template_gui_create.h"
@ -49,9 +50,6 @@
#include "safeguards.h"
typedef GUIList<const Group*> GUIGroupList;
enum TemplateReplaceWindowWidgets {
TRW_CAPTION,
@ -582,8 +580,7 @@ public:
}
list.ForceResort();
extern bool GroupNameSorter(const Group * const &a, const Group * const &b);
list.Sort(&GroupNameSorter);
SortGUIGroupList(list);
AddParents(&list, INVALID_GROUP, 0);

@ -19,8 +19,6 @@
#include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h"
typedef GUIList<const Group*> GUIGroupList;
void ShowTemplateReplaceWindow();
bool TemplateVehicleClicked(const TemplateVehicle *v);

@ -46,6 +46,7 @@
#include "core/geometry_func.hpp"
#include "infrastructure_func.h"
#include "zoom_func.h"
#include "group_gui_list.h"
#include "core/span_type.hpp"
#include "3rdparty/cpp-btree/btree_map.h"
@ -641,9 +642,6 @@ static const TraceRestrictDropDownListSet *GetSortedCargoTypeDropDownListSet()
*/
static DropDownList GetGroupDropDownList(Owner owner, GroupID group_id, int &selected)
{
typedef GUIList<const Group*> GUIGroupList;
extern bool GroupNameSorter(const Group * const &a, const Group * const &b);
GUIGroupList list;
for (const Group *g : Group::Iterate()) {
@ -653,7 +651,7 @@ static DropDownList GetGroupDropDownList(Owner owner, GroupID group_id, int &sel
}
list.ForceResort();
list.Sort(&GroupNameSorter);
SortGUIGroupList(list);
DropDownList dlist;
selected = -1;

@ -1546,18 +1546,18 @@ static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const
/** Sort vehicles by their name */
static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b)
{
static char last_name[2][64];
static std::string last_name[2] = { {}, {} };
if (a != _last_vehicle[0]) {
_last_vehicle[0] = a;
SetDParam(0, a->index);
GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0]));
last_name[0] = GetString(STR_VEHICLE_NAME);
}
if (b != _last_vehicle[1]) {
_last_vehicle[1] = b;
SetDParam(0, b->index);
GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1]));
last_name[1] = GetString(STR_VEHICLE_NAME);
}
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).

Loading…
Cancel
Save