diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b0150d3d5..d0e029607c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,7 +444,7 @@ if(WIN32) endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) - add_definitions(-D_SQ64) + add_definitions(-DPOINTER_IS_64BIT) endif() include(CreateRegression) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index a4d7bcb7d4..370757442b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -544,7 +544,7 @@ public: DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG); } else { // toggle renew_keep_length - DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING); + DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length"); } break; } diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index 779cc99543..7d126a43dc 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -198,7 +198,7 @@ bmno_full_transparency: m_colour = r == 0 ? m_colour : cmap; \ m_colour = m != 0 ? m_colour : srcm; \ } -#ifdef _SQ64 +#ifdef POINTER_IS_64BIT uint64 srcs = _mm_cvtsi128_si64(srcABCD); uint64 dsts; if (animated) dsts = _mm_cvtsi128_si64(dstABCD); @@ -449,7 +449,7 @@ bm_normal: else Draw(bp, zoom); } } else { -#ifdef _SQ64 +#ifdef POINTER_IS_64BIT if (sprite_flags & SF_TRANSLUCENT) { if (sprite_flags & SF_NO_ANIM) Draw(bp, zoom); else Draw(bp, zoom); diff --git a/src/blitter/32bpp_sse_func.hpp b/src/blitter/32bpp_sse_func.hpp index 1dca7b8fff..eb2fc1cab5 100644 --- a/src/blitter/32bpp_sse_func.hpp +++ b/src/blitter/32bpp_sse_func.hpp @@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into) static inline void LoadUint64(const uint64 value, __m128i &into) { -#ifdef _SQ64 +#ifdef POINTER_IS_64BIT into = _mm_cvtsi64_si128(value); #else #if (SSE_VERSION >= 4) @@ -303,7 +303,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel m_colour = r == 0 ? m_colour : cmap; \ m_colour = m != 0 ? m_colour : srcm; \ } -#ifdef _SQ64 +#ifdef POINTER_IS_64BIT uint64 srcs = _mm_cvtsi128_si64(srcABCD); uint64 remapped_src = 0; CMOV_REMAP(c0, 0, srcs, mvX2); diff --git a/src/cargopacket.h b/src/cargopacket.h index 9e26ba3367..d064149501 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -18,6 +18,7 @@ #include "vehicle_type.h" #include "company_type.h" #include "core/multimap.hpp" +#include "saveload/saveload.h" #include /** Unique identifier for a single cargo packet. */ @@ -33,7 +34,7 @@ struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets() template class CargoList; class StationCargoList; // forward-declare, so we can use it in VehicleCargoList. -extern const struct SaveLoad *GetCargoPacketDesc(); +extern SaveLoadTable GetCargoPacketDesc(); typedef uint32 TileOrStationID; @@ -68,7 +69,7 @@ private: friend class VehicleCargoList; friend class StationCargoList; /** We want this to be saved, right? */ - friend const struct SaveLoad *GetCargoPacketDesc(); + friend SaveLoadTable GetCargoPacketDesc(); friend void Load_CPDP(); public: /** Maximum number of items in a single cargo packet. */ @@ -342,7 +343,7 @@ public: /** The super class ought to know what it's doing. */ friend class CargoList; /** The vehicles have a cargo list (and we want that saved). */ - friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); + friend SaveLoadTable GetVehicleDescription(VehicleType vt); friend class CargoShift; friend class CargoTransfer; @@ -493,7 +494,7 @@ public: /** The super class ought to know what it's doing. */ friend class CargoList; /** The stations, via GoodsEntry, have a CargoList. */ - friend const struct SaveLoad *GetGoodsDesc(); + friend SaveLoadTable GetGoodsDesc(); friend class CargoLoad; friend class CargoTransfer; diff --git a/src/command.cpp b/src/command.cpp index b63b416141..7dd81541b6 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -536,6 +536,7 @@ enum CommandLogEntryFlag : uint16 { DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag) struct CommandLogEntry { + std::string text; TileIndex tile; uint32 p1; uint32 p2; @@ -550,8 +551,8 @@ struct CommandLogEntry { CommandLogEntry() { } - CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags) - : tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter), + CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, std::string text) + : text(text), tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter), current_company(_current_company), local_company(_local_company), log_flags(log_flags) { } }; @@ -607,11 +608,8 @@ static void DumpSubCommandLog(char *&buffer, const char *last, const CommandLog switch (entry.cmd & CMD_ID_MASK) { case CMD_CHANGE_SETTING: - buffer += seprintf(buffer, last, " [%s]", GetSettingNameByIndex(entry.p1)); - break; - case CMD_CHANGE_COMPANY_SETTING: - buffer += seprintf(buffer, last, " [%s]", GetCompanySettingNameByIndex(entry.p1)); + buffer += seprintf(buffer, last, " [%s]", entry.text.c_str()); break; } @@ -806,7 +804,7 @@ Money GetAvailableMoneyForCommand() return Company::Get(company)->money; } -static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags) +static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, const char *text) { if (res.Failed()) log_flags |= CLEF_CMD_FAILED; if (_generating_world) log_flags |= CLEF_GENERATING_WORLD; @@ -824,7 +822,16 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 return; } } - cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags); + + std::string str; + switch (cmd & CMD_ID_MASK) { + case CMD_CHANGE_SETTING: + case CMD_CHANGE_COMPANY_SETTING: + if (text != nullptr) str.assign(text); + break; + } + + cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags, std::move(str)); cmd_log.next = (cmd_log.next + 1) % cmd_log.log.size(); cmd_log.count++; } @@ -889,7 +896,7 @@ bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, C if (my_cmd) log_flags |= CLEF_MY_CMD; if (binary_length > 0) log_flags |= CLEF_BINARY; if (!random_state.Check()) log_flags |= CLEF_RANDOM; - AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags); + AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text); if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) { CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG; @@ -935,7 +942,7 @@ CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, ui if (my_cmd) log_flags |= CLEF_MY_CMD; if (binary_length > 0) log_flags |= CLEF_BINARY; if (!random_state.Check()) log_flags |= CLEF_RANDOM; - AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags); + AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text); if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) { CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG; diff --git a/src/console.cpp b/src/console.cpp index de297a68c1..8ea8b9200d 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -111,7 +111,7 @@ void IConsolePrint(TextColour colour_code, const char *string) * characters and (when applicable) assign it to the console buffer */ str = stredup(string); str_strip_colours(str); - str_validate(str, str + strlen(str)); + StrMakeValidInPlace(str); if (_network_dedicated) { NetworkAdminConsole("console", str); diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index a864307b64..bcebe26010 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -550,7 +550,7 @@ DEF_CONSOLE_CMD(ConClearBuffer) * Network Core Console Commands **********************************/ -static bool ConKickOrBan(const char *argv, bool ban, const char *reason) +static bool ConKickOrBan(const char *argv, bool ban, const std::string &reason) { uint n; @@ -604,7 +604,7 @@ DEF_CONSOLE_CMD(ConKick) if (argc != 2 && argc != 3) return false; /* No reason supplied for kicking */ - if (argc == 2) return ConKickOrBan(argv[1], false, nullptr); + if (argc == 2) return ConKickOrBan(argv[1], false, {}); /* Reason for kicking supplied */ size_t kick_message_length = strlen(argv[2]); @@ -628,7 +628,7 @@ DEF_CONSOLE_CMD(ConBan) if (argc != 2 && argc != 3) return false; /* No reason supplied for kicking */ - if (argc == 2) return ConKickOrBan(argv[1], true, nullptr); + if (argc == 2) return ConKickOrBan(argv[1], true, {}); /* Reason for kicking supplied */ size_t kick_message_length = strlen(argv[2]); @@ -827,7 +827,7 @@ DEF_CONSOLE_CMD(ConClientNickChange) return true; } - if (!NetworkServerChangeClientName(client_id, client_name.c_str())) { + if (!NetworkServerChangeClientName(client_id, client_name)) { IConsoleError("Cannot give a client a duplicate name"); } diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp new file mode 100644 index 0000000000..394b9ef38c --- /dev/null +++ b/src/core/span_type.hpp @@ -0,0 +1,98 @@ +/* + * 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 . + */ + +/** @file span_type.hpp Minimized implementation of C++20 std::span. */ + +#ifndef CORE_SPAN_TYPE_HPP +#define CORE_SPAN_TYPE_HPP + +/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */ + +/* Template to check if a template variable defines size() and data(). */ +template +struct has_size_and_data : std::false_type{}; +template +struct has_size_and_data +< + C, std::void_t< + decltype(std::size(std::declval())), + decltype(std::data(std::declval()))> +> : std::true_type{}; + +/* Template to check if two elements are compatible. */ +template +struct is_compatible_element : std::false_type {}; +template +struct is_compatible_element +< + C, E, std::void_t< + decltype(std::data(std::declval())), + typename std::remove_pointer()))>::type(*)[]> +> : std::is_convertible()))>::type(*)[], E(*)[]>{}; + +/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */ +template +struct is_compatible_container : std::bool_constant +< + has_size_and_data::value + && is_compatible_element::value +>{}; + +/** + * A trimmed down version of what std::span will be in C++20. + * + * It is fully forwards compatible, so if this codebase switches to C++20, + * all "span" instances can be replaced by "std::span" without loss of + * functionality. + * + * Currently it only supports basic functionality: + * - size() and friends + * - begin() and friends + * + * It is meant to simplify function parameters, where we only want to walk + * a continuous list. + */ +template +class span { +public: + typedef T element_type; + typedef typename std::remove_cv< T >::type value_type; + + typedef T &reference; + typedef T *pointer; + typedef const T &const_reference; + typedef const T *const_pointer; + + typedef pointer iterator; + typedef const_pointer const_iterator; + + typedef size_t size_type; + typedef std::ptrdiff_t difference_type; + + constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {} + + template::value), int>::type = 0> + constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {} + template::value && is_compatible_container::value), int>::type = 0> + constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {} + + constexpr size_t size() const noexcept { return static_cast( last - first ); } + constexpr std::ptrdiff_t ssize() const noexcept { return static_cast( last - first ); } + constexpr bool empty() const noexcept { return size() == 0; } + + constexpr iterator begin() const noexcept { return iterator(first); } + constexpr iterator end() const noexcept { return iterator(last); } + + constexpr const_iterator cbegin() const noexcept { return const_iterator(first); } + constexpr const_iterator cend() const noexcept { return const_iterator(last); } + +private: + pointer first; + pointer last; +}; + +#endif /* CORE_SPAN_TYPE_HPP */ diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 47ff98eb2f..6b17bfad35 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -153,7 +153,7 @@ char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const _openttd_revision_modified, _openttd_release_version, _openttd_newgrf_version, -#ifdef _SQ64 +#ifdef POINTER_IS_64BIT 64, #else 32, diff --git a/src/fios.cpp b/src/fios.cpp index 3cd0a9993e..b26e31e505 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -342,7 +342,7 @@ bool FiosFileScanner::AddFile(const std::string &filename, size_t basepath_lengt t = filename.c_str() + (ps == std::string::npos ? 0 : ps + 1); } strecpy(fios->title, t, lastof(fios->title)); - str_validate(fios->title, lastof(fios->title)); + StrMakeValidInPlace(fios->title, lastof(fios->title)); return true; } @@ -394,7 +394,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c std::string dirname = std::string(d_name) + PATHSEP; SetDParamStr(0, dirname); GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title)); - str_validate(fios->title, lastof(fios->title)); + StrMakeValidInPlace(fios->title, lastof(fios->title)); } } closedir(dir); @@ -446,7 +446,7 @@ static void GetFileTitle(const std::string &file, char *title, const char *last, size_t read = fread(title, 1, last - title, f); assert(title + read <= last); title[read] = '\0'; - str_validate(title, last); + StrMakeValidInPlace(title, last); FioFCloseFile(f); } diff --git a/src/highscore.cpp b/src/highscore.cpp index 4c5b6b1aa2..d40f2419de 100644 --- a/src/highscore.cpp +++ b/src/highscore.cpp @@ -170,7 +170,7 @@ void LoadFromHighScore() i = SP_SAVED_HIGHSCORE_END; break; } - str_validate(hs->company, lastof(hs->company), SVS_NONE); + StrMakeValidInPlace(hs->company, lastof(hs->company), SVS_NONE); hs->title = EndGameGetPerformanceTitleFromValue(hs->score); } } diff --git a/src/ini_load.cpp b/src/ini_load.cpp index 2b3f89bb26..9b8a4a31b8 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.cpp @@ -22,7 +22,7 @@ */ IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr) { - this->name = str_validate(name); + this->name = StrMakeValid(name); *parent->last_item = this; parent->last_item = &this->next; @@ -50,7 +50,7 @@ void IniItem::SetValue(const std::string_view value) */ IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr) { - this->name = str_validate(name); + this->name = StrMakeValid(name); this->last_item = &this->item; *parent->last_group = this; @@ -294,7 +294,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, if (!quoted && e == t) { item->value.reset(); } else { - item->value = str_validate(std::string(t)); + item->value = StrMakeValid(std::string(t)); } } else { /* it's an orphan item */ diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 473383d747..91832278c1 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -2639,7 +2639,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}서버 STR_NETWORK_ERROR_CLIENT_START :{WHITE}접속할 수 없습니다 STR_NETWORK_ERROR_TIMEOUT :{WHITE}접속자 #{NUM}의 입력 시간이 초과되었습니다 STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}프로토콜 오류가 발생되어 연결이 끊어졌습니다 -STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}접속자 이름을 지정하지 않았습니다. 접속자 이름은 멀티플레이 창 맨 위에서 설정할 수 있습니다. +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}접속자 이름을 설정하지 않았습니다. 이름은 멀티플레이 창의 상단에서 설정할 수 있습니다. STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}서버 이름을 지정하지 않았습니다. 서버 이름은 멀티플레이 창 맨 위에서 설정할 수 있습니다. STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}이 접속자의 게임 버전이 서버의 버전과 일치하지 않습니다 STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}잘못된 비밀번호입니다 diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index e8c47b50d4..90f71f4680 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -17,10 +17,10 @@ #include "../station_base.h" #include "../cargotype.h" #include "../date_func.h" +#include "../saveload/saveload.h" #include "linkgraph_type.h" #include -struct SaveLoad; class LinkGraph; /** @@ -531,8 +531,8 @@ public: protected: friend class LinkGraph::ConstNode; friend class LinkGraph::Node; - friend const SaveLoad *GetLinkGraphDesc(); - friend const SaveLoad *GetLinkGraphJobDesc(); + friend SaveLoadTable GetLinkGraphDesc(); + friend SaveLoadTable GetLinkGraphJobDesc(); friend void Save_LinkGraph(LinkGraph &lg); friend void Load_LinkGraph(LinkGraph &lg); diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index f0df823191..6eb942be7b 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -56,7 +56,7 @@ private: typedef std::vector NodeAnnotationVector; typedef SmallMatrix EdgeAnnotationMatrix; - friend const SaveLoad *GetLinkGraphJobDesc(); + friend SaveLoadTable GetLinkGraphJobDesc(); friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj); friend class LinkGraphSchedule; friend class LinkGraphJobGroup; diff --git a/src/linkgraph/linkgraphschedule.h b/src/linkgraph/linkgraphschedule.h index af61087ceb..1df20d380d 100644 --- a/src/linkgraph/linkgraphschedule.h +++ b/src/linkgraph/linkgraphschedule.h @@ -41,7 +41,7 @@ private: ~LinkGraphSchedule(); typedef std::list GraphList; typedef std::list> JobList; - friend const SaveLoad *GetLinkGraphScheduleDesc(); + friend SaveLoadTable GetLinkGraphScheduleDesc(); protected: std::unique_ptr handlers[6]; ///< Handlers to be run for each job. diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 49eb34824b..486b6e64ee 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1075,7 +1075,7 @@ struct QueryStringWindow : public Window char *last_of = &this->editbox.text.buf[this->editbox.text.max_bytes - 1]; GetString(this->editbox.text.buf, str, last_of); - str_validate(this->editbox.text.buf, last_of, SVS_NONE); + StrMakeValidInPlace(this->editbox.text.buf, last_of, SVS_NONE); /* Make sure the name isn't too long for the text buffer in the number of * characters (not bytes). max_chars also counts the '\0' characters. */ diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 21f50503c5..7222a14bb9 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -401,7 +401,7 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set assert(pos <= std::numeric_limits::max()); this->pos = static_cast(pos); - str_validate(bufp, last, settings); + StrMakeValidInPlace(bufp, last, settings); } /** @@ -430,7 +430,7 @@ std::string Packet::Recv_string(size_t length, StringValidationSettings settings while (this->Recv_uint8() != '\0') {} } - return str_validate(str, settings); + return StrMakeValid(str, settings); } /** @@ -455,7 +455,7 @@ void Packet::Recv_string(std::string &buffer, StringValidationSettings settings) size_t length = ttd_strnlen((const char *)(this->buffer.data() + this->pos), this->Size() - this->pos - 1); buffer.assign((const char *)(this->buffer.data() + this->pos), length); this->pos += (uint)length + 1; - str_validate_inplace(buffer, settings); + StrMakeValidInPlace(buffer, settings); } /** diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp index fe19622f78..73bc697c13 100644 --- a/src/network/core/tcp_admin.cpp +++ b/src/network/core/tcp_admin.cpp @@ -30,8 +30,6 @@ static_assert((int)CRR_END == (int)ADMIN_CRR_END); NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_STATUS_INACTIVE) { this->sock = s; - this->admin_name[0] = '\0'; - this->admin_version[0] = '\0'; } NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error) @@ -89,9 +87,9 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p) default: if (this->HasClientQuit()) { - DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name, this->admin_version); + DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name.c_str(), this->admin_version.c_str()); } else { - DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name, this->admin_version); + DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name.c_str(), this->admin_version.c_str()); } this->CloseConnection(); @@ -124,7 +122,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets() */ NetworkRecvStatus NetworkAdminSocketHandler::ReceiveInvalidPacket(PacketAdminType type) { - DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name, this->admin_version); + DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name.c_str(), this->admin_version.c_str()); return NETWORK_RECV_STATUS_MALFORMED_PACKET; } diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h index 8b4a738bfa..6d498ce5df 100644 --- a/src/network/core/tcp_admin.h +++ b/src/network/core/tcp_admin.h @@ -109,9 +109,9 @@ enum AdminCompanyRemoveReason { /** Main socket handler for admin related connections. */ class NetworkAdminSocketHandler : public NetworkTCPSocketHandler { protected: - char admin_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the admin. - char admin_version[NETWORK_REVISION_LENGTH]; ///< Version string of the admin. - AdminStatus status; ///< Status of this admin. + std::string admin_name; ///< Name of the admin. + std::string admin_version; ///< Version string of the admin. + AdminStatus status; ///< Status of this admin. NetworkRecvStatus ReceiveInvalidPacket(PacketAdminType type); diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 8a284daf38..5e3e2145f0 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -74,7 +74,7 @@ ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : Net ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() { _network_admins_connected--; - DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version); + DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name.c_str(), this->admin_version.c_str()); if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID; if (this->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { @@ -140,7 +140,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er std::string error_message = GetString(GetNetworkErrorMsg(error)); - DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, error_message.c_str()); + DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name.c_str(), this->admin_version.c_str(), error_message.c_str()); return this->CloseConnection(true); } @@ -473,7 +473,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action * Send a notification indicating the rcon command has completed. * @param command The original command sent. */ -NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *command) +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string_view command) { Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON_END); @@ -488,7 +488,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *comma * @param colour The colour of the text. * @param result The result of the command. */ -NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result) +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const std::string_view result) { Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON); @@ -503,14 +503,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p) { if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); - char command[NETWORK_RCONCOMMAND_LENGTH]; + std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH); - p->Recv_string(command, sizeof(command)); - - DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name, this->admin_version, command); + DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), command.c_str()); _redirect_console_to_admin = this->index; - IConsoleCmdExec(command); + IConsoleCmdExec(command.c_str()); _redirect_console_to_admin = INVALID_ADMIN_ID; return this->SendRconEnd(command); } @@ -519,11 +517,9 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Pack { if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); - char json[NETWORK_GAMESCRIPT_JSON_LENGTH]; + std::string json = p->Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH); - p->Recv_string(json, sizeof(json)); - - DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name, this->admin_version, json); + DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), json.c_str()); Game::NewEvent(new ScriptEventAdminPort(json)); return NETWORK_RECV_STATUS_OKAY; @@ -535,7 +531,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p) uint32 d1 = p->Recv_uint32(); - DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name, this->admin_version, d1); + DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name.c_str(), this->admin_version.c_str(), d1); return this->SendPong(d1); } @@ -545,13 +541,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p) * @param origin The origin of the string. * @param string The string that's put on the console. */ -NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string) +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string_view origin, const std::string_view string) { /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet * are bigger than the MTU, just ignore the message. Better safe than sorry. It should * never occur though as the longest strings are chat messages, which are still 30% * smaller than COMPAT_MTU. */ - if (strlen(origin) + strlen(string) + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY; + if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY; Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE); @@ -566,12 +562,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi * Send GameScript JSON output. * @param json The JSON string. */ -NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const char *json) +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json) { /* At the moment we cannot transmit anything larger than MTU. So we limit * the maximum amount of json data that can be sent. Account also for * the trailing \0 of the string */ - if (strlen(json) + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY; + if (json.size() + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY; Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT); @@ -661,17 +657,17 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p) return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); } - p->Recv_string(this->admin_name, sizeof(this->admin_name)); - p->Recv_string(this->admin_version, sizeof(this->admin_version)); + this->admin_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH); + this->admin_version = p->Recv_string(NETWORK_REVISION_LENGTH); - if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) { + if (this->admin_name.empty() || this->admin_version.empty()) { /* no name or version supplied */ return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); } this->status = ADMIN_STATUS_ACTIVE; - DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version); + DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name.c_str(), this->admin_version.c_str()); return this->SendProtocol(); } @@ -691,7 +687,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENC if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) { /* The server does not know of this UpdateType. */ - DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name, this->admin_version); + DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name.c_str(), this->admin_version.c_str()); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); } @@ -761,7 +757,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p) default: /* An unsupported "poll" update type. */ - DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version); + DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name.c_str(), this->admin_version.c_str()); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); } @@ -787,7 +783,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p) break; default: - DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version); + DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name.c_str(), this->admin_version.c_str()); return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET); } @@ -925,7 +921,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i * @param colour_code The colour of the string. * @param string The string to show. */ -void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string) +void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string) { ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string); } @@ -935,7 +931,7 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, * @param origin the origin of the message. * @param string the message as printed on the console. */ -void NetworkAdminConsole(const char *origin, const char *string) +void NetworkAdminConsole(const std::string_view origin, const std::string_view string) { for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { @@ -948,7 +944,7 @@ void NetworkAdminConsole(const char *origin, const char *string) * Send GameScript JSON to the admin network (if they did opt in for the respective update). * @param json The JSON data as received from the GameScript. */ -void NetworkAdminGameScript(const char *json) +void NetworkAdminGameScript(const std::string_view json) { for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) { diff --git a/src/network/network_admin.h b/src/network/network_admin.h index 009c7fb359..32c582bae5 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.h @@ -62,12 +62,12 @@ public: NetworkRecvStatus SendCompanyStats(); NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data); - NetworkRecvStatus SendRcon(uint16 colour, const char *command); - NetworkRecvStatus SendConsole(const char *origin, const char *command); - NetworkRecvStatus SendGameScript(const char *json); + NetworkRecvStatus SendRcon(uint16 colour, const std::string_view command); + NetworkRecvStatus SendConsole(const std::string_view origin, const std::string_view command); + NetworkRecvStatus SendGameScript(const std::string_view json); NetworkRecvStatus SendCmdNames(); NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp); - NetworkRecvStatus SendRconEnd(const char *command); + NetworkRecvStatus SendRconEnd(const std::string_view command); static void Send(); static void AcceptConnection(SOCKET s, const NetworkAddress &address); @@ -108,9 +108,9 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); void NetworkAdminUpdate(AdminUpdateFrequency freq); -void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string); -void NetworkAdminConsole(const char *origin, const char *string); -void NetworkAdminGameScript(const char *json); +void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string); +void NetworkAdminConsole(const std::string_view origin, const std::string_view string); +void NetworkAdminGameScript(const std::string_view json); void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp); #endif /* NETWORK_ADMIN_H */ diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 359676e847..06a9dc7ab4 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -612,7 +612,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str * Tell the server that we like to change the name of the client. * @param name The new name. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const std::string &name) { Packet *p = new Packet(PACKET_CLIENT_SET_NAME, SHRT_MAX); @@ -637,7 +637,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit() * @param pass The password for the remote command. * @param command The actual command. */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const char *command) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const std::string &command) { Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX); p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed)); @@ -1467,7 +1467,7 @@ void NetworkClient_Connected() * @param password The password. * @param command The command to execute. */ -void NetworkClientSendRcon(const std::string &password, const char *command) +void NetworkClientSendRcon(const std::string &password, const std::string &command) { MyClient::SendRCon(password, command); } @@ -1574,12 +1574,11 @@ void NetworkUpdateClientName(const std::string &client_name) /* Don't change the name if it is the same as the old name */ if (client_name.compare(ci->client_name) != 0) { if (!_network_server) { - MyClient::SendSetName(client_name.c_str()); + MyClient::SendSetName(client_name); } else { /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ - char temporary_name[NETWORK_CLIENT_NAME_LENGTH]; - strecpy(temporary_name, client_name.c_str(), lastof(temporary_name)); - if (NetworkFindName(temporary_name, lastof(temporary_name))) { + std::string temporary_name = client_name; + if (NetworkMakeClientNameUnique(temporary_name)) { NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); ci->client_name = temporary_name; NetworkUpdateClientInfo(CLIENT_ID_SERVER); diff --git a/src/network/network_client.h b/src/network/network_client.h index 97482a12b8..4c18c301cb 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -110,8 +110,8 @@ public: static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data); static NetworkRecvStatus SendSetPassword(const std::string &password); - static NetworkRecvStatus SendSetName(const char *name); - static NetworkRecvStatus SendRCon(const std::string &password, const char *command); + static NetworkRecvStatus SendSetName(const std::string &name); + static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command); static NetworkRecvStatus SendMove(CompanyID company, const std::string &password); static bool IsConnected(); diff --git a/src/network/network_func.h b/src/network/network_func.h index 845260da01..96daffead1 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -55,7 +55,7 @@ void NetworkClientsToSpectators(CompanyID cid); bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = ""); void NetworkClientJoinGame(); void NetworkClientRequestMove(CompanyID company, const std::string &pass = ""); -void NetworkClientSendRcon(const std::string &password, const char *command); +void NetworkClientSendRcon(const std::string &password, const std::string &command); void NetworkClientSendSettingsPassword(const std::string &password); void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData()); void NetworkClientSendDesyncMsg(const char *msg); @@ -75,16 +75,16 @@ void NetworkServerUpdateGameInfo(); void NetworkServerShowStatusToConsole(); bool NetworkServerStart(); void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci); -bool NetworkServerChangeClientName(ClientID client_id, const char *new_name); +bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name); void NetworkServerDoMove(ClientID client_id, CompanyID company_id); -void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string); +void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string); void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false); -void NetworkServerKickClient(ClientID client_id, const char *reason); -uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason); -uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason); +void NetworkServerKickClient(ClientID client_id, const std::string &reason); +uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason); +uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason); void NetworkInitChatMessage(); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 0edbae77e9..64c23d333b 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1676,7 +1676,7 @@ enum DropDownAdmin { */ static void AdminClientKickCallback(Window *w, bool confirmed) { - if (confirmed) NetworkServerKickClient(_admin_client_id, nullptr); + if (confirmed) NetworkServerKickClient(_admin_client_id, {}); } /** @@ -1686,7 +1686,7 @@ static void AdminClientKickCallback(Window *w, bool confirmed) */ static void AdminClientBanCallback(Window *w, bool confirmed) { - if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, nullptr); + if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, {}); } /** diff --git a/src/network/network_internal.h b/src/network/network_internal.h index a9beabf745..260984d84e 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -124,7 +124,7 @@ void ShowNetworkError(StringID error_string); void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", NetworkTextMessageData data = NetworkTextMessageData()); uint NetworkCalculateLag(const NetworkClientSocket *cs); StringID GetNetworkErrorMsg(NetworkErrorCode err); -bool NetworkFindName(char *new_name, const char *last); +bool NetworkMakeClientNameUnique(std::string &new_name); std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed); NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 64dec9d0d6..f2aa6f1b40 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -443,12 +443,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() * @param error The error to disconnect for. * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason) +NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const std::string &reason) { Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX); p->Send_uint8(error); - if (reason != nullptr) p->Send_string(reason); + if (!reason.empty()) p->Send_string(reason); this->SendPacket(p); StringID strid = GetNetworkErrorMsg(error); @@ -461,7 +461,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str()); - if (error == NETWORK_ERROR_KICKED && reason != nullptr) { + if (error == NETWORK_ERROR_KICKED && !reason.empty()) { NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid); } else { NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid); @@ -823,7 +823,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame() * @param colour The colour of the result. * @param command The command that was executed. */ -NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command) +NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const std::string &command) { Packet *p = new Packet(PACKET_SERVER_RCON, SHRT_MAX); @@ -928,8 +928,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } - char name[NETWORK_CLIENT_NAME_LENGTH]; - CompanyID playas; char client_revision[NETWORK_REVISION_LENGTH]; p->Recv_string(client_revision, sizeof(client_revision)); @@ -941,8 +939,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) return this->SendError(NETWORK_ERROR_WRONG_REVISION); } - p->Recv_string(name, sizeof(name)); - playas = (Owner)p->Recv_uint8(); + std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH); + CompanyID playas = (Owner)p->Recv_uint8(); if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; @@ -965,14 +963,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) break; } - if (!NetworkIsValidClientName(name)) { + if (!NetworkIsValidClientName(client_name)) { /* An invalid client name was given. However, the client ensures the name * is valid before it is sent over the network, so something went horribly * wrong. This is probably someone trying to troll us. */ return this->SendError(NETWORK_ERROR_INVALID_CLIENT_NAME); } - if (!NetworkFindName(name, lastof(name))) { // Change name if duplicate + if (!NetworkMakeClientNameUnique(client_name)) { // Change name if duplicate /* We could not create a name for this client */ return this->SendError(NETWORK_ERROR_NAME_IN_USE); } @@ -981,7 +979,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) NetworkClientInfo *ci = new NetworkClientInfo(this->client_id); this->SetInfo(ci); ci->join_date = _date; - ci->client_name = name; + ci->client_name = client_name; ci->client_playas = playas; DEBUG(desync, 1, "client: date{%08x; %02x; %02x}; client: %02x; company: %02x", _date, _date_fract, _tick_skip_counter, (int)ci->index, (int)ci->client_playas); @@ -1528,10 +1526,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } - char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkClientInfo *ci; - p->Recv_string(client_name, sizeof(client_name)); + std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH); ci = this->GetInfo(); if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; @@ -1545,7 +1542,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet } /* Display change */ - if (NetworkFindName(client_name, lastof(client_name))) { + if (NetworkMakeClientNameUnique(client_name)) { NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name); ci->client_name = client_name; NetworkUpdateClientInfo(ci->client_id); @@ -1558,15 +1555,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p) { if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); - char command[NETWORK_RCONCOMMAND_LENGTH]; - if (_settings_client.network.rcon_password.empty()) { NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied"); return NETWORK_RECV_STATUS_OKAY; } std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH); - p->Recv_string(command, sizeof(command)); + std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH); if (password != GenerateCompanyPasswordHash(_settings_client.network.rcon_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) { DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id); @@ -1574,10 +1569,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p) return NETWORK_RECV_STATUS_OKAY; } - DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command); + DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command.c_str()); _redirect_console_to_client = this->client_id; - IConsoleCmdExec(command); + IConsoleCmdExec(command.c_str()); _redirect_console_to_client = INVALID_CLIENT_ID; return NETWORK_RECV_STATUS_OKAY; } @@ -1837,42 +1832,40 @@ static void NetworkAutoCleanCompanies() /** * Check whether a name is unique, and otherwise try to make it unique. * @param new_name The name to check/modify. - * @param last The last writeable element of the buffer. * @return True if an unique name was achieved. */ -bool NetworkFindName(char *new_name, const char *last) +bool NetworkMakeClientNameUnique(std::string &name) { - bool found_name = false; + bool is_name_unique = false; uint number = 0; - char original_name[NETWORK_CLIENT_NAME_LENGTH]; + std::string original_name = name; - strecpy(original_name, new_name, lastof(original_name)); - - while (!found_name) { - found_name = true; + while (!is_name_unique) { + is_name_unique = true; for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (ci->client_name.compare(new_name) == 0) { + if (ci->client_name.compare(name) == 0) { /* Name already in use */ - found_name = false; + is_name_unique = false; break; } } /* Check if it is the same as the server-name */ const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); if (ci != nullptr) { - if (ci->client_name.compare(new_name) == 0) found_name = false; // name already in use + if (ci->client_name.compare(name) == 0) is_name_unique = false; // name already in use } - if (!found_name) { + if (!is_name_unique) { /* Try a new name ( #1, #2, and so on) */ + name = original_name + " #" + std::to_string(number); - /* Something's really wrong when there're more names than clients */ - if (number++ > MAX_CLIENTS) break; - seprintf(new_name, last, "%s #%d", original_name, number); + /* The constructed client name is larger than the limit, + * so... bail out as no valid name can be created. */ + if (name.size() >= NETWORK_CLIENT_NAME_LENGTH) return false; } } - return found_name; + return is_name_unique; } /** @@ -1881,7 +1874,7 @@ bool NetworkFindName(char *new_name, const char *last) * @param new_name the new name for the client * @return true iff the name was changed */ -bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) +bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name) { /* Check if the name's already in use */ for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { @@ -2213,7 +2206,7 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id) * @param colour_code The colour of the text. * @param string The actual reply. */ -void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string) +void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string) { NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string); } @@ -2223,7 +2216,7 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha * @param client_id The client to kick. * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -void NetworkServerKickClient(ClientID client_id, const char *reason) +void NetworkServerKickClient(ClientID client_id, const std::string &reason) { if (client_id == CLIENT_ID_SERVER) return; NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason); @@ -2235,7 +2228,7 @@ void NetworkServerKickClient(ClientID client_id, const char *reason) * @param ban Whether to ban or kick. * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason) +uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason) { return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason); } @@ -2246,7 +2239,7 @@ uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason) * @param ban Whether to ban or just kick. * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason) +uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason) { /* Add address to ban-list */ if (ban) { @@ -2270,7 +2263,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason) for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == CLIENT_ID_SERVER) continue; if (cs->client_id == _redirect_console_to_client) continue; - if (cs->client_address.IsInNetmask(ip)) { + if (cs->client_address.IsInNetmask(ip.c_str())) { NetworkServerKickClient(cs->client_id, reason); n++; } diff --git a/src/network/network_server.h b/src/network/network_server.h index 950d3b4250..96533f33f6 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -103,11 +103,11 @@ public: NetworkRecvStatus SendQuit(ClientID client_id); NetworkRecvStatus SendShutdown(); NetworkRecvStatus SendNewGame(); - NetworkRecvStatus SendRConResult(uint16 colour, const char *command); + NetworkRecvStatus SendRConResult(uint16 colour, const std::string &command); NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id); NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci); - NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr); + NetworkRecvStatus SendError(NetworkErrorCode error, const std::string &reason = {}); NetworkRecvStatus SendDesyncLog(const std::string &log); NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data); NetworkRecvStatus SendJoin(ClientID client_id); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index f7edc9c7ae..4f6dcdcef1 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2678,7 +2678,7 @@ static std::string ReadDWordAsString(ByteReader *reader) char output[5]; for (int i = 0; i < 4; i++) output[i] = reader->ReadByte(); output[4] = '\0'; - str_validate(output, lastof(output)); + StrMakeValidInPlace(output, lastof(output)); return std::string(output); } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 56b53bcb02..bd2106022e 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -254,9 +254,8 @@ static_assert(lengthof(_news_type_data) == NT_END); NewsDisplay NewsTypeData::GetDisplay() const { const SettingDesc *sd = GetSettingFromName(this->name); - assert(sd != nullptr); - void *ptr = GetVariableAddress(nullptr, &sd->save); - return (NewsDisplay)ReadValue(ptr, sd->save.conv); + assert(sd != nullptr && sd->IsIntSetting()); + return (NewsDisplay)sd->AsIntSetting()->Read(nullptr); } /** Window class displaying a news item. */ diff --git a/src/order_backup.h b/src/order_backup.h index c81de0d93d..d3539e1459 100644 --- a/src/order_backup.h +++ b/src/order_backup.h @@ -15,6 +15,7 @@ #include "tile_type.h" #include "vehicle_type.h" #include "base_consist.h" +#include "saveload/saveload.h" /** Unique identifier for an order backup. */ typedef uint8 OrderBackupID; @@ -34,7 +35,7 @@ static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31; */ struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist { private: - friend const struct SaveLoad *GetOrderBackupDescription(); ///< Saving and loading of order backups. + friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups. friend void Load_BKOR(); ///< Creating empty orders upon savegame loading. uint32 user; ///< The user that requested the backup. TileIndex tile; ///< Tile of the depot where the order was changed. diff --git a/src/order_base.h b/src/order_base.h index 07d738efb9..e62b950e93 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -19,6 +19,7 @@ #include "vehicle_type.h" #include "date_type.h" #include "schdispatch.h" +#include "saveload/saveload.h" #include #include @@ -62,9 +63,9 @@ struct OrderExtraInfo { */ struct Order : OrderPool::PoolItem<&_order_pool> { private: - friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. + friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. friend void Load_VEHS(); ///< Loading of ancient vehicles. - friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders. + friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders. friend void Load_ORDX(); ///< Saving and loading of orders. friend void Save_ORDX(); ///< Saving and loading of orders. friend void Load_VEOX(); ///< Saving and loading of orders. @@ -586,7 +587,7 @@ template T CargoMaskValueFilter(CargoTypes &cargo_mask, struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { private: friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain - friend const struct SaveLoad *GetOrderListDescription(); ///< Saving and loading of order lists. + friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists. friend void Ptrs_ORDL(); ///< Saving and loading of order lists. StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const; diff --git a/src/os/macosx/osx_stdafx.h b/src/os/macosx/osx_stdafx.h index 8246a70ef0..a7e6259dd6 100644 --- a/src/os/macosx/osx_stdafx.h +++ b/src/os/macosx/osx_stdafx.h @@ -74,8 +74,8 @@ #endif /* Check for mismatching 'architectures' */ -#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(_SQ64)) || (!defined(__LP64__) && defined(_SQ64))) -# error "Compiling 64 bits without _SQ64 set! (or vice versa)" +#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(POINTER_IS_64BIT)) || (!defined(__LP64__) && defined(POINTER_IS_64BIT))) +# error "Compiling 64 bits without POINTER_IS_64BIT set! (or vice versa)" #endif /* Name conflict */ diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index 0b2d8de6a5..8502341f47 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -174,7 +174,7 @@ int CDECL main(int argc, char *argv[]) SetRandomSeed(time(nullptr)); /* Make sure our arguments contain only valid UTF-8 characters. */ - for (int i = 0; i < argc; i++) ValidateString(argv[i]); + for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); return openttd_main(argc, argv); } diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 0f53fb1727..e0d7c7e31c 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -243,7 +243,7 @@ void CocoaReleaseAutoreleasePool(); int CDECL main(int argc, char *argv[]) { /* Make sure our arguments contain only valid UTF-8 characters. */ - for (int i = 0; i < argc; i++) ValidateString(argv[i]); + for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); #ifdef WITH_COCOA CocoaSetupAutoreleasePool(); diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 70716e8f3b..3c2ea2ff2b 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -436,7 +436,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi argc = ParseCommandLine(cmdline, argv, lengthof(argv)); /* Make sure our arguments contain only valid UTF-8 characters. */ - for (int i = 0; i < argc; i++) ValidateString(argv[i]); + for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); openttd_main(argc, argv); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index da91cf04e3..5150f77c99 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1970,15 +1970,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin last_suitable_trackdir = trackdir; } else if (!test_only && last_suitable_tile != INVALID_TILE && ret.GetErrorMessage() != STR_ERROR_CANNOT_MODIFY_TRACK_TRAIN_APPROACHING) { /* If a signal can't be placed, place it at the last possible position. */ - SB(p1, 0, 3, TrackdirToTrack(last_suitable_trackdir)); - ClrBit(p1, 17); + SB(param1, 0, 3, TrackdirToTrack(last_suitable_trackdir)); + ClrBit(param1, 17); /* Pick the correct orientation for the track direction. */ signals = 0; if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(last_suitable_trackdir); if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(last_suitable_trackdir); - ret = DoCommand(last_suitable_tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); + ret = DoCommand(last_suitable_tile, param1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); if (ret.Succeeded() && IsTileType(last_suitable_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(last_suitable_tile) == TrackdirToExitdir(last_suitable_trackdir)) { /* Blacklist far end of tunnel if we just actioned the near end */ tunnel_bridge_blacklist.push_back(GetOtherTunnelBridgeEnd(last_suitable_tile)); diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 3bc1d0f879..fcb78f2edd 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -30,7 +30,6 @@ static const SaveLoad _ai_company[] = { SLEG_SSTR(_ai_saveload_settings, SLE_STR), SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), SLEG_CONDVAR(_ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), - SLE_END() }; static void SaveReal_AIPL(int *index_ptr) diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 88f925cc5d..ef343fc179 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -21,7 +21,6 @@ static const SaveLoad _engine_renew_desc[] = { SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS), SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, SLV_175, SL_MAX_VERSION), - SLE_END() }; static void Save_ERNW() diff --git a/src/saveload/bridge_signal_sl.cpp b/src/saveload/bridge_signal_sl.cpp index 4c73478527..8a42b100bb 100644 --- a/src/saveload/bridge_signal_sl.cpp +++ b/src/saveload/bridge_signal_sl.cpp @@ -19,7 +19,6 @@ struct LongBridgeSignalStorageStub { static const SaveLoad _long_bridge_signal_storage_stub_desc[] = { SLE_VAR(LongBridgeSignalStorageStub, length, SLE_UINT32), - SLE_END() }; static void Load_XBSS() diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index 75f081eb25..3ca64d77ef 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -24,7 +24,6 @@ struct TempStorage { static const SaveLoad _cargomonitor_pair_desc[] = { SLE_VAR(TempStorage, number, SLE_UINT32), SLE_VAR(TempStorage, amount, SLE_UINT32), - SLE_END() }; static CargoMonitorID FixupCargoMonitor(CargoMonitorID number) diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 6861c3da96..27e5a193b7 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -108,7 +108,7 @@ extern btree::btree_map _cargo_packet_deferred_payments; * some of the variables itself are private. * @return the saveload description for CargoPackets. */ -const SaveLoad *GetCargoPacketDesc() +SaveLoadTable GetCargoPacketDesc() { static const SaveLoad _cargopacket_desc[] = { SLE_VAR(CargoPacket, source, SLE_UINT16), @@ -122,8 +122,6 @@ const SaveLoad *GetCargoPacketDesc() /* Used to be paid_for, but that got changed. */ SLE_CONDNULL(1, SL_MIN_VERSION, SLV_121), - - SLE_END() }; return _cargopacket_desc; } @@ -136,7 +134,7 @@ static void Save_CAPA() std::vector filtered_packet_desc = SlFilterObject(GetCargoPacketDesc()); for (CargoPacket *cp : CargoPacket::Iterate()) { SlSetArrayIndex(cp->index); - SlObjectSaveFiltered(cp, filtered_packet_desc.data()); + SlObjectSaveFiltered(cp, filtered_packet_desc); } } @@ -149,7 +147,7 @@ static void Load_CAPA() int index; while ((index = SlIterateArray()) != -1) { CargoPacket *cp = new (index) CargoPacket(); - SlObjectLoadFiltered(cp, filtered_packet_desc.data()); + SlObjectLoadFiltered(cp, filtered_packet_desc); } } diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index f73937a1c9..e9dc3d2530 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -79,7 +79,6 @@ static void Load_CHTX() SLE_STR(CheatsExtLoad, name, SLE_STRB, 256), SLE_VAR(CheatsExtLoad, cht.been_used, SLE_BOOL), SLE_VAR(CheatsExtLoad, cht.value, SLE_BOOL), - SLE_END() }; CheatsExtLoad current_cheat; @@ -122,7 +121,6 @@ static void Save_CHTX() SLE_STR(CheatsExtSave, name, SLE_STR, 0), SLE_VAR(CheatsExtSave, cht.been_used, SLE_BOOL), SLE_VAR(CheatsExtSave, cht.value, SLE_BOOL), - SLE_END() }; SlAutolength([](void *) { @@ -153,7 +151,6 @@ static const SaveLoad _settings_ext_save_desc[] = { SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), - SLE_END() }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 041af087ea..8bee3f3aa5 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -294,8 +294,6 @@ static const SaveLoad _company_desc[] = { SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION), SLE_CONDVAR_X(CompanyProperties, purchase_land_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUY_LAND_RATE_LIMIT)), SLE_CONDVAR_X(CompanyProperties, build_object_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUILD_OBJECT_RATE_LIMIT)), - - SLE_END() }; static const SaveLoad _company_settings_desc[] = { @@ -316,8 +314,6 @@ static const SaveLoad _company_settings_desc[] = { SLE_CONDVAR_X(Company, settings.vehicle.auto_timetable_by_default, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)), SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static const SaveLoad _company_settings_skip_desc[] = { @@ -339,8 +335,6 @@ static const SaveLoad _company_settings_skip_desc[] = { SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 2, 2)), // settings.vehicle.auto_timetable_by_default SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static const SaveLoad _company_economy_desc[] = { @@ -356,8 +350,6 @@ static const SaveLoad _company_economy_desc[] = { SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES), SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), - - SLE_END() }; /* We do need to read this single value, as the bigger it gets, the more data is stored */ @@ -393,7 +385,6 @@ static const SaveLoad _company_ai_desc[] = { SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107), SLE_CONDNULL(64, SLV_2, SLV_107), - SLE_END() }; static const SaveLoad _company_ai_build_rec_desc[] = { @@ -402,14 +393,12 @@ static const SaveLoad _company_ai_build_rec_desc[] = { SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), SLE_CONDNULL(4, SLV_6, SLV_107), SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107), - SLE_END() }; static const SaveLoad _company_livery_desc[] = { SLE_CONDVAR(Livery, in_use, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION), - SLE_END() }; static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops) diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index e2560422b9..9c64e1f93e 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -26,7 +26,6 @@ static const SaveLoad _depot_desc[] = { SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION), SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)), - SLE_END() }; static void Save_DEPT() diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index a913b0c73a..67a9a187c5 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -47,7 +47,6 @@ static const SaveLoad _economy_desc[] = { SLE_VAR(Economy, infl_amount_pr, SLE_UINT8), SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, SLV_102, SL_MAX_VERSION), SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), - SLE_END() }; /** Economy variables */ @@ -68,7 +67,6 @@ static const SaveLoad _cargopayment_desc[] = { SLE_VAR(CargoPayment, route_profit, SLE_INT64), SLE_VAR(CargoPayment, visual_profit, SLE_INT64), SLE_CONDVAR_X(CargoPayment, visual_transfer, SLE_INT64, SLV_181, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_CHILLPP)), - SLE_END() }; static void Save_CAPY() diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 77635f6a1c..c0229f9bf6 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -43,8 +43,6 @@ static const SaveLoad _engine_desc[] = { SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static std::vector _temp_engine; @@ -174,7 +172,6 @@ static const SaveLoad _engine_id_mapping_desc[] = { SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16), SLE_VAR(EngineIDMapping, type, SLE_UINT8), SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8), - SLE_END() }; static void Save_EIDS() diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 863d80c960..f0744df3a6 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -463,7 +463,6 @@ static void Save_SLXI() static const SaveLoad _xlsi_sub_chunk_desc[] = { SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0), - SLE_END() }; // calculate lengths @@ -550,9 +549,8 @@ static void Load_SLXI() if (chunk_flags != 0) SlErrorCorruptFmt("SLXI chunk: unknown chunk header flags: 0x%X", chunk_flags); char name_buffer[256]; - const SaveLoadGlobVarList xlsi_sub_chunk_name_desc[] = { + const SaveLoad xlsi_sub_chunk_name_desc[] = { SLEG_STR(name_buffer, SLE_STRB), - SLEG_END() }; auto version_error = [](StringID str, const char *feature, int64 p1, int64 p2) { diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 00ca6d9ab9..055a5fbfc4 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -30,7 +30,6 @@ static const SaveLoad _game_script[] = { SLEG_SSTR(_game_saveload_settings, SLE_STR), SLEG_VAR(_game_saveload_version, SLE_UINT32), SLEG_VAR(_game_saveload_is_random, SLE_BOOL), - SLE_END() }; static void SaveReal_GSDT(int *index_ptr) @@ -117,12 +116,10 @@ static uint _game_saveload_strings; static const SaveLoad _game_language_header[] = { SLEG_SSTR(_game_saveload_string, SLE_STR), SLEG_VAR(_game_saveload_strings, SLE_UINT32), - SLE_END() }; static const SaveLoad _game_language_string[] = { SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), - SLE_END() }; static void SaveReal_GSTR(const LanguageStrings *ls) diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index 10a71e9b72..581ef41c31 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -18,13 +18,11 @@ static const SaveLoad _glog_action_desc[] = { SLE_VAR(LoggedAction, tick, SLE_UINT16), - SLE_END() }; static const SaveLoad _glog_mode_desc[] = { SLE_VAR(LoggedChange, mode.mode, SLE_UINT8), SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8), - SLE_END() }; static char old_revision_text[GAMELOG_REVISION_LENGTH]; @@ -35,62 +33,53 @@ static const SaveLoad _glog_revision_desc[] = { SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32), SLE_VAR(LoggedChange, revision.slver, SLE_UINT16), SLE_VAR(LoggedChange, revision.modified, SLE_UINT8), - SLE_END() }; static const SaveLoad _glog_oldver_desc[] = { SLE_VAR(LoggedChange, oldver.type, SLE_UINT32), SLE_VAR(LoggedChange, oldver.version, SLE_UINT32), - SLE_END() }; static const SaveLoad _glog_setting_desc[] = { SLE_STR(LoggedChange, setting.name, SLE_STR, 128), SLE_VAR(LoggedChange, setting.oldval, SLE_INT32), SLE_VAR(LoggedChange, setting.newval, SLE_INT32), - SLE_END() }; static const SaveLoad _glog_grfadd_desc[] = { SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ), SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16), - SLE_END() }; static const SaveLoad _glog_grfrem_desc[] = { SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32), - SLE_END() }; static const SaveLoad _glog_grfcompat_desc[] = { SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ), SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16), - SLE_END() }; static const SaveLoad _glog_grfparam_desc[] = { SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32), - SLE_END() }; static const SaveLoad _glog_grfmove_desc[] = { SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32), - SLE_END() }; static const SaveLoad _glog_grfbug_desc[] = { SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64), SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8), - SLE_END() }; static const SaveLoad _glog_emergency_desc[] = { - SLE_END() + SLE_CONDNULL(0, SL_MIN_VERSION, SL_MIN_VERSION), // Just an empty list, to keep the rest of the code easier. }; -static const SaveLoad * const _glog_desc[] = { +static const SaveLoadTable _glog_desc[] = { _glog_mode_desc, _glog_revision_desc, _glog_oldver_desc, diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 4ee9f39ebe..2c9d8fde9f 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -21,7 +21,6 @@ static const SaveLoad _goals_desc[] = { SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION), SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION), - SLE_END() }; static void Save_GOAL() diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index c5f7e2b507..a6ae263f9d 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -26,7 +26,6 @@ static const SaveLoad _group_desc[] = { SLE_CONDVAR(Group, livery.colour1, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION), SLE_CONDVAR(Group, livery.colour2, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION), SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION), - SLE_END() }; static void Save_GRPS() diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 6f41e34552..a59524de67 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -75,8 +75,6 @@ static const SaveLoad _industry_desc[] = { SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION), SLE_CONDNULL(32, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static void Save_INDY() @@ -139,7 +137,6 @@ static void Ptrs_INDY() /** Description of the data to save and load in #IndustryBuildData. */ static const SaveLoad _industry_builder_desc[] = { SLEG_VAR(_industry_builder.wanted_inds, SLE_UINT32), - SLEG_END() }; /** Load/save industry builder. */ @@ -155,7 +152,6 @@ static const SaveLoad _industrytype_builder_desc[] = { SLE_VAR(IndustryTypeBuildData, target_count, SLE_UINT16), SLE_VAR(IndustryTypeBuildData, max_wait, SLE_UINT16), SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16), - SLE_END() }; /** Save industry-type build data. */ diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index ac7cb1b793..01cb2915ed 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -104,7 +104,6 @@ struct LabelObject { static const SaveLoad _label_object_desc[] = { SLE_VAR(LabelObject, label, SLE_UINT32), - SLE_END(), }; static void Save_RAIL() diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index cd6376c9ad..0e8711b821 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -28,13 +28,12 @@ static uint16 _num_nodes; * Get a SaveLoad array for a link graph. * @return SaveLoad array for link graph. */ -const SaveLoad *GetLinkGraphDesc() +SaveLoadTable GetLinkGraphDesc() { static const SaveLoad link_graph_desc[] = { SLE_VAR(LinkGraph, last_compression, SLE_INT32), SLEG_VAR(_num_nodes, SLE_UINT16), SLE_VAR(LinkGraph, cargo, SLE_UINT8), - SLE_END() }; return link_graph_desc; } @@ -55,7 +54,7 @@ void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj) * Of course the settings have to be saved and loaded, too, to avoid desyncs. * @return Array of SaveLoad structs. */ -const SaveLoad *GetLinkGraphJobDesc() +SaveLoadTable GetLinkGraphJobDesc() { static std::vector saveloads; static const char *prefix = "linkgraph."; @@ -84,28 +83,25 @@ const SaveLoad *GetLinkGraphJobDesc() SLE_VAR(LinkGraphJob, join_date_ticks, SLE_INT32), SLE_CONDVAR_X(LinkGraphJob, start_date_ticks, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE)), SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16), - SLE_END() }; - int i = 0; - do { - saveloads.push_back(job_desc[i++]); - } while (saveloads.back().cmd != SL_END); + for (auto &sld : job_desc) { + saveloads.push_back(sld); + } } - return &saveloads[0]; + return saveloads; } /** * Get a SaveLoad array for the link graph schedule. * @return SaveLoad array for the link graph schedule. */ -const SaveLoad *GetLinkGraphScheduleDesc() +SaveLoadTable GetLinkGraphScheduleDesc() { static const SaveLoad schedule_desc[] = { SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH), SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB), - SLE_END() }; return schedule_desc; } @@ -121,7 +117,6 @@ static const SaveLoad _node_desc[] = { SLE_VAR(Node, demand, SLE_UINT32), SLE_VAR(Node, station, SLE_UINT16), SLE_VAR(Node, last_update, SLE_INT32), - SLE_END() }; /** @@ -134,7 +129,6 @@ static const SaveLoad _edge_desc[] = { SLE_VAR(Edge, last_unrestricted_update, SLE_INT32), SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), SLE_VAR(Edge, next_edge, SLE_UINT16), - SLE_END() }; std::vector _filtered_node_desc; @@ -157,10 +151,10 @@ void Save_LinkGraph(LinkGraph &lg) uint16 size = lg.Size(); for (NodeID from = 0; from < size; ++from) { Node *node = &lg.nodes[from]; - SlObjectSaveFiltered(node, _filtered_node_desc.data()); + SlObjectSaveFiltered(node, _filtered_node_desc); /* ... but as that wasted a lot of space we save a sparse matrix now. */ for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { - SlObjectSaveFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); + SlObjectSaveFiltered(&lg.edges[from][to], _filtered_edge_desc); } } } @@ -174,17 +168,17 @@ void Load_LinkGraph(LinkGraph &lg) uint size = lg.Size(); for (NodeID from = 0; from < size; ++from) { Node *node = &lg.nodes[from]; - SlObjectLoadFiltered(node, _filtered_node_desc.data()); + SlObjectLoadFiltered(node, _filtered_node_desc); if (IsSavegameVersionBefore(SLV_191)) { /* We used to save the full matrix ... */ for (NodeID to = 0; to < size; ++to) { - SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); + SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc); } } else { /* ... but as that wasted a lot of space we save a sparse matrix now. */ for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { if (to >= size) SlErrorCorrupt("Link graph structure overflow"); - SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc.data()); + SlObjectLoadFiltered(&lg.edges[from][to], _filtered_edge_desc); } } } @@ -196,7 +190,7 @@ void Load_LinkGraph(LinkGraph &lg) */ static void DoSave_LGRJ(LinkGraphJob *lgj) { - SlObjectSaveFiltered(lgj, _filtered_job_desc.data()); + SlObjectSaveFiltered(lgj, _filtered_job_desc); _num_nodes = lgj->Size(); SlObjectSaveFiltered(const_cast(&lgj->Graph()), GetLinkGraphDesc()); // GetLinkGraphDesc has no conditionals Save_LinkGraph(const_cast(lgj->Graph())); @@ -245,7 +239,7 @@ static void Load_LGRJ() NOT_REACHED(); } LinkGraphJob *lgj = new (index) LinkGraphJob(); - SlObjectLoadFiltered(lgj, _filtered_job_desc.data()); + SlObjectLoadFiltered(lgj, _filtered_job_desc); if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) { GetLinkGraphJobDayLengthScaleAfterLoad(lgj); } diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index b0d1c01913..e90cde0d88 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -25,10 +25,9 @@ static uint32 _map_dim_y; extern bool _sl_maybe_chillpp; -static const SaveLoadGlobVarList _map_dimensions[] = { +static const SaveLoad _map_dimensions[] = { SLEG_CONDVAR(_map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLEG_END() }; static void Save_MAPS() diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index ce50cc5d8d..d120fa95e9 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -72,7 +72,7 @@ void ResetViewportAfterLoadGame() byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame version 162. -static const SaveLoadGlobVarList _date_desc[] = { +static const SaveLoad _date_desc[] = { SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR(_date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_VAR(_date_fract, SLE_UINT16), @@ -99,10 +99,9 @@ static const SaveLoadGlobVarList _date_desc[] = { SLEG_CONDVAR_X(_road_layout_change_counter, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)), SLEG_CONDVAR_X(_extra_aspects, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), SLE_CONDNULL(4, SLV_11, SLV_120), - SLEG_END() }; -static const SaveLoadGlobVarList _date_check_desc[] = { +static const SaveLoad _date_check_desc[] = { SLEG_CONDVAR(_load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR(_load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLE_NULL(2), // _date_fract @@ -129,7 +128,6 @@ static const SaveLoadGlobVarList _date_check_desc[] = { SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)), // _road_layout_change_counter SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4)), // _extra_aspects SLE_CONDNULL(4, SLV_11, SLV_120), - SLEG_END() }; /* Save load date related variables as well as persistent tick counters @@ -149,13 +147,12 @@ static void Check_DATE() } -static const SaveLoadGlobVarList _view_desc[] = { +static const SaveLoad _view_desc[] = { SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, SLV_6, SL_MAX_VERSION), SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8), - SLEG_END() }; static void SaveLoad_VIEW() diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 060006bf30..709496691b 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -21,7 +21,6 @@ static const SaveLoad _newgrf_mapping_desc[] = { SLE_VAR(EntityIDMapping, grfid, SLE_UINT32), SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8), SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8), - SLE_END() }; /** @@ -69,7 +68,6 @@ static const SaveLoad _grfconfig_desc[] = { SLE_VAR(GRFConfig, num_params, SLE_UINT8), SLE_CONDVAR(GRFConfig, palette, SLE_UINT8, SLV_101, SL_MAX_VERSION), SLEG_CONDSSTR_X(_grf_name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_NEWGRF_INFO_EXTRA)), - SLE_END() }; diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index 2c385b6552..40ca8cd110 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -25,8 +25,6 @@ static const SaveLoad _object_desc[] = { SLE_CONDVAR(Object, colour, SLE_UINT8, SLV_148, SL_MAX_VERSION), SLE_CONDVAR(Object, view, SLE_UINT8, SLV_155, SL_MAX_VERSION), SLE_CONDVAR(Object, type, SLE_UINT16, SLV_186, SL_MAX_VERSION), - - SLE_END() }; static void Save_OBJS() diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index 38b2080ef7..376ba2e060 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.cpp @@ -236,7 +236,7 @@ static inline bool CheckOldSavegameType(FILE *f, char *temp, const char *last, u bool ret = VerifyOldNameChecksum(temp, len); temp[len - 2] = '\0'; // name is null-terminated in savegame, but it's better to be sure - str_validate(temp, last); + StrMakeValidInPlace(temp, last); return ret; } diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 952afb2d5f..e6f6da8dcf 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -113,7 +113,7 @@ Order UnpackOldOrder(uint16 packed) return order; } -const SaveLoad *GetOrderDescription() +SaveLoadTable GetOrderDescription() { static const SaveLoad _order_desc[] = { SLE_VAR(Order, type, SLE_UINT8), @@ -135,7 +135,6 @@ const SaveLoad *GetOrderDescription() /* Leftover from the minor savegame version stuff * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */ SLE_CONDNULL(10, SLV_5, SLV_36), - SLE_END() }; return _order_desc; @@ -148,7 +147,7 @@ static void Save_ORDR() _filtered_desc = SlFilterObject(GetOrderDescription()); for (Order *order : Order::Iterate()) { SlSetArrayIndex(order->index); - SlObjectSaveFiltered(order, _filtered_desc.data()); + SlObjectSaveFiltered(order, _filtered_desc); } } @@ -206,19 +205,18 @@ static void Load_ORDR() while ((index = SlIterateArray()) != -1) { Order *order = new (index) Order(); - SlObjectLoadFiltered(order, _filtered_desc.data()); + SlObjectLoadFiltered(order, _filtered_desc); } } } -const SaveLoad *GetOrderExtraInfoDescription() +const SaveLoadTable GetOrderExtraInfoDescription() { static const SaveLoad _order_extra_info_desc[] = { SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, 32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1, 2)), SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)), SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)), SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)), - SLE_END() }; return _order_extra_info_desc; @@ -230,7 +228,7 @@ void Save_ORDX() for (Order *order : Order::Iterate()) { if (order->extra) { SlSetArrayIndex(order->index); - SlObjectSaveFiltered(order->extra.get(), _filtered_desc.data()); + SlObjectSaveFiltered(order->extra.get(), _filtered_desc); } } } @@ -243,7 +241,7 @@ void Load_ORDX() Order *order = Order::GetIfValid(index); assert(order != nullptr); order->AllocExtraInfo(); - SlObjectLoadFiltered(order->extra.get(), _filtered_desc.data()); + SlObjectLoadFiltered(order->extra.get(), _filtered_desc); } } @@ -257,7 +255,7 @@ static void Ptrs_ORDR() } } -const SaveLoad *GetOrderListDescription() +SaveLoadTable GetOrderListDescription() { static const SaveLoad _orderlist_desc[] = { SLE_REF(OrderList, first, REF_ORDER), @@ -269,7 +267,6 @@ const SaveLoad *GetOrderListDescription() SLE_CONDVAR_X(OrderList, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)), SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), - SLE_END() }; return _orderlist_desc; @@ -312,7 +309,7 @@ void Ptrs_ORDL() } } -const SaveLoad *GetOrderBackupDescription() +SaveLoadTable GetOrderBackupDescription() { static const SaveLoad _order_backup_desc[] = { SLE_VAR(OrderBackup, user, SLE_UINT32), @@ -338,7 +335,6 @@ const SaveLoad *GetOrderBackupDescription() SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)), - SLE_END() }; return _order_backup_desc; diff --git a/src/saveload/plans_sl.cpp b/src/saveload/plans_sl.cpp index 94c2e80b8d..613d4b32a5 100644 --- a/src/saveload/plans_sl.cpp +++ b/src/saveload/plans_sl.cpp @@ -22,7 +22,6 @@ static const SaveLoad _plan_desc[] = { SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)), SLE_CONDSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)), SLE_CONDVAR_X(Plan, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 4)), - SLE_END() }; static void RealSave_PLAN(Plan *p) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 232f2de558..0432fc16df 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1112,7 +1112,7 @@ static void SlString(void *ptr, size_t length, VarType conv) if ((conv & SLF_ALLOW_NEWLINE) != 0) { settings = settings | SVS_ALLOW_NEWLINE; } - str_validate((char *)ptr, (char *)ptr + len, settings); + StrMakeValidInPlace((char *)ptr, (char *)ptr + len, settings); break; } case SLA_PTRS: break; @@ -1151,7 +1151,7 @@ static void SlStdString(std::string &str, VarType conv) if ((conv & SLF_ALLOW_NEWLINE) != 0) { settings = settings | SVS_ALLOW_NEWLINE; } - str_validate_inplace(str, settings); + StrMakeValidInPlace(str, settings); break; } case SLA_PTRS: break; @@ -1593,10 +1593,10 @@ static void SlDeque(void *deque, VarType conv) /** Are we going to save this object or not? */ -static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld) +static inline bool SlIsObjectValidInSavegame(const SaveLoad &sld) { - if (!sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) return false; - if (sld->conv & SLF_NOT_IN_SAVE) return false; + if (!sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) return false; + if (sld.conv & SLF_NOT_IN_SAVE) return false; return true; } @@ -1606,10 +1606,10 @@ static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld) * @note If the variable is skipped it is skipped in the savegame * bytestream itself as well, so there is no need to skip it somewhere else */ -static inline bool SlSkipVariableOnLoad(const SaveLoad *sld) +static inline bool SlSkipVariableOnLoad(const SaveLoad &sld) { - if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) { - SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length); + if ((sld.conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) { + SlSkipBytes(SlCalcConvMemLen(sld.conv) * sld.length); return true; } @@ -1618,26 +1618,26 @@ static inline bool SlSkipVariableOnLoad(const SaveLoad *sld) /** * Calculate the size of an object. - * @param object to be measured - * @param sld The SaveLoad description of the object so we know how to manipulate it - * @return size of given object + * @param object to be measured. + * @param slt The SaveLoad table with objects to save/load. + * @return size of given object. */ -size_t SlCalcObjLength(const void *object, const SaveLoad *sld) +size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt) { size_t length = 0; /* Need to determine the length and write a length tag. */ - for (; sld->cmd != SL_END; sld++) { + for (auto &sld : slt) { length += SlCalcObjMemberLength(object, sld); } return length; } -size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) +size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld) { assert(_sl.action == SLA_SAVE); - switch (sld->cmd) { + switch (sld.cmd) { case SL_VAR: case SL_REF: case SL_ARR: @@ -1651,17 +1651,17 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) /* CONDITIONAL saveload types depend on the savegame version */ if (!SlIsObjectValidInSavegame(sld)) break; - switch (sld->cmd) { - case SL_VAR: return SlCalcConvFileLen(sld->conv); + switch (sld.cmd) { + case SL_VAR: return SlCalcConvFileLen(sld.conv); case SL_REF: return SlCalcRefLen(); - case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv); - case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv); + case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv); + case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld.length, sld.conv); case SL_LST: return SlCalcListLen>(GetVariableAddress(object, sld)); case SL_PTRDEQ: return SlCalcListLen>(GetVariableAddress(object, sld)); case SL_VEC: return SlCalcListLen>(GetVariableAddress(object, sld)); - case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv); + case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv); case SL_VARVEC: { - const size_t size_len = SlCalcConvMemLen(sld->conv); + const size_t size_len = SlCalcConvMemLen(sld.conv); switch (size_len) { case 1: return SlCalcVarListLen>(GetVariableAddress(object, sld), 1); case 2: return SlCalcVarListLen>(GetVariableAddress(object, sld), 2); @@ -1689,41 +1689,41 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) * matches with the actual variable size. * @param sld The saveload configuration to test. */ -static bool IsVariableSizeRight(const SaveLoad *sld) +static bool IsVariableSizeRight(const SaveLoad &sld) { - switch (sld->cmd) { + switch (sld.cmd) { case SL_VAR: - switch (GetVarMemType(sld->conv)) { + switch (GetVarMemType(sld.conv)) { case SLE_VAR_BL: - return sld->size == sizeof(bool); + return sld.size == sizeof(bool); case SLE_VAR_I8: case SLE_VAR_U8: - return sld->size == sizeof(int8); + return sld.size == sizeof(int8); case SLE_VAR_I16: case SLE_VAR_U16: - return sld->size == sizeof(int16); + return sld.size == sizeof(int16); case SLE_VAR_I32: case SLE_VAR_U32: - return sld->size == sizeof(int32); + return sld.size == sizeof(int32); case SLE_VAR_I64: case SLE_VAR_U64: - return sld->size == sizeof(int64); + return sld.size == sizeof(int64); case SLE_VAR_NAME: - return sld->size == sizeof(std::string); + return sld.size == sizeof(std::string); default: - return sld->size == sizeof(void *); + return sld.size == sizeof(void *); } case SL_REF: /* These should all be pointer sized. */ - return sld->size == sizeof(void *); + return sld.size == sizeof(void *); case SL_STR: /* These should be pointer sized, or fixed array. */ - return sld->size == sizeof(void *) || sld->size == sld->length; + return sld.size == sizeof(void *) || sld.size == sld.length; case SL_STDSTR: /* These should be all pointers to std::string. */ - return sld->size == sizeof(std::string); + return sld.size == sizeof(std::string); default: return true; @@ -1732,15 +1732,15 @@ static bool IsVariableSizeRight(const SaveLoad *sld) #endif /* OTTD_ASSERT */ -void SlFilterObject(const SaveLoad *sld, std::vector &save); +void SlFilterObject(const SaveLoadTable &slt, std::vector &save); -static void SlFilterObjectMember(const SaveLoad *sld, std::vector &save) +static void SlFilterObjectMember(const SaveLoad &sld, std::vector &save) { #ifdef OTTD_ASSERT assert(IsVariableSizeRight(sld)); #endif - switch (sld->cmd) { + switch (sld.cmd) { case SL_VAR: case SL_REF: case SL_ARR: @@ -1762,7 +1762,7 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector &sav break; case SLA_PTRS: case SLA_NULL: - switch (sld->cmd) { + switch (sld.cmd) { case SL_REF: case SL_LST: case SL_PTRDEQ: @@ -1777,14 +1777,14 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector &sav default: NOT_REACHED(); } - save.push_back(*sld); + save.push_back(sld); break; /* SL_WRITEBYTE writes a value to the savegame to identify the type of an object. * When loading, the value is read explictly with SlReadByte() to determine which * object description to use. */ case SL_WRITEBYTE: - if (_sl.action == SLA_SAVE) save.push_back(*sld); + if (_sl.action == SLA_SAVE) save.push_back(sld); break; /* SL_VEH_INCLUDE loads common code for vehicles */ @@ -1800,30 +1800,29 @@ static void SlFilterObjectMember(const SaveLoad *sld, std::vector &sav } } -void SlFilterObject(const SaveLoad *sld, std::vector &save) +void SlFilterObject(const SaveLoadTable &slt, std::vector &save) { - for (; sld->cmd != SL_END; sld++) { + for (auto &sld : slt) { SlFilterObjectMember(sld, save); } } -std::vector SlFilterObject(const SaveLoad *sld) +std::vector SlFilterObject(const SaveLoadTable &slt) { std::vector save; - SlFilterObject(sld, save); - save.push_back(SLE_END()); + SlFilterObject(slt, save); return save; } template -bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) +bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld) { #ifdef OTTD_ASSERT if (check_version) assert(IsVariableSizeRight(sld)); #endif - VarType conv = GB(sld->conv, 0, 8); - switch (sld->cmd) { + VarType conv = GB(sld.conv, 0, 8); + switch (sld.cmd) { case SL_VAR: case SL_REF: case SL_ARR: @@ -1840,7 +1839,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) if (SlSkipVariableOnLoad(sld)) return false; } - switch (sld->cmd) { + switch (sld.cmd) { case SL_VAR: SlSaveLoadConvGeneric(ptr, conv); break; case SL_REF: // Reference variable, translate switch (action) { @@ -1860,14 +1859,14 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) default: NOT_REACHED(); } break; - case SL_ARR: SlArray(ptr, sld->length, conv); break; - case SL_STR: SlString(ptr, sld->length, sld->conv); break; + case SL_ARR: SlArray(ptr, sld.length, conv); break; + case SL_STR: SlString(ptr, sld.length, sld.conv); break; case SL_LST: SlList>(ptr, (SLRefType)conv); break; case SL_PTRDEQ: SlList>(ptr, (SLRefType)conv); break; case SL_VEC: SlList>(ptr, (SLRefType)conv); break; case SL_DEQUE: SlDeque(ptr, conv); break; case SL_VARVEC: { - const size_t size_len = SlCalcConvMemLen(sld->conv); + const size_t size_len = SlCalcConvMemLen(sld.conv); switch (size_len) { case 1: SlVarList>(ptr, conv); break; case 2: SlVarList>(ptr, conv); break; @@ -1877,7 +1876,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) } break; } - case SL_STDSTR: SlStdString(*static_cast(ptr), sld->conv); break; + case SL_STDSTR: SlStdString(*static_cast(ptr), sld.conv); break; default: NOT_REACHED(); } break; @@ -1910,7 +1909,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad *sld) return true; } -bool SlObjectMember(void *ptr, const SaveLoad *sld) +bool SlObjectMember(void *ptr, const SaveLoad &sld) { switch (_sl.action) { case SLA_SAVE: @@ -1928,71 +1927,71 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) /** * Main SaveLoad function. - * @param object The object that is being saved or loaded - * @param sld The SaveLoad description of the object so we know how to manipulate it + * @param object The object that is being saved or loaded. + * @param slt The SaveLoad table with objects to save/load. */ -void SlObject(void *object, const SaveLoad *sld) +void SlObject(void *object, const SaveLoadTable &slt) { /* Automatically calculate the length? */ if (_sl.need_length != NL_NONE) { - SlSetLength(SlCalcObjLength(object, sld)); + SlSetLength(SlCalcObjLength(object, slt)); } - for (; sld->cmd != SL_END; sld++) { + for (auto &sld : slt) { void *ptr = GetVariableAddress(object, sld); SlObjectMember(ptr, sld); } } template -void SlObjectIterateBase(void *object, const SaveLoad *sld) +void SlObjectIterateBase(void *object, const SaveLoadTable &slt) { - for (; sld->cmd != SL_END; sld++) { - void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld); + for (auto &sld : slt) { + void *ptr = sld.global ? sld.address : GetVariableAddress(object, sld); SlObjectMemberGeneric(ptr, sld); } } -void SlObjectSaveFiltered(void *object, const SaveLoad *sld) +void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt) { if (_sl.need_length != NL_NONE) { _sl.need_length = NL_NONE; _sl.dumper->StartAutoLength(); - SlObjectIterateBase(object, sld); + SlObjectIterateBase(object, slt); auto result = _sl.dumper->StopAutoLength(); _sl.need_length = NL_WANTLENGTH; SlSetLength(result.second); _sl.dumper->CopyBytes(result.first, result.second); } else { - SlObjectIterateBase(object, sld); + SlObjectIterateBase(object, slt); } } -void SlObjectLoadFiltered(void *object, const SaveLoad *sld) +void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt) { - SlObjectIterateBase(object, sld); + SlObjectIterateBase(object, slt); } -void SlObjectPtrOrNullFiltered(void *object, const SaveLoad *sld) +void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt) { switch (_sl.action) { case SLA_PTRS: - SlObjectIterateBase(object, sld); + SlObjectIterateBase(object, slt); return; case SLA_NULL: - SlObjectIterateBase(object, sld); + SlObjectIterateBase(object, slt); return; default: NOT_REACHED(); } } /** - * Save or Load (a list of) global variables - * @param sldg The global variable that is being loaded or saved + * Save or Load (a list of) global variables. + * @param slt The SaveLoad table with objects to save/load. */ -void SlGlobList(const SaveLoadGlobVarList *sldg) +void SlGlobList(const SaveLoadTable &slt) { - SlObject(nullptr, (const SaveLoad*)sldg); + SlObject(nullptr, slt); } /** diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 012a7d7676..84a0826986 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -12,6 +12,7 @@ #include "../fileio_type.h" #include "../strings_type.h" +#include "../core/span_type.hpp" #include "extended_ver_sl.h" #include @@ -564,7 +565,6 @@ enum SaveLoadTypes { SL_PTRDEQ = 13, ///< Save/load a pointer type deque. SL_VARVEC = 14, ///< Save/load a primitive type vector. - SL_END = 15 }; typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes @@ -586,8 +586,8 @@ struct SaveLoad { SlXvFeatureTest ext_feature_test; ///< extended feature test }; -/** Same as #SaveLoad but global variables are used (for better readability); */ -typedef SaveLoad SaveLoadGlobVarList; +/** A table of SaveLoad entries. */ +using SaveLoadTable = span; /** * Storage of simple variables, references (pointers), and arrays. @@ -813,9 +813,6 @@ typedef SaveLoad SaveLoadGlobVarList; #define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()} #define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0, SlXvFeatureTest()} -/** End marker of a struct/class save or load. */ -#define SLE_END() {false, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0, SlXvFeatureTest()} - /** * Storage of global simple variables, references (pointers), and arrays. * @param cmd Load/save type. @see SaveLoadType @@ -983,9 +980,6 @@ typedef SaveLoad SaveLoadGlobVarList; */ #define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)nullptr, SlXvFeatureTest()} -/** End marker of global variables save or load. */ -#define SLEG_END() {true, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0, SlXvFeatureTest()} - /** * Checks whether the savegame is below \a major.\a minor. * @param major Major number of the version to check against. @@ -1065,22 +1059,22 @@ static inline bool IsNumericType(VarType conv) * is taken. If non-null only the offset is stored in the union and we need * to add this to the address of the object */ -static inline void *GetVariableAddress(const void *object, const SaveLoad *sld) +static inline void *GetVariableAddress(const void *object, const SaveLoad &sld) { /* Entry is a global address. */ - if (sld->global) return sld->address; + if (sld.global) return sld.address; #ifdef _DEBUG /* Entry is a null-variable, mostly used to read old savegames etc. */ - if (GetVarMemType(sld->conv) == SLE_VAR_NULL) { - assert(sld->address == nullptr); + if (GetVarMemType(sld.conv) == SLE_VAR_NULL) { + assert(sld.address == nullptr); return nullptr; } /* Everything else should be a non-null pointer. */ assert(object != nullptr); #endif - return const_cast((const byte *)object + (ptrdiff_t)sld->address); + return const_cast((const byte *)object + (ptrdiff_t)sld.address); } int64 ReadValue(const void *ptr, VarType conv); @@ -1092,8 +1086,8 @@ int SlIterateArray(); void SlAutolength(AutolengthProc *proc, void *arg); size_t SlGetFieldLength(); void SlSetLength(size_t length); -size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld); -size_t SlCalcObjLength(const void *object, const SaveLoad *sld); +size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld); +size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt); byte SlReadByte(); void SlWriteByte(byte b); @@ -1111,15 +1105,15 @@ void SlSkipBytes(size_t length); size_t SlGetBytesRead(); size_t SlGetBytesWritten(); -void SlGlobList(const SaveLoadGlobVarList *sldg); +void SlGlobList(const SaveLoadTable &slt); void SlArray(void *array, size_t length, VarType conv); -void SlObject(void *object, const SaveLoad *sld); -bool SlObjectMember(void *object, const SaveLoad *sld); +void SlObject(void *object, const SaveLoadTable &slt); +bool SlObjectMember(void *object, const SaveLoad &sld); -std::vector SlFilterObject(const SaveLoad *sld); -void SlObjectSaveFiltered(void *object, const SaveLoad *sld); -void SlObjectLoadFiltered(void *object, const SaveLoad *sld); -void SlObjectPtrOrNullFiltered(void *object, const SaveLoad *sld); +std::vector SlFilterObject(const SaveLoadTable &slt); +void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt); +void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt); +void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt); void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false); void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false); diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index 11bfd00169..2812edf8ce 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -23,7 +23,7 @@ void ResetOldNames(); void ResetOldWaypoints(); void MoveBuoysToWaypoints(); void MoveWaypointsToBaseStations(); -const SaveLoad *GetBaseStationDescription(); +SaveLoadTable GetBaseStationDescription(); void AfterLoadVehicles(bool part_of_load); void AfterLoadEngines(); diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index b8b68ca1d9..deaffac8f6 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -26,7 +26,6 @@ static const SaveLoad _sign_desc[] = { SLE_CONDVAR(Sign, owner, SLE_UINT8, SLV_6, SL_MAX_VERSION), SLE_CONDVAR_X(Sign, z, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164, SlXvFeatureTest(XSLFTO_AND, XSLFI_ZPOS_32_BIT, 0, 0)), SLE_CONDVAR_X(Sign, z, SLE_INT32, SLV_164, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_ZPOS_32_BIT)), - SLE_END() }; /** Save all signs */ diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 4097133ac3..68e042978b 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -157,8 +157,6 @@ static const SaveLoad _roadstop_desc[] = { SLE_CONDNULL(4, SL_MIN_VERSION, SLV_25), SLE_CONDNULL(1, SLV_25, SLV_26), - - SLE_END() }; static const SaveLoad _old_station_desc[] = { @@ -218,8 +216,6 @@ static const SaveLoad _old_station_desc[] = { /* reserve extra space in savegame here. (currently 32 bytes) */ SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION), - - SLE_END() }; static uint16 _waiting_acceptance; @@ -232,8 +228,6 @@ static Money _cargo_feeder_share; static const SaveLoad _station_speclist_desc[] = { SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION), - - SLE_END() }; CargoPacketList _packets; @@ -253,7 +247,6 @@ static const SaveLoad _flow_desc[] = { SLE_VAR(FlowSaveLoad, via, SLE_UINT16), SLE_VAR(FlowSaveLoad, share, SLE_UINT32), SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION), - SLE_END() }; #endif @@ -262,7 +255,7 @@ static const SaveLoad _flow_desc[] = { * some of the variables itself are private. * @return the saveload description for GoodsEntry. */ -const SaveLoad *GetGoodsDesc() +SaveLoadTable GetGoodsDesc() { static const SaveLoad goods_desc[] = { SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68), @@ -289,7 +282,6 @@ const SaveLoad *GetGoodsDesc() SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDVAR_X(GoodsEntry, last_vehicle_type, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 1)), - SLE_END() }; return goods_desc; @@ -300,7 +292,6 @@ typedef std::pair StationCargoPair; static const SaveLoad _cargo_list_desc[] = { SLE_VAR(StationCargoPair, first, SLE_UINT16), SLE_PTRDEQ(StationCargoPair, second, REF_CARGO_PACKET), - SLE_END() }; /** @@ -411,8 +402,6 @@ static const SaveLoad _base_station_desc[] = { SLE_VAR(BaseStation, random_bits, SLE_UINT16), SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), SLE_VAR(BaseStation, num_specs, SLE_UINT8), - - SLE_END() }; static OldPersistentStorage _old_st_persistent_storage; @@ -461,8 +450,6 @@ static const SaveLoad _station_desc[] = { SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_CONDNULL_X(32 * 24, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_22)), SLE_CONDVAR_X(Station, station_cargo_history_cargoes, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_STATION_CARGO_HISTORY)), - - SLE_END() }; static const SaveLoad _waypoint_desc[] = { @@ -474,15 +461,13 @@ static const SaveLoad _waypoint_desc[] = { SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), - - SLE_END() }; /** * Get the base station description to be used for SL_ST_INCLUDE * @return the base station description. */ -const SaveLoad *GetBaseStationDescription() +SaveLoadTable GetBaseStationDescription() { return _base_station_desc; } @@ -511,7 +496,7 @@ static void SetupDescs_ROADSTOP() static void RealSave_STNN(BaseStation *bst) { bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0; - SlObjectSaveFiltered(bst, waypoint ? _filtered_waypoint_desc.data() : _filtered_station_desc.data()); + SlObjectSaveFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc)); MemoryDumper *dumper = MemoryDumper::GetCurrent(); @@ -520,7 +505,7 @@ static void RealSave_STNN(BaseStation *bst) for (CargoID i = 0; i < NUM_CARGO; i++) { _num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize(); _num_flows = (uint32)st->goods[i].flows.size(); - SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc.data()); + SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc); for (FlowStatMap::const_iterator outer_it(st->goods[i].flows.begin()); outer_it != st->goods[i].flows.end(); ++outer_it) { uint32 sum_shares = 0; FlowSaveLoad flow; @@ -563,7 +548,7 @@ static void RealSave_STNN(BaseStation *bst) } for (uint i = 0; i < bst->num_specs; i++) { - SlObjectSaveFiltered(&bst->speclist[i], _filtered_station_speclist_desc.data()); + SlObjectSaveFiltered(&bst->speclist[i], _filtered_station_speclist_desc); } } @@ -592,7 +577,7 @@ static void Load_STNN() bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); - SlObjectLoadFiltered(bst, waypoint ? _filtered_waypoint_desc.data() : _filtered_station_desc.data()); + SlObjectLoadFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc)); if (!waypoint) { Station *st = Station::From(bst); @@ -606,7 +591,7 @@ static void Load_STNN() } for (CargoID i = 0; i < num_cargo; i++) { - SlObjectLoadFiltered(&st->goods[i], _filtered_goods_desc.data()); + SlObjectLoadFiltered(&st->goods[i], _filtered_goods_desc); StationID prev_source = INVALID_STATION; if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) { for (uint32 j = 0; j < _num_flows; ++j) { @@ -684,7 +669,7 @@ static void Load_STNN() /* Allocate speclist memory when loading a game */ bst->speclist = CallocT(bst->num_specs); for (uint i = 0; i < bst->num_specs; i++) { - SlObjectLoadFiltered(&bst->speclist[i], _filtered_station_speclist_desc.data()); + SlObjectLoadFiltered(&bst->speclist[i], _filtered_station_speclist_desc); } } } @@ -698,7 +683,7 @@ static void Ptrs_STNN() SetupDescs_STNN(); if (!IsSavegameVersionBefore(SLV_183)) { - assert(_filtered_goods_desc[0].cmd == SL_END); + assert(_filtered_goods_desc.size() == 0); } uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; @@ -707,7 +692,7 @@ static void Ptrs_STNN() GoodsEntry *ge = &st->goods[i]; if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) { SwapPackets(ge); - SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc.data()); + SlObjectPtrOrNullFiltered(ge, _filtered_goods_desc); SwapPackets(ge); } else { //SlObject(ge, GetGoodsDesc()); @@ -716,11 +701,11 @@ static void Ptrs_STNN() } } } - SlObjectPtrOrNullFiltered(st, _filtered_station_desc.data()); + SlObjectPtrOrNullFiltered(st, _filtered_station_desc); } for (Waypoint *wp : Waypoint::Iterate()) { - SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc.data()); + SlObjectPtrOrNullFiltered(wp, _filtered_waypoint_desc); } } @@ -729,7 +714,7 @@ static void Save_ROADSTOP() SetupDescs_ROADSTOP(); for (RoadStop *rs : RoadStop::Iterate()) { SlSetArrayIndex(rs->index); - SlObjectSaveFiltered(rs, _filtered_roadstop_desc.data()); + SlObjectSaveFiltered(rs, _filtered_roadstop_desc); } } @@ -740,7 +725,7 @@ static void Load_ROADSTOP() while ((index = SlIterateArray()) != -1) { RoadStop *rs = new (index) RoadStop(INVALID_TILE); - SlObjectLoadFiltered(rs, _filtered_roadstop_desc.data()); + SlObjectLoadFiltered(rs, _filtered_roadstop_desc); } } @@ -748,7 +733,7 @@ static void Ptrs_ROADSTOP() { SetupDescs_ROADSTOP(); for (RoadStop *rs : RoadStop::Iterate()) { - SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc.data()); + SlObjectPtrOrNullFiltered(rs, _filtered_roadstop_desc); } } diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 7abe396f38..a01904e3a1 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -18,7 +18,6 @@ static const SaveLoad _storage_desc[] = { SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE), SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), - SLE_END() }; /** Load persistent storage data. */ diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index dba2a064f5..06083fb103 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -34,7 +34,6 @@ static const SaveLoad _story_page_elements_desc[] = { SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION), SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32), SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0), - SLE_END() }; static void Save_STORY_PAGE_ELEMENT() @@ -69,7 +68,6 @@ static const SaveLoad _story_pages_desc[] = { SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185), SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION), SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0), - SLE_END() }; static void Save_STORY_PAGE() diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index 986980a9a5..13b6bcd287 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -25,7 +25,6 @@ static const SaveLoad _subsidies_desc[] = { SLE_CONDVAR(Subsidy, src, SLE_UINT16, SLV_5, SL_MAX_VERSION), SLE_CONDVAR(Subsidy, dst, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION), - SLE_END() }; static void Save_SUBS() diff --git a/src/saveload/tbtr_template_replacement_sl.cpp b/src/saveload/tbtr_template_replacement_sl.cpp index fa349304d3..e33e05e242 100644 --- a/src/saveload/tbtr_template_replacement_sl.cpp +++ b/src/saveload/tbtr_template_replacement_sl.cpp @@ -7,7 +7,6 @@ static const SaveLoad _template_replacement_desc[] = { SLE_VAR(TemplateReplacement, sel_template, SLE_UINT16), SLE_VAR(TemplateReplacement, group, SLE_UINT16), - SLE_END() }; static void Save_TMPL_RPLS() diff --git a/src/saveload/tbtr_template_veh_sl.cpp b/src/saveload/tbtr_template_veh_sl.cpp index d2af9a3d4f..cde76c8b97 100644 --- a/src/saveload/tbtr_template_veh_sl.cpp +++ b/src/saveload/tbtr_template_veh_sl.cpp @@ -9,7 +9,7 @@ #include "saveload.h" -const SaveLoad* GTD() { +const SaveLoadTable GTD() { static const SaveLoad _template_veh_desc[] = { SLE_REF(TemplateVehicle, next, REF_TEMPLATE_VEHICLE), @@ -49,15 +49,9 @@ const SaveLoad* GTD() { SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 2, 3)), SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)), - - SLE_END() }; - static const SaveLoad * const _ret[] = { - _template_veh_desc, - }; - - return _ret[0]; + return _template_veh_desc; } static void Save_TMPLS() diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index cf4d9cbb1d..ad9258f67c 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -243,8 +243,6 @@ static const SaveLoad _town_desc[] = { SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space - - SLE_END() }; static const SaveLoad _town_supplied_desc[] = { @@ -252,8 +250,6 @@ static const SaveLoad _town_supplied_desc[] = { SLE_CONDVAR(TransportedCargoStat, new_max, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), - - SLE_END() }; static const SaveLoad _town_received_desc[] = { @@ -261,8 +257,6 @@ static const SaveLoad _town_received_desc[] = { SLE_CONDVAR(TransportedCargoStat, new_max, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), - - SLE_END() }; static const SaveLoad _town_received_desc_spp[] = { @@ -270,8 +264,6 @@ static const SaveLoad _town_received_desc_spp[] = { SLE_CONDVAR(TransportedCargoStat, new_max, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, old_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, new_act, SLE_FILE_U32 | SLE_VAR_U16, SLV_165, SL_MAX_VERSION), - - SLE_END() }; std::vector _filtered_town_desc; @@ -297,13 +289,13 @@ static void Load_HIDS() static void RealSave_Town(Town *t) { - SlObjectSaveFiltered(t, _filtered_town_desc.data()); + SlObjectSaveFiltered(t, _filtered_town_desc); for (CargoID i = 0; i < NUM_CARGO; i++) { - SlObjectSaveFiltered(&t->supplied[i], _filtered_town_supplied_desc.data()); + SlObjectSaveFiltered(&t->supplied[i], _filtered_town_supplied_desc); } for (int i = TE_BEGIN; i < NUM_TE; i++) { - SlObjectSaveFiltered(&t->received[i], _filtered_town_received_desc.data()); + SlObjectSaveFiltered(&t->received[i], _filtered_town_received_desc); } } @@ -324,10 +316,10 @@ static void Load_TOWN() while ((index = SlIterateArray()) != -1) { Town *t = new (index) Town(); - SlObjectLoadFiltered(t, _filtered_town_desc.data()); + SlObjectLoadFiltered(t, _filtered_town_desc); for (CargoID i = 0; i < num_cargo; i++) { - SlObjectLoadFiltered(&t->supplied[i], _filtered_town_supplied_desc.data()); + SlObjectLoadFiltered(&t->supplied[i], _filtered_town_supplied_desc); } if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) { for (int i = TE_BEGIN; i < NUM_TE; i++) { @@ -335,7 +327,7 @@ static void Load_TOWN() } } else { for (int i = TE_BEGIN; i < NUM_TE; i++) { - SlObjectLoadFiltered(&t->received[i], _filtered_town_received_desc.data()); + SlObjectLoadFiltered(&t->received[i], _filtered_town_received_desc); } } @@ -362,7 +354,7 @@ static void Ptrs_TOWN() SetupDescs_TOWN(); for (Town *t : Town::Iterate()) { - SlObjectPtrOrNullFiltered(t, _filtered_town_desc.data()); + SlObjectPtrOrNullFiltered(t, _filtered_town_desc); } } diff --git a/src/saveload/tracerestrict_sl.cpp b/src/saveload/tracerestrict_sl.cpp index 53f9eb23f2..6fa8af19a1 100644 --- a/src/saveload/tracerestrict_sl.cpp +++ b/src/saveload/tracerestrict_sl.cpp @@ -16,7 +16,6 @@ static const SaveLoad _trace_restrict_mapping_desc[] = { SLE_VAR(TraceRestrictMappingItem, program_id, SLE_UINT32), - SLE_END() }; /** @@ -50,7 +49,6 @@ struct TraceRestrictProgramStub { static const SaveLoad _trace_restrict_program_stub_desc[] = { SLE_VAR(TraceRestrictProgramStub, length, SLE_UINT32), - SLE_END() }; /** @@ -120,14 +118,12 @@ struct TraceRestrictSlotStub { static const SaveLoad _trace_restrict_slot_stub_desc[] = { SLE_VAR(TraceRestrictSlotStub, length, SLE_UINT32), - SLE_END() }; static const SaveLoad _trace_restrict_slot_desc[] = { SLE_VAR(TraceRestrictSlot, max_occupancy, SLE_UINT32), SLE_SSTR(TraceRestrictSlot, name, SLF_ALLOW_CONTROL), SLE_VAR(TraceRestrictSlot, owner, SLE_UINT8), - SLE_END() }; /** @@ -174,7 +170,6 @@ static const SaveLoad _trace_restrict_counter_desc[] = { SLE_VAR(TraceRestrictCounter, value, SLE_INT32), SLE_SSTR(TraceRestrictCounter, name, SLF_ALLOW_CONTROL), SLE_VAR(TraceRestrictCounter, owner, SLE_UINT8), - SLE_END() }; /** diff --git a/src/saveload/train_speed_adaptation.cpp b/src/saveload/train_speed_adaptation.cpp index 21dfa39441..7d8e5ac8c9 100644 --- a/src/saveload/train_speed_adaptation.cpp +++ b/src/saveload/train_speed_adaptation.cpp @@ -18,7 +18,6 @@ static const SaveLoad _train_speed_adaptation_map_desc[] = { SLE_VAR(SignalSpeedType, first.last_passing_train_dir, SLE_UINT8), SLE_VAR(SignalSpeedType, second.train_speed, SLE_UINT16), SLE_VAR(SignalSpeedType, second.time_stamp, SLE_UINT64), - SLE_END() }; static void Load_TSAS() diff --git a/src/saveload/tunnel_sl.cpp b/src/saveload/tunnel_sl.cpp index 447fa94685..f8ad309662 100644 --- a/src/saveload/tunnel_sl.cpp +++ b/src/saveload/tunnel_sl.cpp @@ -20,7 +20,6 @@ static const SaveLoad _tunnel_desc[] = { SLE_CONDVAR(Tunnel, tile_s, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION), SLE_CONDVAR(Tunnel, height, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION), SLE_CONDVAR(Tunnel, is_chunnel, SLE_BOOL, SL_MIN_VERSION, SL_MAX_VERSION), - SLE_END() }; static void Save_TUNN() diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 6a28f5fae9..cc5076d813 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -616,7 +616,7 @@ static uint32 _old_ahead_separation; * @param vt the vehicle type. Can be VEH_END for the common vehicle description data * @return the saveload description */ -const SaveLoad *GetVehicleDescription(VehicleType vt) +SaveLoadTable GetVehicleDescription(VehicleType vt) { /** Save and load of vehicles */ static const SaveLoad _common_veh_desc[] = { @@ -780,11 +780,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)), SLE_CONDNULL_X(160, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)), - - SLE_END() }; - static const SaveLoad _train_desc[] = { SLE_WRITEBYTE(Vehicle, type), SLE_VEH_INCLUDE(), @@ -809,8 +806,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR_X(Train, speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPEED_RESTRICTION)), SLE_CONDVAR_X(Train, signal_speed_restriction, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TRAIN_SPEED_ADAPTATION)), SLE_CONDVAR_X(Train, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 2)), - - SLE_END() }; static const SaveLoad _roadveh_desc[] = { @@ -833,8 +828,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDNULL(2, SLV_6, SLV_131), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDVAR_X(RoadVehicle, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 6)), - - SLE_END() }; static const SaveLoad _ship_desc[] = { @@ -847,8 +840,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR_X(Ship, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 8)), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static const SaveLoad _aircraft_desc[] = { @@ -872,8 +863,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR(Aircraft, flags, SLE_UINT8, SLV_167, SL_MAX_VERSION), SLE_CONDNULL(13, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static const SaveLoad _special_desc[] = { @@ -904,8 +893,6 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, SLV_2, SL_MAX_VERSION), SLE_CONDNULL(15, SLV_2, SLV_144), // old reserved space - - SLE_END() }; static const SaveLoad _disaster_desc[] = { @@ -947,12 +934,10 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space - - SLE_END() }; - static const SaveLoad * const _veh_descs[] = { + static const SaveLoadTable _veh_descs[] = { _train_desc, _roadveh_desc, _ship_desc, @@ -981,9 +966,9 @@ static std::vector * const _filtered_veh_descs[] = { &_filtered_disaster_desc, }; -const SaveLoad *GetVehicleDescriptionFiltered(VehicleType vt) +const SaveLoadTable GetVehicleDescriptionFiltered(VehicleType vt) { - return _filtered_veh_descs[vt]->data(); + return *(_filtered_veh_descs[vt]); } static void SetupDescs_VEHS() @@ -1078,7 +1063,7 @@ static void Ptrs_VEHS() } } -const SaveLoad *GetOrderExtraInfoDescription(); +const SaveLoadTable GetOrderExtraInfoDescription(); void Save_VEOX() { @@ -1103,14 +1088,13 @@ void Load_VEOX() } } -const SaveLoad *GetVehicleSpeedRestrictionDescription() +const SaveLoadTable GetVehicleSpeedRestrictionDescription() { static const SaveLoad _vehicle_speed_restriction_desc[] = { SLE_VAR(PendingSpeedRestrictionChange, distance, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, new_speed, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, prev_speed, SLE_UINT16), SLE_VAR(PendingSpeedRestrictionChange, flags, SLE_UINT16), - SLE_END() }; return _vehicle_speed_restriction_desc; @@ -1391,7 +1375,7 @@ void SlProcessVENC() } } -const SaveLoad *GetVehicleLookAheadDescription() +const SaveLoadTable GetVehicleLookAheadDescription() { static const SaveLoad _vehicle_look_ahead_desc[] = { SLE_VAR(TrainReservationLookAhead, reservation_end_tile, SLE_UINT32), @@ -1402,13 +1386,12 @@ const SaveLoad *GetVehicleLookAheadDescription() SLE_VAR(TrainReservationLookAhead, tunnel_bridge_reserved_tiles, SLE_INT16), SLE_VAR(TrainReservationLookAhead, flags, SLE_UINT16), SLE_VAR(TrainReservationLookAhead, speed_restriction, SLE_UINT16), - SLE_END() }; return _vehicle_look_ahead_desc; } -const SaveLoad *GetVehicleLookAheadItemDescription() +const SaveLoadTable GetVehicleLookAheadItemDescription() { static const SaveLoad _vehicle_look_ahead_item_desc[] = { SLE_VAR(TrainReservationLookAheadItem, start, SLE_INT32), @@ -1416,18 +1399,16 @@ const SaveLoad *GetVehicleLookAheadItemDescription() SLE_VAR(TrainReservationLookAheadItem, z_pos, SLE_INT16), SLE_VAR(TrainReservationLookAheadItem, data_id, SLE_UINT16), SLE_VAR(TrainReservationLookAheadItem, type, SLE_UINT8), - SLE_END() }; return _vehicle_look_ahead_item_desc; } -const SaveLoad *GetVehicleLookAheadCurveDescription() +const SaveLoadTable GetVehicleLookAheadCurveDescription() { static const SaveLoad _vehicle_look_ahead_curve_desc[] = { SLE_VAR(TrainReservationLookAheadCurve, position, SLE_INT32), SLE_VAR(TrainReservationLookAheadCurve, dir_diff, SLE_UINT8), - SLE_END() }; return _vehicle_look_ahead_curve_desc; diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index ee137c45a3..027659ee06 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -180,8 +180,6 @@ static const SaveLoad _old_waypoint_desc[] = { SLE_CONDVAR(OldWaypoint, localidx, SLE_UINT8, SLV_3, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, grfid, SLE_UINT32, SLV_17, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, owner, SLE_UINT8, SLV_101, SL_MAX_VERSION), - - SLE_END() }; static void Load_WAYP() diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index 8f7371266d..24aa0bcaf3 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.cpp @@ -139,7 +139,7 @@ return 1; } - NetworkAdminGameScript(json.c_str()); + NetworkAdminGameScript(json); sq_pushinteger(vm, 1); return 1; diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index 20f1b3f7a1..9f5722c100 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -260,7 +260,7 @@ /* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew) { - return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew"), autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); + return ScriptObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew"); } /* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company) @@ -273,7 +273,7 @@ /* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months) { - return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_months"), months, CMD_CHANGE_COMPANY_SETTING); + return ScriptObject::DoCommand(0, 0, months, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_months"); } /* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company) @@ -288,7 +288,7 @@ { EnforcePrecondition(false, money >= 0); EnforcePrecondition(false, (int64)money <= UINT32_MAX); - return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_money"), money, CMD_CHANGE_COMPANY_SETTING); + return ScriptObject::DoCommand(0, 0, money, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_money"); } /* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company) diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index 84c001836d..3cc5287eb8 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -118,23 +118,18 @@ bool ScriptEventCompanyAskMerger::AcceptMerger() return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY); } -ScriptEventAdminPort::ScriptEventAdminPort(const char *json) : +ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) : ScriptEvent(ET_ADMIN_PORT), - json(stredup(json)) + json(json) { } -ScriptEventAdminPort::~ScriptEventAdminPort() -{ - free(this->json); -} - #define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++; #define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; } SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) { - char *p = this->json; + const char *p = this->json.c_str(); if (this->ReadTable(vm, p) == nullptr) { sq_pushnull(vm); @@ -144,9 +139,9 @@ SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) return 1; } -char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p) +const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p) { - char *value = p; + const char *value = p; bool escape = false; for (;;) { @@ -168,14 +163,14 @@ char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p) p++; } - *p = '\0'; - sq_pushstring(vm, value, -1); - *p++ = '"'; + size_t len = p - value; + sq_pushstring(vm, value, len); + p++; // Step past the end-of-string marker (") return p; } -char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p) +const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p) { sq_newtable(vm); @@ -218,7 +213,7 @@ char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p) return p; } -char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) +const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p) { SKIP_EMPTY(p); @@ -257,7 +252,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) sq_newarray(vm, 0); /* Empty array? */ - char *p2 = p + 1; + const char *p2 = p + 1; SKIP_EMPTY(p2); if (*p2 == ']') { p = p2 + 1; diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index 1d514389b5..3ed6c5b10a 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.hpp @@ -837,8 +837,7 @@ public: /** * @param json The JSON string which got sent. */ - ScriptEventAdminPort(const char *json); - ~ScriptEventAdminPort(); + ScriptEventAdminPort(const std::string &json); /** * Convert an ScriptEvent to the real instance. @@ -853,28 +852,28 @@ public: SQInteger GetObject(HSQUIRRELVM vm); private: - char *json; ///< The JSON string. + std::string json; ///< The JSON string. /** * Read a table from a JSON string. * @param vm The VM used. * @param p The (part of the) JSON string reading. */ - char *ReadTable(HSQUIRRELVM vm, char *p); + const char *ReadTable(HSQUIRRELVM vm, const char *p); /** * Read a value from a JSON string. * @param vm The VM used. * @param p The (part of the) JSON string reading. */ - char *ReadValue(HSQUIRRELVM vm, char *p); + const char *ReadValue(HSQUIRRELVM vm, const char *p); /** * Read a string from a JSON string. * @param vm The VM used. * @param p The (part of the) JSON string reading. */ - char *ReadString(HSQUIRRELVM vm, char *p); + const char *ReadString(HSQUIRRELVM vm, const char *p); }; /** diff --git a/src/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index 8b0459367e..b1699d94f6 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.cpp @@ -26,9 +26,7 @@ if (!IsValid(setting)) return -1; const SettingDesc *sd = GetSettingFromName(setting); - - void *ptr = GetVariableAddress(&_settings_game, &sd->save); - return (int32)ReadValue(ptr, sd->save.conv); + return sd->AsIntSetting()->Read(&_settings_game); } /* static */ bool ScriptGameSettings::SetValue(const char *setting, int value) @@ -39,7 +37,7 @@ if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false; - return ScriptObject::DoCommand(0, GetSettingIndex(sd), value, CMD_CHANGE_SETTING); + return ScriptObject::DoCommand(0, 0, value, CMD_CHANGE_SETTING, sd->name); } /* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index 9cf6c7c957..0295c67aa7 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -118,7 +118,7 @@ { if (HasWagonRemoval() == enable_removal) return true; - return ScriptObject::DoCommand(0, ::GetCompanySettingIndex("company.renew_keep_length"), enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); + return ScriptObject::DoCommand(0, 0, enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.renew_keep_length"); } /* static */ bool ScriptGroup::HasWagonRemoval() diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 9c81ee01da..d9b4023a81 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -287,7 +287,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() { char buffer[64]; ::GetString(buffer, string, lastof(buffer)); - ::str_validate(buffer, lastof(buffer), SVS_NONE); + ::StrMakeValidInPlace(buffer, lastof(buffer), SVS_NONE); return ::stredup(buffer); } @@ -316,7 +316,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() if (binary_length == 0 && !StrEmpty(text) && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) { /* The string must be valid, i.e. not contain special codes. Since some * can be made with GSText, make sure the control codes are removed. */ - ::str_validate(const_cast(text), text + strlen(text), SVS_NONE); + ::StrMakeValidInPlace(const_cast(text), text + strlen(text), SVS_NONE); } /* Set the default callback to return a true/false result of the DoCommand */ diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp index a251e12d0d..f717a8e389 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -82,7 +82,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) sq_getstring(vm, -1, &value); this->params[parameter] = stredup(value); - ValidateString(this->params[parameter]); + StrMakeValidInPlace(this->params[parameter]); break; } @@ -157,7 +157,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm) if (sq_gettype(vm, 2) == OT_STRING) { const SQChar *key_string; sq_getstring(vm, 2, &key_string); - ValidateString(key_string); + StrMakeValidInPlace(const_cast(key_string)); if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR; k = atoi(key_string + 6); diff --git a/src/script/script_info.cpp b/src/script/script_info.cpp index d02bbe324e..d381ae9c2c 100644 --- a/src/script/script_info.cpp +++ b/src/script/script_info.cpp @@ -122,14 +122,14 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm) while (SQ_SUCCEEDED(sq_next(vm, -2))) { const SQChar *key; if (SQ_FAILED(sq_getstring(vm, -2, &key))) return SQ_ERROR; - ValidateString(key); + StrMakeValidInPlace(const_cast(key)); if (strcmp(key, "name") == 0) { const SQChar *sqvalue; if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR; char *name = stredup(sqvalue); char *s; - ValidateString(name); + StrMakeValidInPlace(name); /* Don't allow '=' and ',' in configure setting names, as we need those * 2 chars to nicely store the settings as a string. */ @@ -141,7 +141,7 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm) const SQChar *sqdescription; if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR; config.description = stredup(sqdescription); - ValidateString(config.description); + StrMakeValidInPlace(const_cast(config.description)); items |= 0x002; } else if (strcmp(key, "min_value") == 0) { SQInteger res; @@ -226,7 +226,7 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm) { const SQChar *setting_name; if (SQ_FAILED(sq_getstring(vm, -2, &setting_name))) return SQ_ERROR; - ValidateString(setting_name); + StrMakeValidInPlace(const_cast(setting_name)); ScriptConfigItem *config = nullptr; for (auto &item : this->config_list) { @@ -253,7 +253,7 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm) /* Because squirrel doesn't support identifiers starting with a digit, * we skip the first character. */ int key = atoi(key_string + 1); - ValidateString(label); + StrMakeValidInPlace(const_cast(label)); /* !Contains() prevents stredup from leaking. */ if (!config->labels->Contains(key)) config->labels->Insert(key, stredup(label)); diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 610f02cfa6..3aa5c35e5a 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -370,7 +370,6 @@ static byte _script_sl_byte; ///< Used as source/target by the script saveload c /** SaveLoad array that saves/loads exactly one byte. */ static const SaveLoad _script_byte[] = { SLEG_VAR(_script_sl_byte, SLE_UINT8), - SLE_END() }; /* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test) diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp index 76e60a66eb..0c4ed735d8 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.cpp @@ -465,7 +465,7 @@ bool Squirrel::CallStringMethodStrdup(HSQOBJECT instance, const char *method_nam if (!this->CallMethod(instance, method_name, &ret, suspend)) return false; if (ret._type != OT_STRING) return false; *res = stredup(ObjectToString(&ret)); - ValidateString(*res); + StrMakeValidInPlace(const_cast(*res)); return true; } diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index 3c6bed6c2c..ff25a5d58a 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -116,7 +116,7 @@ namespace SQConvert { char *tmp_str = stredup(tmp); sq_poptop(vm); ptr->push_back((void *)tmp_str); - str_validate(tmp_str, tmp_str + strlen(tmp_str)); + StrMakeValidInPlace(tmp_str); return tmp_str; } diff --git a/src/settings.cpp b/src/settings.cpp index 25433c70a2..2c51ed3b74 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -22,6 +22,7 @@ */ #include "stdafx.h" +#include #include #include "currency.h" #include "screenshot.h" @@ -119,17 +120,6 @@ const SettingDesc *GetSettingDescription(uint index) return _settings.begin()[index].get(); } -/** - * Get the setting at the given index into the company settings table. - * @param index The index to look for. - * @return The setting at the given index, or nullptr when the index is invalid. - */ -static const SettingDesc *GetCompanySettingDescription(uint index) -{ - if (index >= _company_settings.size()) return nullptr; - return _company_settings.begin()[index].get(); -} - /** * Groups in openttd.cfg that are actually lists. */ @@ -295,7 +285,7 @@ static bool LoadIntList(const char *str, void *array, int nelems, VarType type) */ void ListSettingDesc::FormatValue(char *buf, const char *last, const void *object) const { - const byte *p = static_cast(GetVariableAddress(object, &this->save)); + const byte *p = static_cast(GetVariableAddress(object, this->save)); int i, v = 0; for (i = 0; i != this->save.length; i++) { @@ -497,7 +487,7 @@ void IntSettingDesc::MakeValueValid(int32 &val) const */ void IntSettingDesc::Write(const void *object, int32 val) const { - void *ptr = GetVariableAddress(object, &this->save); + void *ptr = GetVariableAddress(object, this->save); WriteValue(ptr, this->save.conv, (int64)val); } @@ -508,7 +498,7 @@ void IntSettingDesc::Write(const void *object, int32 val) const */ int32 IntSettingDesc::Read(const void *object) const { - void *ptr = GetVariableAddress(object, &this->save); + void *ptr = GetVariableAddress(object, this->save); return (int32)ReadValue(ptr, this->save.conv); } @@ -527,7 +517,7 @@ void StringSettingDesc::MakeValueValid(std::string &str) const * includes the '\0' termination for network transfer purposes. * Also ensure the string is valid after chopping of some bytes. */ std::string stdstr(str, this->max_length - 1); - str.assign(str_validate(stdstr, SVS_NONE)); + str.assign(StrMakeValid(stdstr, SVS_NONE)); } /** @@ -537,7 +527,7 @@ void StringSettingDesc::MakeValueValid(std::string &str) const */ void StringSettingDesc::Write(const void *object, const std::string &str) const { - reinterpret_cast(GetVariableAddress(object, &this->save))->assign(str); + reinterpret_cast(GetVariableAddress(object, this->save))->assign(str); } /** @@ -547,7 +537,7 @@ void StringSettingDesc::Write(const void *object, const std::string &str) const */ const std::string &StringSettingDesc::Read(const void *object) const { - return *reinterpret_cast(GetVariableAddress(object, &this->save)); + return *reinterpret_cast(GetVariableAddress(object, this->save)); } /** @@ -615,7 +605,7 @@ void StringSettingDesc::ParseValue(const IniItem *item, void *object) const void ListSettingDesc::ParseValue(const IniItem *item, void *object) const { const char *str = (item == nullptr) ? this->def : item->value.has_value() ? item->value->c_str() : nullptr; - void *ptr = GetVariableAddress(object, &this->save); + void *ptr = GetVariableAddress(object, this->save); if (!LoadIntList(str, ptr, this->save.length, GetVarMemType(this->save.conv))) { ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY); msg.SetDParamStr(0, this->name); @@ -1703,7 +1693,9 @@ static void PrepareOldDiffCustom() */ static void HandleOldDiffCustom(bool savegame) { - uint options_to_load = GAME_DIFFICULTY_NUM - ((savegame && IsSavegameVersionBefore(SLV_4)) ? 1 : 0); + /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */ + bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4); + uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0); if (!savegame) { /* If we did read to old_diff_custom, then at least one value must be non 0. */ @@ -1715,11 +1707,21 @@ static void HandleOldDiffCustom(bool savegame) if (!old_diff_custom_used) return; } - for (uint i = 0; i < options_to_load; i++) { - const SettingDesc *sd = GetSettingDescription(i); - /* Skip deprecated options */ - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; - int32 value = (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]); + /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */ + uint i = 0; + for (const auto &name : _old_diff_settings) { + if (has_no_town_council_tolerance && name == "town_council_tolerance") continue; + + std::string fullname = "difficulty." + name; + const SettingDesc *sd = GetSettingFromName(fullname.c_str()); + + /* Some settings are no longer in use; skip reading those. */ + if (sd == nullptr) { + i++; + continue; + } + + int32 value = (int32)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]); sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value); } } @@ -2177,20 +2179,75 @@ void IntSettingDesc::ChangeValue(const void *object, int32 newval) const if (_save_config) SaveToConfig(); } +/** + * Given a name of setting, return a setting description from the table. + * @param name Name of the setting to return a setting description of. + * @param settings Table to look in for the setting. + * @return Pointer to the setting description of setting \a name if it can be found, + * \c nullptr indicates failure to obtain the description. + */ +static const SettingDesc *GetSettingFromName(const char *name, const SettingTable &settings) +{ + /* First check all full names */ + for (auto &sd : settings) { + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; + if (strcmp(sd->name, name) == 0) return sd.get(); + } + + /* Then check the shortcut variant of the name. */ + for (auto &sd : settings) { + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; + const char *short_name = strchr(sd->name, '.'); + if (short_name != nullptr) { + short_name++; + if (strcmp(short_name, name) == 0) return sd.get(); + } + } + + return nullptr; +} + +/** + * Given a name of setting, return a company setting description of it. + * @param name Name of the company setting to return a setting description of. + * @return Pointer to the setting description of setting \a name if it can be found, + * \c nullptr indicates failure to obtain the description. + */ +static const SettingDesc *GetCompanySettingFromName(const char *name) +{ + if (strncmp(name, "company.", 8) == 0) name += 8; + return GetSettingFromName(name, _company_settings); +} + +/** + * Given a name of any setting, return any setting description of it. + * @param name Name of the setting to return a setting description of. + * @return Pointer to the setting description of setting \a name if it can be found, + * \c nullptr indicates failure to obtain the description. + */ +const SettingDesc *GetSettingFromName(const char *name) +{ + auto sd = GetSettingFromName(name, _settings); + if (sd != nullptr) return sd; + + return GetCompanySettingFromName(name); +} + /** * Network-safe changing of settings (server-only). * @param tile unused * @param flags operation to perform - * @param p1 the index of the setting in the SettingDesc array which identifies it + * @param p1 unused * @param p2 the new value for the setting * The new value is properly clamped to its minimum/maximum when setting - * @param text unused + * @param text the name of the setting to change * @return the cost of this operation or an error * @see _settings */ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - const SettingDesc *sd = GetSettingDescription(p1); + if (StrEmpty(text)) return CMD_ERROR; + const SettingDesc *sd = GetSettingFromName(text); if (sd == nullptr) return CMD_ERROR; if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) return CMD_ERROR; @@ -2219,15 +2276,17 @@ const char *GetSettingNameByIndex(uint32 idx) * Change one of the per-company settings. * @param tile unused * @param flags operation to perform - * @param p1 the index of the setting in the _company_settings array which identifies it + * @param p1 unused * @param p2 the new value for the setting * The new value is properly clamped to its minimum/maximum when setting - * @param text unused + * @param text the name of the company setting to change * @return the cost of this operation or an error */ CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - const SettingDesc *sd = GetCompanySettingDescription(p1); + if (StrEmpty(text)) return CMD_ERROR; + const SettingDesc *sd = GetCompanySettingFromName(text); + if (sd == nullptr) return CMD_ERROR; if (!sd->IsIntSetting()) return CMD_ERROR; @@ -2244,45 +2303,7 @@ const char *GetCompanySettingNameByIndex(uint32 idx) { if (idx >= _company_settings.size()) return nullptr; - return GetCompanySettingDescription(idx)->name; -} - -/** - * Get the index of the given setting in the setting table. - * @param settings The settings to look through. - * @param setting The setting to look for. - * @return The index, or UINT32_MAX when it has not been found. - */ -static uint GetSettingIndex(const SettingTable &settings, const SettingDesc *setting) -{ - uint index = 0; - for (auto &sd : settings) { - if (sd.get() == setting) return index; - index++; - } - return UINT32_MAX; -} - -/** - * Get the index of the setting with this description. - * @param sd the setting to get the index for. - * @return the index of the setting to be used for CMD_CHANGE_SETTING. - */ -uint GetSettingIndex(const SettingDesc *sd) -{ - assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) == 0); - return GetSettingIndex(_settings, sd); -} - -/** - * Get the index of the company setting with this description. - * @param sd the setting to get the index for. - * @return the index of the setting to be used for CMD_CHANGE_COMPANY_SETTING. - */ -static uint GetCompanySettingIndex(const SettingDesc *sd) -{ - assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) != 0); - return GetSettingIndex(_company_settings, sd); + return _company_settings.begin()[idx]->name; } /** @@ -2297,7 +2318,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) const IntSettingDesc *setting = sd->AsIntSetting(); if ((setting->flags & SGF_PER_COMPANY) != 0) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - return DoCommandP(0, GetCompanySettingIndex(setting), value, CMD_CHANGE_COMPANY_SETTING); + return DoCommandP(0, 0, value, CMD_CHANGE_COMPANY_SETTING, nullptr, setting->name); } else if (setting->flags & SGF_NO_NEWGAME) { return false; } @@ -2327,7 +2348,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && (_network_server || _network_settings_access))) { - return DoCommandP(0, GetSettingIndex(setting), value, CMD_CHANGE_SETTING); + return DoCommandP(0, 0, value, CMD_CHANGE_SETTING, nullptr, setting->name); } return false; } @@ -2353,25 +2374,13 @@ void SyncCompanySettings() { const void *old_object = &Company::Get(_current_company)->settings; const void *new_object = &_settings_client.company; - uint i = 0; for (auto &sd : _company_settings) { uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) NetworkSendCommand(0, i, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, nullptr, _local_company, 0); - i++; + if (old_value != new_value) NetworkSendCommand(0, 0, new_value, 0, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company, 0); } } -/** - * Get the index in the _company_settings array of a setting - * @param name The name of the setting - * @return The index in the _company_settings array - */ -uint GetCompanySettingIndex(const char *name) -{ - return GetCompanySettingIndex(GetSettingFromName(name)); -} - /** * Set a setting value with a string. * @param sd the setting to change. @@ -2419,42 +2428,11 @@ uint GetSettingIndexByFullName(const char *name) return UINT32_MAX; } -/** - * Given a name of setting, return a setting description of it. - * @param name Name of the setting to return a setting description of - * @param i Pointer to an integer that will contain the index of the setting after the call, if it is successful. - * @param ignore_version Return a setting even if it not valid for the current savegame version - * @return Pointer to the setting description of setting \a name if it can be found, - * \c nullptr indicates failure to obtain the description - */ -const SettingDesc *GetSettingFromName(const char *name, bool ignore_version) +const SettingDesc *GetSettingFromFullName(const char *name) { - /* First check all full names */ for (auto &sd : _settings) { - if (sd->name == nullptr) continue; - if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; - if (strcmp(sd->name, name) == 0) return sd.get(); + if (sd->name != nullptr && strcmp(sd->name, name) == 0) return sd.get(); } - - /* Then check the shortcut variant of the name. */ - for (auto &sd : _settings) { - if (sd->name == nullptr) continue; - if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; - const char *short_name = strchr(sd->name, '.'); - if (short_name != nullptr) { - short_name++; - if (strcmp(short_name, name) == 0) return sd.get(); - } - } - - if (strncmp(name, "company.", 8) == 0) name += 8; - /* And finally the company-based settings */ - for (auto &sd : _company_settings) { - if (sd->name == nullptr) continue; - if (!ignore_version && !SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; - if (strcmp(sd->name, name) == 0) return sd.get(); - } - return nullptr; } @@ -2581,7 +2559,7 @@ void IConsoleListSettings(const char *prefilter) */ static void LoadSettingsXref(const SettingDesc *osd, void *object) { DEBUG(sl, 3, "PATS chunk: Loading xref setting: '%s'", osd->xref.target); - const SettingDesc *setting_xref = GetSettingFromName(osd->xref.target, true); + const SettingDesc *setting_xref = GetSettingFromFullName(osd->xref.target); assert(setting_xref != nullptr); // Generate a new SaveLoad from the xref target using the version params from the source @@ -2589,9 +2567,9 @@ static void LoadSettingsXref(const SettingDesc *osd, void *object) { sld.version_from = osd->save.version_from; sld.version_to = osd->save.version_to; sld.ext_feature_test = osd->save.ext_feature_test; - void *ptr = GetVariableAddress(object, &sld); + void *ptr = GetVariableAddress(object, sld); - if (!SlObjectMember(ptr, &sld)) return; + if (!SlObjectMember(ptr, sld)) return; int64 val = ReadValue(ptr, sld.conv); if (osd->xref.conv != nullptr) val = osd->xref.conv(val); if (setting_xref->IsIntSetting()) { @@ -2612,14 +2590,14 @@ static void LoadSettings(const SettingTable &settings, void *object) for (auto &osd : settings) { if (osd->patx_name != nullptr) continue; - const SaveLoad *sld = &osd->save; + const SaveLoad &sld = osd->save; if (osd->xref.target != nullptr) { - if (sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) LoadSettingsXref(osd.get(), object); + if (sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) LoadSettingsXref(osd.get(), object); continue; } void *ptr = GetVariableAddress(object, sld); - if (!SlObjectMember(ptr, &osd->save)) continue; + if (!SlObjectMember(ptr, osd->save)) continue; if (osd->IsIntSetting()) { const IntSettingDesc *int_setting = osd->AsIntSetting(); int_setting->MakeValueValidAndWrite(object, int_setting->Read(object)); @@ -2641,14 +2619,14 @@ static void SaveSettings(const SettingTable &settings, void *object) for (auto &sd : settings) { if (sd->patx_name != nullptr) continue; if (sd->xref.target != nullptr) continue; - length += SlCalcObjMemberLength(object, &sd->save); + length += SlCalcObjMemberLength(object, sd->save); } SlSetLength(length); for (auto &sd : settings) { if (sd->patx_name != nullptr) continue; - void *ptr = GetVariableAddress(object, &sd->save); - SlObjectMember(ptr, &sd->save); + void *ptr = GetVariableAddress(object, sd->save); + SlObjectMember(ptr, sd->save); } } @@ -2708,7 +2686,6 @@ static const SaveLoad _settings_ext_load_desc[] = { SLE_VAR(SettingsExtLoad, flags, SLE_UINT32), SLE_STR(SettingsExtLoad, name, SLE_STRB, 256), SLE_VAR(SettingsExtLoad, setting_length, SLE_UINT32), - SLE_END() }; /** @@ -2724,7 +2701,6 @@ static const SaveLoad _settings_ext_save_desc[] = { SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), - SLE_END() }; /** @@ -2762,7 +2738,7 @@ static void LoadSettingsPatx(const SettingTable &settings, void *object) assert(iter != _sorted_patx_settings.end()); // found setting const SettingDesc *setting = (*iter); - const SaveLoad *sld = &(setting->save); + const SaveLoad &sld = setting->save; size_t read = SlGetBytesRead(); void *ptr = GetVariableAddress(object, sld); SlObjectMember(ptr, sld); @@ -2799,7 +2775,7 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object) size_t length = 8; for (auto &sd : settings) { if (sd->patx_name == nullptr) continue; - uint32 setting_length = (uint32)SlCalcObjMemberLength(object, &sd->save); + uint32 setting_length = (uint32)SlCalcObjMemberLength(object, sd->save); if (!setting_length) continue; current_setting.name = sd->patx_name; @@ -2825,8 +2801,8 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object) current_setting.name = desc->patx_name; current_setting.setting_length = settings_to_add[i].setting_length; SlObject(¤t_setting, _settings_ext_save_desc); - void *ptr = GetVariableAddress(object, &desc->save); - SlObjectMember(ptr, &desc->save); + void *ptr = GetVariableAddress(object, desc->save); + SlObjectMember(ptr, desc->save); } } @@ -2903,7 +2879,7 @@ void LoadSettingsPlyx(bool skip) if (setting != nullptr) { // found setting - const SaveLoad *sld = &(setting->save); + const SaveLoad &sld = setting->save; size_t read = SlGetBytesRead(); void *ptr = GetVariableAddress(&(c->settings), sld); SlObjectMember(ptr, sld); @@ -2933,7 +2909,6 @@ void SaveSettingsPlyx() SLE_VAR(SettingsExtSave, flags, SLE_UINT32), SLE_STR(SettingsExtSave, name, SLE_STR, 0), SLE_VAR(SettingsExtSave, setting_length, SLE_UINT32), - SLE_END() }; std::vector company_setting_counts; @@ -2947,7 +2922,7 @@ void SaveSettingsPlyx() uint32 setting_count = 0; for (auto &sd : _company_settings) { if (sd->patx_name == nullptr) continue; - uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), &sd->save); + uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), sd->save); if (!setting_length) continue; current_setting.name = sd->patx_name; @@ -2978,15 +2953,15 @@ void SaveSettingsPlyx() for (auto &sd : _company_settings) { if (sd->patx_name == nullptr) continue; - uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), &sd->save); + uint32 setting_length = (uint32)SlCalcObjMemberLength(&(c->settings), sd->save); if (!setting_length) continue; current_setting.flags = 0; current_setting.name = sd->patx_name; current_setting.setting_length = setting_length; SlObject(¤t_setting, _settings_plyx_desc); - void *ptr = GetVariableAddress(&(c->settings), &sd->save); - SlObjectMember(ptr, &sd->save); + void *ptr = GetVariableAddress(&(c->settings), sd->save); + SlObjectMember(ptr, sd->save); } } } diff --git a/src/settings_func.h b/src/settings_func.h index d547dc2de2..9e8ec6599b 100644 --- a/src/settings_func.h +++ b/src/settings_func.h @@ -32,7 +32,6 @@ struct GRFConfig *LoadGRFPresetFromConfig(const char *config_name); void SaveGRFPresetToConfig(const char *config_name, struct GRFConfig *config); void DeleteGRFPresetFromConfig(const char *config_name); -uint GetCompanySettingIndex(const char *name); void SetDefaultCompanySettings(CompanyID cid); void SyncCompanySettings(); diff --git a/src/settings_internal.h b/src/settings_internal.h index 7e99dee2ee..a48f1390c5 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -348,9 +348,8 @@ struct XrefSettingDesc : SettingDesc { typedef std::initializer_list> SettingTable; -const SettingDesc *GetSettingFromName(const char *name, bool ignore_version = false); +const SettingDesc *GetSettingFromName(const char *name); bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false); bool SetSettingValue(const StringSettingDesc *sd, const std::string value, bool force_newgame = false); -uint GetSettingIndex(const SettingDesc *sd); #endif /* SETTINGS_INTERNAL_H */ diff --git a/src/settings_type.h b/src/settings_type.h index 50be90bac8..fbb44beab6 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -61,6 +61,9 @@ enum IndustryDensity { /** Settings related to the difficulty of the game */ struct DifficultySettings { + byte competitor_start_time; ///< Unused value, used to load old savegames. + byte competitor_intelligence; ///< Unused value, used to load old savegames. + byte max_no_competitors; ///< the number of competitors (AIs) byte number_towns; ///< the amount of towns byte industry_density; ///< The industry density. @see IndustryDensity diff --git a/src/string.cpp b/src/string.cpp index 5af0b8ba86..30d4c02588 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -216,7 +216,7 @@ const char *str_fix_scc_encoded(char *str, const char *last) template -static void str_validate(T &dst, const char *str, const char *last, StringValidationSettings settings) +static void StrMakeValidInPlace(T &dst, const char *str, const char *last, StringValidationSettings settings) { /* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */ @@ -276,51 +276,52 @@ static void str_validate(T &dst, const char *str, const char *last, StringValida } /** - * Scans the string for valid characters and if it finds invalid ones, - * replaces them with a question mark '?' (if not ignored) - * @param str the string to validate - * @param last the last valid character of str - * @param settings the settings for the string validation. + * Scans the string for invalid characters and replaces then with a + * question mark '?' (if not ignored). + * @param str The string to validate. + * @param last The last valid character of str. + * @param settings The settings for the string validation. * @return pointer to terminating 0. */ -char *str_validate(char *str, const char *last, StringValidationSettings settings) +char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings) { char *dst = str; - str_validate(dst, str, last, settings); + StrMakeValidInPlace(dst, str, last, settings); *dst = '\0'; return dst; } /** - * Scans the string for valid characters and if it finds invalid ones, - * replaces them with a question mark '?' (if not ignored) - * @param str the string to validate - * @param settings the settings for the string validation. + * Scans the string for invalid characters and replaces then with a + * question mark '?' (if not ignored). + * Only use this function when you are sure the string ends with a '\0'; + * otherwise use StrMakeValidInPlace(str, last, settings) variant. + * @param str The string (of which you are sure ends with '\0') to validate. */ -std::string str_validate(const std::string &str, StringValidationSettings settings) +void StrMakeValidInPlace(char *str, StringValidationSettings settings) +{ + /* We know it is '\0' terminated. */ + StrMakeValidInPlace(str, str + strlen(str), settings); +} + +/** + * Scans the string for invalid characters and replaces then with a + * question mark '?' (if not ignored). + * @param str The string to validate. + * @param settings The settings for the string validation. + */ +std::string StrMakeValid(const std::string &str, StringValidationSettings settings) { auto buf = str.data(); auto last = buf + str.size(); std::ostringstream dst; std::ostreambuf_iterator dst_iter(dst); - str_validate(dst_iter, buf, last, settings); + StrMakeValidInPlace(dst_iter, buf, last, settings); return dst.str(); } -/** - * Scans the string for valid characters and if it finds invalid ones, - * replaces them with a question mark '?'. - * @param str the string to validate - */ -void ValidateString(const char *str) -{ - /* We know it is '\0' terminated. */ - str_validate(const_cast(str), str + strlen(str) + 1); -} - - /** * Checks whether the given string is valid, i.e. contains only * valid (printable) characters and is properly terminated. @@ -496,6 +497,16 @@ size_t Utf8StringLength(const char *s) return len; } +/** + * Get the length of an UTF-8 encoded string in number of characters + * and thus not the number of bytes that the encoded string contains. + * @param s The string to get the length for. + * @return The length of the string in characters. + */ +size_t Utf8StringLength(const std::string &str) +{ + return Utf8StringLength(str.c_str()); +} /** * Convert a given ASCII string to lowercase. diff --git a/src/string_func.h b/src/string_func.h index feef8d4c49..8fec9226fb 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -42,9 +42,9 @@ char *str_vfmt(const char *str, va_list ap) WARN_FORMAT(1, 0); std::string CDECL stdstr_fmt(const char *str, ...) WARN_FORMAT(1, 2); std::string stdstr_vfmt(const char *str, va_list va) WARN_FORMAT(1, 0); -char *str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2); -[[nodiscard]] std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); -void ValidateString(const char *str); +char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2); +[[nodiscard]] std::string StrMakeValid(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); +void StrMakeValidInPlace(char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); const char *str_fix_scc_encoded(char *str, const char *last) NOACCESS(2); void str_strip_colours(char *str); @@ -171,6 +171,7 @@ static inline const char *Utf8PrevChar(const char *s) } size_t Utf8StringLength(const char *s); +size_t Utf8StringLength(const std::string &str); /** * Is the given character a lead surrogate code point? diff --git a/src/string_func_extra.h b/src/string_func_extra.h index 5ac5d7ed67..430f3f6f99 100644 --- a/src/string_func_extra.h +++ b/src/string_func_extra.h @@ -11,11 +11,11 @@ #include "string_func.h" #include -static inline void str_validate_inplace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) +static inline void StrMakeValidInPlace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) { if (str.empty()) return; char *buf = str.data(); - str.resize(str_validate(buf, buf + str.size(), settings) - buf); + str.resize(StrMakeValidInPlace(buf, buf + str.size(), settings) - buf); } template diff --git a/src/table/CMakeLists.txt b/src/table/CMakeLists.txt index d2e1e50fa7..d8fefc047d 100644 --- a/src/table/CMakeLists.txt +++ b/src/table/CMakeLists.txt @@ -1,50 +1,4 @@ -set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated) -set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table) - -set(TABLE_INI_SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini -) - -if (HOST_BINARY_DIR) - include(${HOST_BINARY_DIR}/settingsgen.cmake) -endif() - -# Generate a command and target to create the settings table -add_custom_command_timestamp(OUTPUT ${TABLE_BINARY_DIR}/settings.h - COMMAND ${CMAKE_COMMAND} -E make_directory ${TABLE_BINARY_DIR} - COMMAND hostsettingsgen - -o ${TABLE_BINARY_DIR}/settings.h - -b ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble - -a ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble - ${TABLE_INI_SOURCE_FILES} - DEPENDS hostsettingsgen ${TABLE_INI_SOURCE_FILES} - ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble - ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating table/settings.h" -) -add_custom_target_timestamp(table_settings - DEPENDS - ${TABLE_BINARY_DIR}/settings.h -) - -add_library(settings - INTERFACE -) -target_include_directories(settings - INTERFACE - ${GENERATED_BINARY_DIR} -) -add_dependencies(settings - table_settings -) -add_library(openttd::settings ALIAS settings) +add_subdirectory(settings) add_files( airport_defaults.h diff --git a/src/table/settings/CMakeLists.txt b/src/table/settings/CMakeLists.txt new file mode 100644 index 0000000000..c4b0ecf091 --- /dev/null +++ b/src/table/settings/CMakeLists.txt @@ -0,0 +1,47 @@ +set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated) +set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table) + +set(TABLE_INI_SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini +) + +if (HOST_BINARY_DIR) + include(${HOST_BINARY_DIR}/settingsgen.cmake) +endif() + +# Generate a command and target to create the settings table +add_custom_command_timestamp(OUTPUT ${TABLE_BINARY_DIR}/settings.h + COMMAND ${CMAKE_COMMAND} -E make_directory ${TABLE_BINARY_DIR} + COMMAND hostsettingsgen + -o ${TABLE_BINARY_DIR}/settings.h + -b ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble + -a ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble + ${TABLE_INI_SOURCE_FILES} + DEPENDS hostsettingsgen ${TABLE_INI_SOURCE_FILES} + ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble + ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating table/settings.h" +) +add_custom_target_timestamp(table_settings + DEPENDS + ${TABLE_BINARY_DIR}/settings.h +) + +add_library(settings + INTERFACE +) +target_include_directories(settings + INTERFACE + ${GENERATED_BINARY_DIR} +) +add_dependencies(settings + table_settings +) +add_library(openttd::settings ALIAS settings) diff --git a/src/table/company_settings.ini b/src/table/settings/company_settings.ini similarity index 98% rename from src/table/company_settings.ini rename to src/table/settings/company_settings.ini index cb7c7affd4..e34e9bc5f8 100644 --- a/src/table/company_settings.ini +++ b/src/table/settings/company_settings.ini @@ -4,6 +4,9 @@ ; 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 . ; +; These are settings that are company-wide. Meaning that if 1 player in a +; company changes them, it changes for all players. + [pre-amble] static void UpdateServiceInterval(int32 new_value); static bool CanUpdateServiceInterval(VehicleType type, int32 &new_value); diff --git a/src/table/currency_settings.ini b/src/table/settings/currency_settings.ini similarity index 97% rename from src/table/currency_settings.ini rename to src/table/settings/currency_settings.ini index e6a9501049..f950cd52bb 100644 --- a/src/table/currency_settings.ini +++ b/src/table/settings/currency_settings.ini @@ -4,6 +4,8 @@ ; 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 . ; +; Settings for the in-game custom currency. + [pre-amble] static const SettingTable _currency_settings{ [post-amble] diff --git a/src/table/gameopt_settings.ini b/src/table/settings/gameopt_settings.ini similarity index 89% rename from src/table/gameopt_settings.ini rename to src/table/settings/gameopt_settings.ini index cbeb78b3db..bd3d58e974 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/settings/gameopt_settings.ini @@ -4,8 +4,18 @@ ; 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 . ; +; Settings that used to be saved in the savegame under the OPTS chunk and +; under "gameopts" in the configuration file, but no longer are. Most of these +; are now moved to other places. +; +; For backwards compatability, this file dictates how both were saved. When +; a configuration files contains these entries, they are read once, and removed +; from the configuration file afterwards. Those that are still supported will +; be saved in their new place. + [pre-amble] static const uint GAME_DIFFICULTY_NUM = 18; +static const std::array _old_diff_settings{"max_no_competitors", "competitor_start_time", "number_towns", "industry_density", "max_loan", "initial_interest", "vehicle_costs", "competitor_speed", "competitor_intelligence", "vehicle_breakdowns", "subsidy_multiplier", "construction_cost", "terrain_type", "quantity_sea_lakes", "economy", "line_reverse_mode", "disasters", "town_council_tolerance"}; static uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; uint8 _old_diff_level; ///< Old difficulty level from old savegames uint8 _old_units; ///< Old units from old savegames diff --git a/src/table/misc_settings.ini b/src/table/settings/misc_settings.ini similarity index 98% rename from src/table/misc_settings.ini rename to src/table/settings/misc_settings.ini index 7e481cb5af..086e82c7bd 100644 --- a/src/table/misc_settings.ini +++ b/src/table/settings/misc_settings.ini @@ -4,6 +4,9 @@ ; 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 . ; +; Various of settings that are stored in global variables. They are all +; located under "misc" in the configuration files. + [pre-amble] extern std::string _config_language_file; diff --git a/src/table/settings.ini b/src/table/settings/settings.ini similarity index 99% rename from src/table/settings.ini rename to src/table/settings/settings.ini index 460d833771..ff03ce55d1 100644 --- a/src/table/settings.ini +++ b/src/table/settings/settings.ini @@ -4,6 +4,9 @@ ; 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 . ; +; Settings as stored in the main configuration file ("openttd.cfg") and in the +; savegame PATS chunk (if not flagged not to). + [pre-amble] /* Begin - Callback Functions for the various settings */ static void v_PositionMainToolbar(int32 new_value); @@ -186,7 +189,7 @@ enumlist = ; Saved settings variables. -; Do not ADD or REMOVE something in this "difficulty.XXX" table or before it. It breaks savegame compatibility. +; The next 18 entries are important for savegame compatibility. Do NOT remove those. See HandleOldDiffCustom() for more details. [SDT_VAR] var = difficulty.max_no_competitors type = SLE_UINT8 @@ -198,10 +201,14 @@ interval = 1 post_cb = MaxNoAIsChange cat = SC_BASIC -[SDT_NULL] -length = 1 +[SDT_VAR] +var = difficulty.competitor_start_time +type = SLE_UINT8 from = SLV_97 to = SLV_110 +def = 2 +min = 0 +max = 3 [SDT_VAR] var = difficulty.number_towns @@ -284,10 +291,14 @@ strhelp = STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT strval = STR_AI_SPEED_VERY_SLOW cat = SC_BASIC -[SDT_NULL] -length = 1 +[SDT_VAR] +var = difficulty.competitor_intelligence +type = SLE_UINT8 from = SLV_97 to = SLV_110 +def = 0 +min = 0 +max = 2 [SDT_VAR] var = difficulty.vehicle_breakdowns @@ -4089,6 +4100,21 @@ str = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT cat = SC_BASIC +; We might need to emulate a right mouse button on mac +[SDTC_VAR] +ifdef = __APPLE__ +var = gui.right_mouse_btn_emulation +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU +strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT +strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND +cat = SC_BASIC + [SDTC_BOOL] var = gui.measure_tooltip flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -6083,27 +6109,6 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = false cat = SC_EXPERT -; Since the network code (CmdChangeSetting and friends) use the index in this array to decide -; which setting the server is talking about all conditional compilation of this array must be at the -; end. This isn't really the best solution, the settings the server can tell the client about should -; either use a separate array or some other form of identifier. - -; -; We might need to emulate a right mouse button on mac -[SDTC_VAR] -ifdef = __APPLE__ -var = gui.right_mouse_btn_emulation -type = SLE_UINT8 -flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -guiflags = SGF_MULTISTRING -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU -strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT -strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND -cat = SC_BASIC - [SDT_BOOL] var = vehicle.pay_for_repair def = true diff --git a/src/table/win32_settings.ini b/src/table/settings/win32_settings.ini similarity index 93% rename from src/table/win32_settings.ini rename to src/table/settings/win32_settings.ini index 2b5b233b9d..14f933d297 100644 --- a/src/table/win32_settings.ini +++ b/src/table/settings/win32_settings.ini @@ -4,6 +4,9 @@ ; 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 . ; +; Windows specific settings that are stored in global variables. They are all +; located under "win32" in the configuration files. + [pre-amble] /* win32_v.cpp only settings */ #if defined(_WIN32) && !defined(DEDICATED) diff --git a/src/table/window_settings.ini b/src/table/settings/window_settings.ini similarity index 94% rename from src/table/window_settings.ini rename to src/table/settings/window_settings.ini index 9ba1dcca55..0dd94153db 100644 --- a/src/table/window_settings.ini +++ b/src/table/settings/window_settings.ini @@ -4,6 +4,9 @@ ; 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 . ; +; The windows configuration file ("windows.cfg") defines various of properties +; of all windows. + [pre-amble] static const SettingTable _window_settings{ diff --git a/src/tbtr_template_vehicle.h b/src/tbtr_template_vehicle.h index 90b732ced7..0914a0aff7 100644 --- a/src/tbtr_template_vehicle.h +++ b/src/tbtr_template_vehicle.h @@ -27,6 +27,8 @@ #include "sortlist_type.h" +#include "saveload/saveload.h" + #include "zoom_func.h" struct TemplateVehicle; @@ -82,7 +84,7 @@ private: TemplateVehicle *first; ///< NOSAVE: pointer to the first vehicle in the chain public: - friend const SaveLoad* GTD(); + friend const SaveLoadTable GTD(); friend void AfterLoadTemplateVehicles(); // Template usage configuration diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index d6c37a4580..e9223af70a 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -375,7 +375,7 @@ static void Xunzip(byte **bufp, size_t *sizep) this->text = ReallocT(this->text, filesize + 1); this->text[filesize] = '\0'; - /* Replace tabs and line feeds with a space since str_validate removes those. */ + /* Replace tabs and line feeds with a space since StrMakeValidInPlace removes those. */ for (char *p = this->text; *p != '\0'; p++) { if (*p == '\t' || *p == '\r') *p = ' '; } @@ -384,7 +384,7 @@ static void Xunzip(byte **bufp, size_t *sizep) char *p = this->text + (strncmp(u8"\ufeff", this->text, 3) == 0 ? 3 : 0); /* Make sure the string is a valid UTF-8 sequence. */ - str_validate(p, this->text + filesize, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE); + StrMakeValidInPlace(p, this->text + filesize, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE); /* Split the string on newlines. */ int row = 0; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 68012e51ac..70e54f0032 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -25,6 +25,7 @@ #include "newgrf_cache_check.h" #include "landscape.h" #include "network/network.h" +#include "saveload/saveload.h" #include #include #include @@ -231,9 +232,8 @@ typedef Pool VehiclePool; extern VehiclePool _vehicle_pool; /* Some declarations of functions, so we can make them friendly */ -struct SaveLoad; struct GroundVehicleCache; -extern const SaveLoad *GetVehicleDescription(VehicleType vt); +extern SaveLoadTable GetVehicleDescription(VehicleType vt); struct LoadgameState; extern bool LoadOldVehicle(LoadgameState *ls, int num); extern void FixOldVehicles(); @@ -253,7 +253,7 @@ private: Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain public: - friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code + friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code friend void FixOldVehicles(); friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the #previous and #first pointers while loading friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 6f631e2278..445ff19e41 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -229,7 +229,7 @@ static void DedicatedHandleKeyInput() break; } } - str_validate(input_line, lastof(input_line)); + StrMakeValidInPlace(input_line, lastof(input_line)); IConsoleCmdExec(input_line); // execute command } diff --git a/src/viewport_sprite_sorter_sse4.cpp b/src/viewport_sprite_sorter_sse4.cpp index 8ad8702c8d..f4c05f3d03 100644 --- a/src/viewport_sprite_sorter_sse4.cpp +++ b/src/viewport_sprite_sorter_sse4.cpp @@ -17,8 +17,8 @@ #include "safeguards.h" static_assert((sizeof(ParentSpriteToDraw) % 16) == 0); -#ifdef _SQ64 - #define LOAD_128 _mm_load_si128 +#ifdef POINTER_IS_64BIT +# define LOAD_128 _mm_load_si128 #else # define LOAD_128 _mm_loadu_si128 #endif