From 5e1bcee39bd409e37687bcfc2ebe8a5ca9237e77 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 13 Apr 2023 17:16:48 +0200 Subject: [PATCH 01/48] Codechange: introduce a framework for all our timers IntervalTimer and TimeoutTimer use RAII, and can be used to replace all the time-based timeouts, lag-detection, "execute every N" we have. As it uses RAII, you can safely use it as static variable, class member, temporary variable, etc. As soon as it goes out-of-scope, it will be safely removed. This allows for much easier to read code when it comes to intervals. --- src/CMakeLists.txt | 1 + src/date.cpp | 55 ++------- src/openttd.cpp | 5 +- src/stdafx.h | 7 ++ src/timer/CMakeLists.txt | 8 ++ src/timer/timer.h | 187 ++++++++++++++++++++++++++++++ src/timer/timer_game_calendar.cpp | 89 ++++++++++++++ src/timer/timer_game_calendar.h | 76 ++++++++++++ src/timer/timer_manager.h | 86 ++++++++++++++ src/timer/timer_window.cpp | 60 ++++++++++ src/timer/timer_window.h | 35 ++++++ src/window.cpp | 67 +++++------ 12 files changed, 591 insertions(+), 85 deletions(-) create mode 100644 src/timer/CMakeLists.txt create mode 100644 src/timer/timer.h create mode 100644 src/timer/timer_game_calendar.cpp create mode 100644 src/timer/timer_game_calendar.h create mode 100644 src/timer/timer_manager.h create mode 100644 src/timer/timer_window.cpp create mode 100644 src/timer/timer_window.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6919f8e71..2af0f95b2e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,6 +24,7 @@ add_subdirectory(sound) add_subdirectory(spriteloader) add_subdirectory(table) add_subdirectory(tests) +add_subdirectory(timer) add_subdirectory(video) add_subdirectory(widgets) diff --git a/src/date.cpp b/src/date.cpp index 198dd89585..9b51a4b01a 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -20,6 +20,8 @@ #include "saveload/saveload.h" #include "newgrf_profiling.h" #include "widgets/statusbar_widget.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "safeguards.h" @@ -189,7 +191,7 @@ static const Month _autosave_months[] = { /** * Runs various procedures that have to be done yearly */ -static void OnNewYear() +static IntervalTimer _on_new_year({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) { CompaniesYearlyLoop(); VehiclesYearlyLoop(); @@ -222,12 +224,12 @@ static void OnNewYear() } if (_settings_client.gui.auto_euro) CheckSwitchToEuro(); -} +}); /** * Runs various procedures that have to be done monthly */ -static void OnNewMonth() +static IntervalTimer _on_new_month({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto) { if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) { _do_autosave = true; @@ -242,12 +244,12 @@ static void OnNewMonth() SubsidyMonthlyLoop(); StationMonthlyLoop(); if (_network_server) NetworkServerMonthlyLoop(); -} +}); /** * Runs various procedures that have to be done daily */ -static void OnNewDay() +static IntervalTimer _on_new_day({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) { if (!_newgrf_profilers.empty() && _newgrf_profile_end_date <= _date) { NewGRFProfiler::FinishAll(); @@ -263,45 +265,4 @@ static void OnNewDay() /* Refresh after possible snowline change */ SetWindowClassesDirty(WC_TOWN_VIEW); -} - -/** - * Increases the tick counter, increases date and possibly calls - * procedures that have to be called daily, monthly or yearly. - */ -void IncreaseDate() -{ - /* increase day, and check if a new day is there? */ - _tick_counter++; - - if (_game_mode == GM_MENU) return; - - _date_fract++; - if (_date_fract < DAY_TICKS) return; - _date_fract = 0; - - /* increase day counter */ - _date++; - - YearMonthDay ymd; - ConvertDateToYMD(_date, &ymd); - - /* check if we entered a new month? */ - bool new_month = ymd.month != _cur_month; - - /* check if we entered a new year? */ - bool new_year = ymd.year != _cur_year; - - /* update internal variables before calling the daily/monthly/yearly loops */ - _cur_month = ymd.month; - _cur_year = ymd.year; - - /* yes, call various daily loops */ - OnNewDay(); - - /* yes, call various monthly loops */ - if (new_month) OnNewMonth(); - - /* yes, call various yearly loops */ - if (new_year) OnNewYear(); -} +}); diff --git a/src/openttd.cpp b/src/openttd.cpp index 4a7806384a..f719a4dcd5 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -68,6 +68,8 @@ #include "industry.h" #include "network/network_gui.h" #include "misc_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "linkgraph/linkgraphschedule.h" @@ -82,7 +84,6 @@ #endif void CallLandscapeTick(); -void IncreaseDate(); void DoPaletteAnimations(); void MusicLoop(); void ResetMusic(); @@ -1408,7 +1409,7 @@ void StateGameLoop() BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP); AnimateAnimatedTiles(); - IncreaseDate(); + TimerManager::Elapsed(1); RunTileLoop(); CallVehicleTicks(); CallLandscapeTick(); diff --git a/src/stdafx.h b/src/stdafx.h index f62a83e83c..d7da1ad8fc 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -155,6 +155,13 @@ # define NOACCESS(args) #endif +/* [[nodiscard]] on constructors doesn't work in GCC older than 10.1. */ +#if __GNUC__ < 10 || (__GNUC__ == 10 && __GNUC_MINOR__ < 1) +# define NODISCARD +#else +# define NODISCARD [[nodiscard]] +#endif + #if defined(__WATCOMC__) # define NORETURN # define CDECL diff --git a/src/timer/CMakeLists.txt b/src/timer/CMakeLists.txt new file mode 100644 index 0000000000..de9e01636f --- /dev/null +++ b/src/timer/CMakeLists.txt @@ -0,0 +1,8 @@ +add_files( + timer_game_calendar.cpp + timer_game_calendar.h + timer_window.cpp + timer_window.h + timer_manager.h + timer.h +) diff --git a/src/timer/timer.h b/src/timer/timer.h new file mode 100644 index 0000000000..3c45df55a9 --- /dev/null +++ b/src/timer/timer.h @@ -0,0 +1,187 @@ +/* + * 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 timer.h Definition of Interval and OneShot timers */ + +#ifndef TIMER_H +#define TIMER_H + +#include "timer_manager.h" + +#include + +/** + * The base where every other type of timer is derived from. + * + * Never use this class directly yourself. + */ +template +class BaseTimer { +public: + using TPeriod = typename TTimerType::TPeriod; + using TElapsed = typename TTimerType::TElapsed; + using TStorage = typename TTimerType::TStorage; + + /** + * Create a new timer. + * + * @param period The period of the timer. + */ + NODISCARD BaseTimer(const TPeriod period) : + period(period) + { + TimerManager::RegisterTimer(*this); + } + + /** + * Delete the timer. + */ + virtual ~BaseTimer() + { + TimerManager::UnregisterTimer(*this); + } + + /* Although these variables are public, they are only public to make saveload easier; not for common use. */ + + TPeriod period; ///< The period of the timer. + TStorage storage = {}; ///< The storage of the timer. + +protected: + /** + * Called by the timer manager to notify the timer that the given amount of time has elapsed. + * + * @param delta Depending on the time type, this is either in milliseconds or in ticks. + */ + virtual void Elapsed(TElapsed delta) = 0; + + /* To ensure only TimerManager can access Elapsed. */ + friend class TimerManager; +}; + +/** + * An interval timer will fire every interval, and will continue to fire until it is deleted. + * + * The callback receives how many times the timer has fired since the last time it fired. + * It will always try to fire every interval, but in times of severe stress it might be late. + * + * Each Timer-type needs to implement the Elapsed() method, and call the callback if needed. + * + * Setting the period to zero disables the interval. It can be reenabled at any time by + * calling SetInterval() with a non-zero period. + */ +template +class IntervalTimer : public BaseTimer { +public: + using TPeriod = typename TTimerType::TPeriod; + using TElapsed = typename TTimerType::TElapsed; + + /** + * Create a new interval timer. + * + * @param interval The interval between each callback. + * @param callback The callback to call when the interval has passed. + */ + NODISCARD IntervalTimer(const TPeriod interval, std::function callback) : + BaseTimer(interval), + callback(callback) + { + } + + /** + * Set a new interval for the timer. + * + * @param interval The interval between each callback. + * @param reset Whether to reset the timer to zero. + */ + void SetInterval(const TPeriod interval, bool reset = true) + { + this->period = interval; + if (reset) this->storage = {}; + } + +private: + std::function callback; + + void Elapsed(TElapsed count) override; +}; + +/** + * A timeout timer will fire once after the interval. You can reset it to fire again. + * The timer will never fire before the interval has passed, but in times of severe stress it might be late. + */ +template +class TimeoutTimer : public BaseTimer { +public: + using TPeriod = typename TTimerType::TPeriod; + using TElapsed = typename TTimerType::TElapsed; + + /** + * Create a new timeout timer. + * + * By default the timeout starts aborted; you will have to call Reset() before it starts. + * + * @param timeout The timeout after which the timer will fire. + * @param callback The callback to call when the timeout has passed. + * @param start Whether to start the timer immediately. If false, you can call Reset() to start it. + */ + NODISCARD TimeoutTimer(const TPeriod timeout, std::function callback, bool start = false) : + BaseTimer(timeout), + fired(!start), + callback(callback) + { + } + + /** + * Reset the timer, so it will fire again after the timeout. + */ + void Reset() + { + this->fired = false; + this->storage = {}; + } + + /** + * Reset the timer, so it will fire again after the timeout. + * + * @param timeout Set a new timeout for the next trigger. + */ + void Reset(const TPeriod timeout) + { + this->period = timeout; + this->fired = false; + this->storage = {}; + } + + /** + * Abort the timer so it doesn't fire if it hasn't yet. + */ + void Abort() + { + this->fired = true; + } + + /** + * Check whether the timeout occurred. + * + * @return True iff the timeout occurred. + */ + bool HasFired() const + { + return this->fired; + } + + /* Although these variables are public, they are only public to make saveload easier; not for common use. */ + + bool fired; ///< Whether the timeout has occurred. + +private: + std::function callback; + + void Elapsed(TElapsed count) override; +}; + +#endif /* TIMER_H */ diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp new file mode 100644 index 0000000000..6ab290eb13 --- /dev/null +++ b/src/timer/timer_game_calendar.cpp @@ -0,0 +1,89 @@ +/* + * 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 timer_game_calendar.cpp + * This file implements the timer logic for the game-calendar-timer. + */ + +#include "stdafx.h" +#include "date_func.h" +#include "openttd.h" +#include "timer.h" +#include "timer_game_calendar.h" +#include "vehicle_base.h" +#include "linkgraph/linkgraph.h" + +#include "safeguards.h" + +template<> +void IntervalTimer::Elapsed(TimerGameCalendar::TElapsed trigger) +{ + if (trigger == this->period.trigger) { + this->callback(1); + } +} + +template<> +void TimeoutTimer::Elapsed(TimerGameCalendar::TElapsed trigger) +{ + if (this->fired) return; + + if (trigger == this->period.trigger) { + this->callback(); + this->fired = true; + } +} + +template<> +void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) +{ + assert(delta == 1); + + _tick_counter++; + + if (_game_mode == GM_MENU) return; + + _date_fract++; + if (_date_fract < DAY_TICKS) return; + _date_fract = 0; + + /* increase day counter */ + _date++; + + YearMonthDay ymd; + ConvertDateToYMD(_date, &ymd); + + /* check if we entered a new month? */ + bool new_month = ymd.month != _cur_month; + + /* check if we entered a new year? */ + bool new_year = ymd.year != _cur_year; + + /* update internal variables before calling the daily/monthly/yearly loops */ + _cur_month = ymd.month; + _cur_year = ymd.year; + + /* Make a temporary copy of the timers, as a timer's callback might add/remove other timers. */ + auto timers = TimerManager::GetTimers(); + + for (auto timer : timers) { + timer->Elapsed(TimerGameCalendar::DAY); + } + + if (new_month) { + for (auto timer : timers) { + timer->Elapsed(TimerGameCalendar::MONTH); + } + } + + if (new_year) { + for (auto timer : timers) { + timer->Elapsed(TimerGameCalendar::YEAR); + } + } +} diff --git a/src/timer/timer_game_calendar.h b/src/timer/timer_game_calendar.h new file mode 100644 index 0000000000..f7dd3dd499 --- /dev/null +++ b/src/timer/timer_game_calendar.h @@ -0,0 +1,76 @@ +/* + * 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 timer_game_calendar.h Definition of the game-calendar-timer */ + +#ifndef TIMER_GAME_CALENDAR_H +#define TIMER_GAME_CALENDAR_H + +/** + * Timer that is increased every 27ms, and counts towards ticks / days / months / years. + * + * The amount of days in a month depends on the month and year (leap-years). + * There are always 74 ticks in a day (and with 27ms, this makes 1 day 1.998 seconds). + * + * IntervalTimer and TimeoutTimer based on this Timer are a bit unusual, as their count is always one. + * You create those timers based on a transition: a new day, a new month or a new year. + * + * Additionally, you need to set a priority. To ensure deterministic behaviour, events are executed + * in priority. It is important that if you assign NONE, you do not use Random() in your callback. + * Other than that, make sure you only set one callback per priority. + * + * For example: + * IntervalTimer({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count){}); + * + */ +class TimerGameCalendar { +public: + enum Trigger { + DAY, + MONTH, + YEAR, + }; + enum Priority { + NONE, ///< These timers can be executed in any order; there is no Random() in them, so order is not relevant. + + /* All other may have a Random() call in them, so order is important. + * For safety, you can only setup a single timer on a single priority. */ + AUTOSAVE, + COMPANY, + DISASTER, + ENGINE, + INDUSTRY, + STATION, + SUBSIDY, + TOWN, + VEHICLE, + }; + + struct TPeriod { + Trigger trigger; + Priority priority; + + TPeriod(Trigger trigger, Priority priority) : trigger(trigger), priority(priority) {} + + bool operator < (const TPeriod &other) const + { + if (this->trigger != other.trigger) return this->trigger < other.trigger; + return this->priority < other.priority; + } + + bool operator == (const TPeriod &other) const + { + return this->trigger == other.trigger && this->priority == other.priority; + } + }; + + using TElapsed = uint; + struct TStorage { + }; +}; + +#endif /* TIMER_GAME_CALENDAR_H */ diff --git a/src/timer/timer_manager.h b/src/timer/timer_manager.h new file mode 100644 index 0000000000..2efe583ad9 --- /dev/null +++ b/src/timer/timer_manager.h @@ -0,0 +1,86 @@ +/* + * 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 timer_manager.h Definition of the TimerManager */ +/** @note don't include this file; include "timer.h". */ + +#ifndef TIMER_MANAGER_H +#define TIMER_MANAGER_H + +#include "stdafx.h" + +#include + +template +class BaseTimer; + +/** + * The TimerManager manages a single Timer-type. + * + * It allows for automatic registration and unregistration of timers like Interval and OneShot. + * + * Each Timer-type needs to implement the Elapsed() method, and distribute that to the timers if needed. + */ +template +class TimerManager { +public: + using TElapsed = typename TTimerType::TElapsed; + + /* Avoid copying this object; it is a singleton object. */ + TimerManager(TimerManager const &) = delete; + TimerManager &operator=(TimerManager const &) = delete; + + /** + * Register a timer. + * + * @param timer The timer to register. + */ + static void RegisterTimer(BaseTimer &timer) { + GetTimers().insert(&timer); + } + + /** + * Unregister a timer. + * + * @param timer The timer to unregister. + */ + static void UnregisterTimer(BaseTimer &timer) { + GetTimers().erase(&timer); + } + + /** + * Called when time for this timer elapsed. + * + * The implementation per type is different, but they all share a similar goal: + * Call the Elapsed() method of all active timers. + * + * @param value The amount of time that has elapsed. + */ + static void Elapsed(TElapsed value); + +private: + /** + * Sorter for timers. + * + * It will sort based on the period, smaller first. If the period is the + * same, it will sort based on the pointer value. + */ + struct base_timer_sorter { + bool operator() (BaseTimer *a, BaseTimer *b) const { + if (a->period == b->period) return a < b; + return a->period < b->period; + } + }; + + /** Singleton list, to store all the active timers. */ + static std::set *, base_timer_sorter> &GetTimers() { + static std::set *, base_timer_sorter> timers; + return timers; + } +}; + +#endif /* TIMER_MANAGER_H */ diff --git a/src/timer/timer_window.cpp b/src/timer/timer_window.cpp new file mode 100644 index 0000000000..dff0b45b8a --- /dev/null +++ b/src/timer/timer_window.cpp @@ -0,0 +1,60 @@ +/* + * 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 timer_window.cpp + * This file implements the timer logic for the Window system. + */ + +#include "stdafx.h" +#include "timer.h" +#include "timer_window.h" + +#include "safeguards.h" + +template<> +void IntervalTimer::Elapsed(TimerWindow::TElapsed delta) +{ + if (this->period == std::chrono::milliseconds::zero()) return; + + this->storage.elapsed += delta; + + uint count = 0; + while (this->storage.elapsed >= this->period) { + this->storage.elapsed -= this->period; + count++; + } + + if (count > 0) { + this->callback(count); + } +} + +template<> +void TimeoutTimer::Elapsed(TimerWindow::TElapsed delta) +{ + if (this->fired) return; + if (this->period == std::chrono::milliseconds::zero()) return; + + this->storage.elapsed += delta; + + if (this->storage.elapsed >= this->period) { + this->callback(); + this->fired = true; + } +} + +template<> +void TimerManager::Elapsed(TimerWindow::TElapsed delta) +{ + /* Make a temporary copy of the timers, as a timer's callback might add/remove other timers. */ + auto timers = TimerManager::GetTimers(); + + for (auto timer : timers) { + timer->Elapsed(delta); + } +} diff --git a/src/timer/timer_window.h b/src/timer/timer_window.h new file mode 100644 index 0000000000..b32048b4c4 --- /dev/null +++ b/src/timer/timer_window.h @@ -0,0 +1,35 @@ +/* + * 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 timer_window.h Definition of the Window system */ + +#ifndef TIMER_WINDOW_H +#define TIMER_WINDOW_H + +#include + +/** + * Timer that represents the real time, usable for the Window system. + * + * This can be used to create intervals based on milliseconds, seconds, etc. + * Mostly used for animation, scrolling, etc. + * + * Please be mindful that the order in which timers are called is not guaranteed. + * + * @note The lowest possible interval is 1ms. + * @note These timers can only be used in the Window system. + */ +class TimerWindow { +public: + using TPeriod = std::chrono::milliseconds; + using TElapsed = std::chrono::milliseconds; + struct TStorage { + std::chrono::milliseconds elapsed; + }; +}; + +#endif /* TIMER_WINDOW_H */ diff --git a/src/window.cpp b/src/window.cpp index 00ed25c7dc..e7db416316 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -39,6 +39,8 @@ #include "network/network_func.h" #include "guitimer_func.h" #include "news_func.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "safeguards.h" @@ -3076,6 +3078,34 @@ void CallWindowRealtimeTickEvent(uint delta_ms) } } +/** Update various of window-related information on a regular interval. */ +static IntervalTimer window_interval(std::chrono::milliseconds(30), [](auto) { + extern int _caret_timer; + _caret_timer += 3; + CursorTick(); + + HandleKeyScrolling(); + HandleAutoscroll(); + DecreaseWindowCounters(); +}); + +/** Blink the window highlight colour constantly. */ +static IntervalTimer highlight_interval(std::chrono::milliseconds(450), [](auto) { + _window_highlight_colour = !_window_highlight_colour; +}); + +/** Blink all windows marked with a white border. */ +static IntervalTimer white_border_interval(std::chrono::milliseconds(30), [](auto) { + if (_network_dedicated) return; + + for (Window *w : Window::Iterate()) { + if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) { + CLRBITS(w->flags, WF_WHITE_BORDER); + w->SetDirty(); + } + } +}); + /** * Update the continuously changing contents of the windows, such as the viewports */ @@ -3093,56 +3123,21 @@ void UpdateWindows() ProcessPendingPerformanceMeasurements(); + TimerManager::Elapsed(std::chrono::milliseconds(delta_ms)); CallWindowRealtimeTickEvent(delta_ms); - static GUITimer network_message_timer = GUITimer(1); - if (network_message_timer.Elapsed(delta_ms)) { - network_message_timer.SetInterval(1000); - NetworkChatMessageLoop(); - } - /* Process invalidations before anything else. */ for (Window *w : Window::Iterate()) { w->ProcessScheduledInvalidations(); w->ProcessHighlightedInvalidations(); } - static GUITimer window_timer = GUITimer(1); - if (window_timer.Elapsed(delta_ms)) { - if (_network_dedicated) window_timer.SetInterval(MILLISECONDS_PER_TICK); - - extern int _caret_timer; - _caret_timer += 3; - CursorTick(); - - HandleKeyScrolling(); - HandleAutoscroll(); - DecreaseWindowCounters(); - } - - static GUITimer highlight_timer = GUITimer(1); - if (highlight_timer.Elapsed(delta_ms)) { - highlight_timer.SetInterval(450); - _window_highlight_colour = !_window_highlight_colour; - } - if (!_pause_mode || _game_mode == GM_EDITOR || _settings_game.construction.command_pause_level > CMDPL_NO_CONSTRUCTION) MoveAllTextEffects(delta_ms); /* Skip the actual drawing on dedicated servers without screen. * But still empty the invalidation queues above. */ if (_network_dedicated) return; - if (window_timer.HasElapsed()) { - window_timer.SetInterval(MILLISECONDS_PER_TICK); - - for (Window *w : Window::Iterate()) { - if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) { - CLRBITS(w->flags, WF_WHITE_BORDER); - w->SetDirty(); - } - } - } - DrawDirtyBlocks(); for (Window *w : Window::Iterate()) { From 1ba4dcc92458b078dc869d381075b6c071221950 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 13 Apr 2023 17:18:27 +0200 Subject: [PATCH 02/48] Codechange: migrate all Window-related timers to the new framework This means we also say goodbye to GUITimers. --- src/CMakeLists.txt | 1 - src/company_gui.cpp | 18 +++++---- src/console_gui.cpp | 13 +++---- src/error.h | 7 ++-- src/error_gui.cpp | 41 ++++++++++++--------- src/framerate_gui.cpp | 31 +++++++--------- src/game/game_gui.cpp | 20 +++++----- src/graph_gui.cpp | 16 ++++++-- src/guitimer_func.h | 63 -------------------------------- src/industry_gui.cpp | 13 ++++--- src/main_gui.cpp | 38 +++++++++++-------- src/misc_gui.cpp | 33 +++++++---------- src/network/network_chat_gui.cpp | 9 +++-- src/network/network_func.h | 1 - src/network/network_gui.cpp | 16 +++----- src/newgrf_gui.cpp | 18 ++++----- src/news_gui.cpp | 28 ++++++-------- src/script/script_gui.cpp | 20 +++++----- src/signs_gui.cpp | 8 ++-- src/smallmap_gui.cpp | 28 ++++++++++---- src/smallmap_gui.h | 21 ++++++++--- src/statusbar_gui.cpp | 38 ++++++++----------- src/texteff.cpp | 14 +++---- src/texteff.hpp | 1 - src/toolbar_gui.cpp | 29 ++++----------- src/town_gui.cpp | 14 ++++--- src/widgets/dropdown.cpp | 26 ++++++------- src/window.cpp | 23 ++++-------- src/window_gui.h | 7 ---- 29 files changed, 259 insertions(+), 336 deletions(-) delete mode 100644 src/guitimer_func.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2af0f95b2e..b251378fad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -192,7 +192,6 @@ add_files( group_gui.h group_type.h gui.h - guitimer_func.h heightmap.cpp heightmap.h highscore.cpp diff --git a/src/company_gui.cpp b/src/company_gui.cpp index dfb1415fcf..1d923c6d61 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -42,6 +42,8 @@ #include "group_cmd.h" #include "misc_cmd.h" #include "object_cmd.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/company_widget.h" @@ -519,15 +521,18 @@ struct CompanyFinancesWindow : Window { } } - void OnHundredthTick() override - { + /** + * Check on a regular interval if the maximum amount of money has changed. + * If it has, rescale the window to fit the new amount. + */ + IntervalTimer rescale_interval = {std::chrono::seconds(3), [this](auto) { const Company *c = Company::Get((CompanyID)this->window_number); if (c->money > CompanyFinancesWindow::max_money) { CompanyFinancesWindow::max_money = std::max(c->money * 2, CompanyFinancesWindow::max_money * 4); this->SetupWidgets(); this->ReInit(); } - } + }}; }; /** First conservative estimate of the maximum amount of money */ @@ -2679,11 +2684,10 @@ struct CompanyWindow : Window } } - void OnHundredthTick() override - { - /* redraw the window every now and then */ + /** Redraw the window on a regular interval. */ + IntervalTimer redraw_interval = {std::chrono::seconds(3), [this](auto) { this->SetDirty(); - } + }}; void OnPlaceObject(Point pt, TileIndex tile) override { diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 972ef23b24..270d005d0e 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -12,7 +12,6 @@ #include "window_gui.h" #include "console_gui.h" #include "console_internal.h" -#include "guitimer_func.h" #include "window_func.h" #include "string_func.h" #include "strings_func.h" @@ -21,6 +20,8 @@ #include "console_func.h" #include "rev.h" #include "video/video_driver.hpp" +#include "timer/timer.h" +#include "timer/timer_window.h" #include #include @@ -115,14 +116,12 @@ struct IConsoleWindow : Window static size_t scroll; int line_height; ///< Height of one line of text in the console. int line_offset; - GUITimer truncate_timer; IConsoleWindow() : Window(&_console_window_desc) { _iconsole_mode = ICONSOLE_OPENED; this->InitNested(0); - this->truncate_timer.SetInterval(3000); ResizeWindow(this, _screen.width, _screen.height / 3); } @@ -186,10 +185,8 @@ struct IConsoleWindow : Window } } - void OnRealtimeTick(uint delta_ms) override - { - if (this->truncate_timer.CountElapsed(delta_ms) == 0) return; - + /** Check on a regular interval if the console buffer needs truncating. */ + IntervalTimer truncate_interval = {std::chrono::seconds(3), [this](auto) { assert(this->height >= 0 && this->line_height > 0); size_t visible_lines = (size_t)(this->height / this->line_height); @@ -198,7 +195,7 @@ struct IConsoleWindow : Window IConsoleWindow::scroll = std::min(IConsoleWindow::scroll, max_scroll); this->SetDirty(); } - } + }}; void OnMouseLoop() override { diff --git a/src/error.h b/src/error.h index 51b164c432..cac0c503bf 100644 --- a/src/error.h +++ b/src/error.h @@ -15,7 +15,8 @@ #include "company_type.h" #include "command_type.h" #include "core/geometry_type.hpp" -#include "guitimer_func.h" + +#include struct GRFFile; @@ -30,7 +31,7 @@ enum WarningLevel { /** The data of the error message. */ class ErrorMessageData { protected: - GUITimer display_timer; ///< Timer before closing the message. + bool is_critical; ///< Whether the error message is critical. uint64 decode_params[20]; ///< Parameters of the message strings. const char *strings[20]; ///< Copies of raw strings that were used. const GRFFile *textref_stack_grffile; ///< NewGRF that filled the #TextRefStack for the error message. @@ -45,7 +46,7 @@ protected: public: ErrorMessageData(const ErrorMessageData &data); ~ErrorMessageData(); - ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr, StringID extra_msg = INVALID_STRING_ID); + ErrorMessageData(StringID summary_msg, StringID detailed_msg, bool is_critical = false, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr, StringID extra_msg = INVALID_STRING_ID); /* Remove the copy assignment, as the default implementation will not do the right thing. */ ErrorMessageData &operator=(ErrorMessageData &rhs) = delete; diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 6d05d24395..b682e7e257 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -21,6 +21,8 @@ #include "window_func.h" #include "console_func.h" #include "window_gui.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/error_widget.h" @@ -71,7 +73,7 @@ static WindowDesc _errmsg_face_desc( * @param data The data to copy. */ ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) : - display_timer(data.display_timer), textref_stack_grffile(data.textref_stack_grffile), textref_stack_size(data.textref_stack_size), + is_critical(data.is_critical), textref_stack_grffile(data.textref_stack_grffile), textref_stack_size(data.textref_stack_size), summary_msg(data.summary_msg), detailed_msg(data.detailed_msg), extra_msg(data.extra_msg), position(data.position), face(data.face) { memcpy(this->textref_stack, data.textref_stack, sizeof(this->textref_stack)); @@ -95,7 +97,7 @@ ErrorMessageData::~ErrorMessageData() * Display an error message in a window. * @param summary_msg General error message showed in first line. Must be valid. * @param detailed_msg Detailed error message showed in second line. Can be INVALID_STRING_ID. - * @param duration The amount of time to show this error message. + * @param is_critical Whether the error is critical. Critical messages never go away on their own. * @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. * @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. * @param textref_stack_grffile NewGRF that provides the #TextRefStack for the error message. @@ -103,7 +105,8 @@ ErrorMessageData::~ErrorMessageData() * @param textref_stack Values to put on the #TextRefStack. * @param extra_msg Extra error message showed in third line. Can be INVALID_STRING_ID. */ -ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) : +ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, bool is_critical, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) : + is_critical(is_critical), textref_stack_grffile(textref_stack_grffile), textref_stack_size(textref_stack_size), summary_msg(summary_msg), @@ -120,8 +123,6 @@ ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, if (textref_stack_size > 0) MemCpyT(this->textref_stack, textref_stack, textref_stack_size); assert(summary_msg != INVALID_STRING_ID); - - this->display_timer.SetInterval(duration * 3000); } /** @@ -187,11 +188,22 @@ private: uint height_summary; ///< Height of the #summary_msg string in pixels in the #WID_EM_MESSAGE widget. uint height_detailed; ///< Height of the #detailed_msg string in pixels in the #WID_EM_MESSAGE widget. uint height_extra; ///< Height of the #extra_msg string in pixels in the #WID_EM_MESSAGE widget. + TimeoutTimer display_timeout; public: - ErrmsgWindow(const ErrorMessageData &data) : Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc), ErrorMessageData(data) + ErrmsgWindow(const ErrorMessageData &data) : + Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc), + ErrorMessageData(data), + display_timeout(std::chrono::seconds(3 * _settings_client.gui.errmsg_duration), [this]() { + this->Close(); + }) { this->InitNested(); + + /* Only start the timeout if the message is not critical. */ + if (!this->is_critical) { + this->display_timeout.Reset(); + } } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override @@ -316,14 +328,7 @@ public: void OnMouseLoop() override { /* Disallow closing the window too easily, if timeout is disabled */ - if (_right_button_down && !this->display_timer.HasElapsed()) this->Close(); - } - - void OnRealtimeTick(uint delta_ms) override - { - if (this->display_timer.CountElapsed(delta_ms) == 0) return; - - this->Close(); + if (_right_button_down && !this->is_critical) this->Close(); } void Close() override @@ -339,7 +344,7 @@ public: */ bool IsCritical() { - return this->display_timer.HasElapsed(); + return this->is_critical; } }; @@ -428,12 +433,12 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel IConsolePrint(wl == WL_WARNING ? CC_WARNING : CC_ERROR, buf); } - bool no_timeout = wl == WL_CRITICAL; + bool is_critical = wl == WL_CRITICAL; if (_game_mode == GM_BOOTSTRAP) return; - if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return; + if (_settings_client.gui.errmsg_duration == 0 && !is_critical) return; - ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg); + ErrorMessageData data(summary_msg, detailed_msg, is_critical, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg); data.CopyOutDParams(); ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0); diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 1a676933ee..e4db1ee341 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -17,12 +17,13 @@ #include "strings_func.h" #include "console_func.h" #include "console_type.h" -#include "guitimer_func.h" #include "company_base.h" #include "ai/ai_info.hpp" #include "ai/ai_instance.hpp" #include "game/game.hpp" #include "game/game_instance.hpp" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/framerate_widget.h" @@ -410,7 +411,6 @@ static const NWidgetPart _framerate_window_widgets[] = { struct FramerateWindow : Window { bool small; bool showing_memory; - GUITimer next_update; int num_active; int num_displayed; @@ -456,7 +456,6 @@ struct FramerateWindow : Window { this->showing_memory = true; this->UpdateData(); this->num_displayed = this->num_active; - this->next_update.SetInterval(100); /* Window is always initialised to MIN_ELEMENTS height, resize to contain num_displayed */ ResizeWindow(this, 0, (std::max(MIN_ELEMENTS, this->num_displayed) - MIN_ELEMENTS) * FONT_HEIGHT_NORMAL); @@ -464,22 +463,21 @@ struct FramerateWindow : Window { void OnRealtimeTick(uint delta_ms) override { - bool elapsed = this->next_update.Elapsed(delta_ms); - /* Check if the shaded state has changed, switch caption text if it has */ if (this->small != this->IsShaded()) { this->small = this->IsShaded(); this->GetWidget(WID_FRW_CAPTION)->SetDataTip(this->small ? STR_FRAMERATE_CAPTION_SMALL : STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); - elapsed = true; - } - - if (elapsed) { this->UpdateData(); this->SetDirty(); - this->next_update.SetInterval(100); } } + /** Update the window on a regular interval. */ + IntervalTimer update_interval = {std::chrono::milliseconds(100), [this](auto) { + this->UpdateData(); + this->SetDirty(); + }}; + void UpdateData() { double gl_rate = _pf_data[PFE_GAMELOOP].GetRate(); @@ -754,7 +752,6 @@ static const NWidgetPart _frametime_graph_window_widgets[] = { struct FrametimeGraphWindow : Window { int vertical_scale; ///< number of TIMESTAMP_PRECISION units vertically int horizontal_scale; ///< number of half-second units horizontally - GUITimer next_scale_update; ///< interval for next scale update PerformanceElement element; ///< what element this window renders graph for Dimension graph_size; ///< size of the main graph area (excluding axis labels) @@ -764,9 +761,9 @@ struct FrametimeGraphWindow : Window { this->element = (PerformanceElement)number; this->horizontal_scale = 4; this->vertical_scale = TIMESTAMP_PRECISION / 10; - this->next_scale_update.SetInterval(1); this->InitNested(number); + this->UpdateScale(); } void SetStringParameters(int widget) const override @@ -882,14 +879,14 @@ struct FrametimeGraphWindow : Window { this->SelectVerticalScale(peak_value); } + /** Update the scaling on a regular interval. */ + IntervalTimer update_interval = {std::chrono::milliseconds(500), [this](auto) { + this->UpdateScale(); + }}; + void OnRealtimeTick(uint delta_ms) override { this->SetDirty(); - - if (this->next_scale_update.Elapsed(delta_ms)) { - this->next_scale_update.SetInterval(500); - this->UpdateScale(); - } } /** Scale and interpolate a value from a source range into a destination range */ diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index fc53f9a43a..0d941d884a 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -15,6 +15,8 @@ #include "../network/network.h" #include "../network/network_content.h" #include "../widgets/dropdown_func.h" +#include "../timer/timer.h" +#include "../timer/timer_window.h" #include "game.hpp" #include "game_gui.hpp" @@ -83,7 +85,6 @@ struct GSConfigWindow : public Window { bool clicked_increase; ///< Whether we clicked the increase or decrease button. bool clicked_dropdown; ///< Whether the dropdown is open. bool closing_dropdown; ///< True, if the dropdown list is currently closing. - GUITimer timeout; ///< Timeout for unclicking the button. int clicked_row; ///< The clicked row of settings. Scrollbar *vscroll; ///< Cache of the vertical scrollbar. typedef std::vector VisibleSettingsList; ///< typdef for a vector of script settings @@ -92,8 +93,7 @@ struct GSConfigWindow : public Window { GSConfigWindow() : Window(&_gs_config_desc), clicked_button(-1), clicked_dropdown(false), - closing_dropdown(false), - timeout(0) + closing_dropdown(false) { this->gs_config = GameConfig::GetConfig(); @@ -336,7 +336,7 @@ struct GSConfigWindow : public Window { if (new_val != old_val) { this->gs_config->SetSetting(config_item.name, new_val); this->clicked_button = num; - this->timeout.SetInterval(150); + this->unclick_timeout.Reset(); } } else if (!bool_item && !config_item.complete_labels) { /* Display a query box so users can enter a custom value. */ @@ -387,13 +387,11 @@ struct GSConfigWindow : public Window { this->vscroll->SetCapacityFromWidget(this, WID_GSC_SETTINGS); } - void OnRealtimeTick(uint delta_ms) override - { - if (this->timeout.Elapsed(delta_ms)) { - this->clicked_button = -1; - this->SetDirty(); - } - } + /** When reset, unclick the button after a small timeout. */ + TimeoutTimer unclick_timeout = {std::chrono::milliseconds(150), [this]() { + this->clicked_button = -1; + this->SetDirty(); + }}; /** * Some data on this window has become invalid. diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index edc9b88d05..5ac49097bf 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -20,6 +20,8 @@ #include "gfx_func.h" #include "core/geometry_func.hpp" #include "currency.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "zoom_func.h" #include "widgets/graph_widget.h" @@ -892,7 +894,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { this->vscroll->SetCount(static_cast(_sorted_standard_cargo_specs.size())); /* Initialise the dataset */ - this->OnHundredthTick(); + this->UpdatePaymentRates(); this->FinishInitNested(window_number); } @@ -1030,10 +1032,18 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - this->OnHundredthTick(); + this->UpdatePaymentRates(); } - void OnHundredthTick() override + /** Update the payment rates on a regular interval. */ + IntervalTimer update_payment_interval = {std::chrono::seconds(3), [this](auto) { + this->UpdatePaymentRates(); + }}; + + /** + * Update the payment rates according to the latest information. + */ + void UpdatePaymentRates() { this->UpdateExcludedData(); diff --git a/src/guitimer_func.h b/src/guitimer_func.h deleted file mode 100644 index f37bd5dbbc..0000000000 --- a/src/guitimer_func.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 guitimer_func.h GUI Timers. */ - -#ifndef GUITIMER_FUNC_H -#define GUITIMER_FUNC_H - -class GUITimer -{ -protected: - uint timer; - uint interval; - -public: - GUITimer() : timer(0), interval(0) { } - explicit GUITimer(uint interval) : timer(0), interval(interval) { } - - inline bool HasElapsed() const - { - return this->interval == 0; - } - - inline void SetInterval(uint interval) - { - this->timer = 0; - this->interval = interval; - } - - /** - * Count how many times the interval has elapsed. - * Use to ensure a specific amount of events happen within a timeframe, e.g. for animation. - * @param delta Time since last test. - * @return Number of times the interval has elapsed. - */ - inline uint CountElapsed(uint delta) - { - if (this->interval == 0) return 0; - uint count = delta / this->interval; - if (this->timer + (delta % this->interval) >= this->interval) count++; - this->timer = (this->timer + delta) % this->interval; - return count; - } - - /** - * Test if a timer has elapsed. - * Use to ensure an event happens only once within a timeframe, e.g. for window updates. - * @param delta Time since last test. - * @return True iff the timer has elapsed. - */ - inline bool Elapsed(uint delta) - { - if (this->CountElapsed(delta) == 0) return false; - this->SetInterval(0); - return true; - } -}; - -#endif /* GUITIMER_FUNC_H */ diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index b1aa3dc4e1..1773012568 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -42,6 +42,8 @@ #include "industry_cmd.h" #include "querystring_gui.h" #include "stringfilter_type.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "table/strings.h" @@ -723,8 +725,7 @@ public: if (success && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } - void OnHundredthTick() override - { + IntervalTimer update_interval = {std::chrono::seconds(3), [this](auto) { if (_game_mode == GM_EDITOR) return; if (this->count == 0) return; const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); @@ -739,7 +740,7 @@ public: this->SetDirty(); } } - } + }}; void OnTimeout() override { @@ -1820,11 +1821,11 @@ public: this->DrawWidgets(); } - void OnHundredthTick() override - { + /** Rebuild the industry list on a regular interval. */ + IntervalTimer rebuild_interval = {std::chrono::seconds(3), [this](auto) { this->industries.ForceResort(); this->BuildSortIndustriesList(); - } + }}; /** * Some data on this window has become invalid. diff --git a/src/main_gui.cpp b/src/main_gui.cpp index bdecd07ba5..fd6c0c1054 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -30,10 +30,11 @@ #include "linkgraph/linkgraph_gui.h" #include "tilehighlight_func.h" #include "hotkeys.h" -#include "guitimer_func.h" #include "error.h" #include "news_gui.h" #include "misc_cmd.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "saveload/saveload.h" @@ -209,12 +210,6 @@ enum { struct MainWindow : Window { - GUITimer refresh; - - /* Refresh times in milliseconds */ - static const uint LINKGRAPH_REFRESH_PERIOD = 7650; - static const uint LINKGRAPH_DELAY = 450; - MainWindow(WindowDesc *desc) : Window(desc) { this->InitNested(0); @@ -225,15 +220,12 @@ struct MainWindow : Window nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZOOM_LVL_VIEWPORT)); this->viewport->overlay = std::make_shared(this, WID_M_VIEWPORT, 0, 0, 2); - this->refresh.SetInterval(LINKGRAPH_DELAY); + this->refresh_timeout.Reset(); } - void OnRealtimeTick(uint delta_ms) override + /** Refresh the link-graph overlay. */ + void RefreshLinkGraph() { - if (!this->refresh.Elapsed(delta_ms)) return; - - this->refresh.SetInterval(LINKGRAPH_REFRESH_PERIOD); - if (this->viewport->overlay->GetCargoMask() == 0 || this->viewport->overlay->GetCompanyMask() == 0) { return; @@ -243,6 +235,22 @@ struct MainWindow : Window this->GetWidget(WID_M_VIEWPORT)->SetDirty(this); } + /** Refresh the link-graph overlay on a regular interval. */ + IntervalTimer refresh_interval = {std::chrono::milliseconds(7650), [this](auto) { + RefreshLinkGraph(); + }}; + + /** + * Sometimes when something happened, force an update to the link-graph a bit sooner. + * + * We don't do it instantly on those changes, as for example when you are scrolling, + * constantly refreshing the link-graph would be very slow. So we delay it a bit, + * and only draw it once the scrolling settles down. + */ + TimeoutTimer refresh_timeout = {std::chrono::milliseconds(450), [this]() { + RefreshLinkGraph(); + }}; + void OnPaint() override { this->DrawWidgets(); @@ -416,7 +424,7 @@ struct MainWindow : Window this->viewport->scrollpos_y += ScaleByZoom(delta.y, this->viewport->zoom); this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x; this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y; - this->refresh.SetInterval(LINKGRAPH_DELAY); + this->refresh_timeout.Reset(); } void OnMouseWheel(int wheel) override @@ -431,7 +439,7 @@ struct MainWindow : Window if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_M_VIEWPORT); nvp->UpdateViewportCoordinates(this); - this->refresh.SetInterval(LINKGRAPH_DELAY); + this->refresh_timeout.Reset(); } } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index f7567d0ed1..51541623fe 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -24,10 +24,11 @@ #include "core/geometry_func.hpp" #include "newgrf_debug.h" #include "zoom_func.h" -#include "guitimer_func.h" #include "viewport_func.h" #include "landscape_cmd.h" #include "rev.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/misc_widget.h" @@ -470,9 +471,6 @@ struct AboutWindow : public Window { int line_height; ///< The height of a single line static const int num_visible_lines = 19; ///< The number of lines visible simultaneously - static const uint TIMER_INTERVAL = 2100; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain parity: 2100 / FONT_HEIGHT_NORMAL = 150ms - GUITimer timer; - AboutWindow() : Window(&_about_desc) { this->InitNested(WN_GAME_OPTIONS_ABOUT); @@ -500,10 +498,6 @@ struct AboutWindow : public Window { d.width = std::max(d.width, GetStringBoundingBox(_credits[i]).width); } *size = maxdim(*size, d); - - /* Set scroll interval based on required speed. To keep scrolling smooth, - * the interval is adjusted rather than the distance moved. */ - this->timer.SetInterval(TIMER_INTERVAL / FONT_HEIGHT_NORMAL); } void DrawWidget(const Rect &r, int widget) const override @@ -521,18 +515,19 @@ struct AboutWindow : public Window { } } - void OnRealtimeTick(uint delta_ms) override - { - uint count = this->timer.CountElapsed(delta_ms); - if (count > 0) { - this->text_position -= count; - /* If the last text has scrolled start a new from the start */ - if (this->text_position < (int)(this->GetWidget(WID_A_SCROLLING_TEXT)->pos_y - lengthof(_credits) * this->line_height)) { - this->text_position = this->GetWidget(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget(WID_A_SCROLLING_TEXT)->current_y; - } - this->SetWidgetDirty(WID_A_SCROLLING_TEXT); + /** + * Scroll the text in the about window slow. + * + * The interval of 2100ms is chosen to maintain parity: 2100 / FONT_HEIGHT_NORMAL = 150ms. + */ + IntervalTimer scroll_interval = {std::chrono::milliseconds(2100) / FONT_HEIGHT_NORMAL, [this](uint count) { + this->text_position -= count; + /* If the last text has scrolled start a new from the start */ + if (this->text_position < (int)(this->GetWidget(WID_A_SCROLLING_TEXT)->pos_y - lengthof(_credits) * this->line_height)) { + this->text_position = this->GetWidget(WID_A_SCROLLING_TEXT)->pos_y + this->GetWidget(WID_A_SCROLLING_TEXT)->current_y; } - } + this->SetWidgetDirty(WID_A_SCROLLING_TEXT); + }}; }; void ShowAboutWindow() diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index ffea399e29..2ed59e9a52 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -18,6 +18,8 @@ #include "../toolbar_gui.h" #include "../core/geometry_func.hpp" #include "../zoom_func.h" +#include "../timer/timer.h" +#include "../timer/timer_window.h" #include "network.h" #include "network_client.h" #include "network_base.h" @@ -170,9 +172,8 @@ void NetworkUndrawChatMessage() } } -/** Check if a message is expired. */ -void NetworkChatMessageLoop() -{ +/** Check if a message is expired on a regular interval. */ +static IntervalTimer network_message_expired_interval(std::chrono::seconds(1), [](auto) { auto now = std::chrono::steady_clock::now(); for (auto &cmsg : _chatmsg_list) { /* Message has expired, remove from the list */ @@ -182,7 +183,7 @@ void NetworkChatMessageLoop() break; } } -} +}); /** Draw the chat message-box */ void NetworkDrawChatMessage() diff --git a/src/network/network_func.h b/src/network/network_func.h index 63d3d0cdc0..618adc1949 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -89,7 +89,6 @@ void NetworkInitChatMessage(); void NetworkReInitChatBoxSize(); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message); void NetworkUndrawChatMessage(); -void NetworkChatMessageLoop(); void NetworkAfterNewGRFScan(); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index cf79efea32..c2a0b8027f 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -32,11 +32,12 @@ #include "../core/geometry_func.hpp" #include "../genworld.h" #include "../map_type.h" -#include "../guitimer_func.h" #include "../zoom_func.h" #include "../sprite.h" #include "../settings_internal.h" #include "../company_cmd.h" +#include "../timer/timer.h" +#include "../timer/timer_window.h" #include "../widgets/network_widget.h" @@ -55,8 +56,6 @@ static void ShowNetworkStartServerWindow(); -static const int NETWORK_LIST_REFRESH_DELAY = 30; ///< Time, in seconds, between updates of the network list. - static ClientID _admin_client_id = INVALID_CLIENT_ID; ///< For what client a confirmation window is open. static CompanyID _admin_company_id = INVALID_COMPANY; ///< For what company a confirmation window is open. @@ -229,7 +228,6 @@ protected: Scrollbar *vscroll; ///< Vertical scrollbar of the list of servers. QueryString name_editbox; ///< Client name editbox. QueryString filter_editbox; ///< Editbox for filter on servers. - GUITimer requery_timer; ///< Timer for network requery. bool searched_internet = false; ///< Did we ever press "Search Internet" button? int lock_offset; ///< Left offset for lock icon. @@ -499,8 +497,6 @@ public: this->last_joined = NetworkAddServer(_settings_client.network.last_joined, false); this->server = this->last_joined; - this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000); - this->servers.SetListing(this->last_sorting); this->servers.SetSortFuncs(this->sorter_funcs); this->servers.SetFilterFuncs(this->filter_funcs); @@ -891,14 +887,12 @@ public: this->vscroll->SetCapacityFromWidget(this, WID_NG_MATRIX); } - void OnRealtimeTick(uint delta_ms) override - { + /** Refresh the online servers on a regular interval. */ + IntervalTimer refresh_interval = {std::chrono::seconds(30), [this](uint count) { if (!this->searched_internet) return; - if (!this->requery_timer.Elapsed(delta_ms)) return; - this->requery_timer.SetInterval(NETWORK_LIST_REFRESH_DELAY * 1000); _network_coordinator_client.GetListing(); - } + }}; }; Listing NetworkGameWindow::last_sorting = {false, 5}; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 23f8816ec1..991c9f3e23 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -28,7 +28,8 @@ #include "textfile_gui.h" #include "tilehighlight_func.h" #include "fios.h" -#include "guitimer_func.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/newgrf_widget.h" #include "widgets/misc_widget.h" @@ -155,7 +156,6 @@ struct NewGRFParametersWindow : public Window { bool clicked_increase; ///< True if the increase button was clicked, false for the decrease button. bool clicked_dropdown; ///< Whether the dropdown is open. bool closing_dropdown; ///< True, if the dropdown list is currently closing. - GUITimer timeout; ///< How long before we unpress the last-pressed button? uint clicked_row; ///< The selected parameter int line_height; ///< Height of a row in the matrix widget. Scrollbar *vscroll; @@ -404,7 +404,7 @@ struct NewGRFParametersWindow : public Window { par_info->SetValue(this->grf_config, val); this->clicked_button = num; - this->timeout.SetInterval(150); + this->unclick_timeout.Reset(); } } else if (par_info->type == PTYPE_UINT_ENUM && !par_info->complete_labels && click_count >= 2) { /* Display a query box so users can enter a custom value. */ @@ -484,13 +484,11 @@ struct NewGRFParametersWindow : public Window { } } - void OnRealtimeTick(uint delta_ms) override - { - if (timeout.Elapsed(delta_ms)) { - this->clicked_button = UINT_MAX; - this->SetDirty(); - } - } + /** When reset, unclick the button after a small timeout. */ + TimeoutTimer unclick_timeout = {std::chrono::milliseconds(150), [this]() { + this->clicked_button = UINT_MAX; + this->SetDirty(); + }}; }; GRFParameterInfo NewGRFParametersWindow::dummy_parameter_info(0); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index ab3bfadb92..841c0db352 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -32,10 +32,11 @@ #include "command_func.h" #include "company_base.h" #include "settings_internal.h" -#include "guitimer_func.h" #include "group_gui.h" #include "zoom_func.h" #include "news_cmd.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/news_widget.h" @@ -267,9 +268,6 @@ struct NewsWindow : Window { const NewsItem *ni; ///< News item to display. static int duration; ///< Remaining time for showing the current news message (may only be access while a news item is displayed). - static const uint TIMER_INTERVAL = 210; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain the 15ms at normal zoom. - GUITimer timer; - NewsWindow(WindowDesc *desc, const NewsItem *ni) : Window(desc), ni(ni) { NewsWindow::duration = 16650; @@ -322,11 +320,6 @@ struct NewsWindow : Window { PositionNewsMessage(this); } - void OnInit() override - { - this->timer.SetInterval(TIMER_INTERVAL / FONT_HEIGHT_NORMAL); - } - void DrawNewsBorder(const Rect &r) const { Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); @@ -554,18 +547,21 @@ struct NewsWindow : Window { void OnRealtimeTick(uint delta_ms) override { - int count = this->timer.CountElapsed(delta_ms); - if (count > 0) { - /* Scroll up newsmessages from the bottom */ - int newtop = std::max(this->top - 2 * count, _screen.height - this->height - this->status_height - this->chat_height); - this->SetWindowTop(newtop); - } - /* Decrement the news timer. We don't need to action an elapsed event here, * so no need to use TimerElapsed(). */ if (NewsWindow::duration > 0) NewsWindow::duration -= delta_ms; } + /** + * Scroll the news message slowly up from the bottom. + * + * The interval of 210ms is chosen to maintain 15ms at normal zoom: 210 / FONT_HEIGHT_NORMAL = 15ms. + */ + IntervalTimer scroll_interval = {std::chrono::milliseconds(210) / FONT_HEIGHT_NORMAL, [this](uint count) { + int newtop = std::max(this->top - 2 * static_cast(count), _screen.height - this->height - this->status_height - this->chat_height); + this->SetWindowTop(newtop); + }}; + private: /** * Moves the window to a new #top coordinate. Makes screen dirty where needed. diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index fd4017c48b..bee329596b 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -21,6 +21,8 @@ #include "../hotkeys.h" #include "../company_cmd.h" #include "../misc_cmd.h" +#include "../timer/timer.h" +#include "../timer/timer_window.h" #include "script_gui.h" #include "script_log.hpp" @@ -288,7 +290,6 @@ struct ScriptSettingsWindow : public Window { bool clicked_increase; ///< Whether we clicked the increase or decrease button. bool clicked_dropdown; ///< Whether the dropdown is open. bool closing_dropdown; ///< True, if the dropdown list is currently closing. - GUITimer timeout; ///< Timeout for unclicking the button. int clicked_row; ///< The clicked row of settings. int line_height; ///< Height of a row in the matrix widget. Scrollbar *vscroll; ///< Cache of the vertical scrollbar. @@ -304,8 +305,7 @@ struct ScriptSettingsWindow : public Window { slot(slot), clicked_button(-1), clicked_dropdown(false), - closing_dropdown(false), - timeout(0) + closing_dropdown(false) { this->script_config = GetConfig(slot); @@ -499,7 +499,7 @@ struct ScriptSettingsWindow : public Window { if (new_val != old_val) { this->script_config->SetSetting(config_item.name, new_val); this->clicked_button = num; - this->timeout.SetInterval(150); + this->unclick_timeout.Reset(); } } else if (!bool_item && !config_item.complete_labels) { /* Display a query box so users can enter a custom value. */ @@ -551,13 +551,11 @@ struct ScriptSettingsWindow : public Window { this->vscroll->SetCapacityFromWidget(this, WID_SCRS_BACKGROUND); } - void OnRealtimeTick(uint delta_ms) override - { - if (this->timeout.Elapsed(delta_ms)) { - this->clicked_button = -1; - this->SetDirty(); - } - } + /** When reset, unclick the button after a small timeout. */ + TimeoutTimer unclick_timeout = {std::chrono::milliseconds(150), [this]() { + this->clicked_button = -1; + this->SetDirty(); + }}; /** * Some data on this window has become invalid. diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 911e0c9363..a5c78a6645 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -27,6 +27,8 @@ #include "transparency.h" #include "gui.h" #include "signs_cmd.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/sign_widget.h" @@ -312,11 +314,11 @@ struct SignListWindow : Window, SignList { this->SortSignsList(); } - void OnHundredthTick() override - { + /** Resort the sign listing on a regular interval. */ + IntervalTimer rebuild_interval = {std::chrono::seconds(3), [this](auto) { this->BuildSortSignList(); this->SetDirty(); - } + }}; /** * Some data on this window has become invalid. diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 4e448a05c2..c98fee110a 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -22,7 +22,6 @@ #include "sound_func.h" #include "window_func.h" #include "company_base.h" -#include "guitimer_func.h" #include "zoom_func.h" #include "smallmap_gui.h" @@ -1072,7 +1071,7 @@ void SmallMapWindow::SetupWidgetData() this->GetWidget(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(plane); } -SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc), refresh(GUITimer(FORCE_REFRESH_PERIOD)) +SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : Window(desc) { _smallmap_industry_highlight = INVALID_INDUSTRYTYPE; this->overlay = new LinkGraphOverlay(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1); @@ -1416,7 +1415,6 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) } if (new_highlight != _smallmap_industry_highlight) { _smallmap_industry_highlight = new_highlight; - this->refresh.SetInterval(_smallmap_industry_highlight != INVALID_INDUSTRYTYPE ? BLINK_PERIOD : FORCE_REFRESH_PERIOD); _smallmap_industry_highlight_state = true; this->SetDirty(); } @@ -1588,11 +1586,9 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) } } -/* virtual */ void SmallMapWindow::OnRealtimeTick(uint delta_ms) +/** Update all the links on the map. */ +void SmallMapWindow::UpdateLinks() { - /* Update the window every now and then */ - if (!this->refresh.Elapsed(delta_ms)) return; - if (this->map_type == SMT_LINKSTATS) { CompanyMask company_mask = this->GetOverlayCompanyMask(); if (this->overlay->GetCompanyMask() != company_mask) { @@ -1601,9 +1597,25 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) this->overlay->SetDirty(); } } +} + +/** Blink the industries (if hover over an industry). */ +void SmallMapWindow::Blink() +{ + if (_smallmap_industry_highlight == INVALID_INDUSTRYTYPE) return; + _smallmap_industry_highlight_state = !_smallmap_industry_highlight_state; - this->refresh.SetInterval(_smallmap_industry_highlight != INVALID_INDUSTRYTYPE ? BLINK_PERIOD : FORCE_REFRESH_PERIOD); + this->UpdateLinks(); + this->SetDirty(); +} + +/** Force a full refresh of the map. */ +void SmallMapWindow::ForceRefresh() +{ + if (_smallmap_industry_highlight != INVALID_INDUSTRYTYPE) return; + + this->UpdateLinks(); this->SetDirty(); } diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 774a42a841..11a08b83a4 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -17,7 +17,8 @@ #include "blitter/factory.hpp" #include "linkgraph/linkgraph_gui.h" #include "widgets/smallmap_widget.h" -#include "guitimer_func.h" +#include "timer/timer.h" +#include "timer/timer_window.h" /* set up the cargos to be displayed in the smallmap's route legend */ void BuildLinkStatsLegend(); @@ -74,8 +75,6 @@ protected: static int map_height_limit; ///< Currently used/cached map height limit. static const uint INDUSTRY_MIN_NUMBER_OF_COLUMNS = 2; ///< Minimal number of columns in the #WID_SM_LEGEND widget for the #SMT_INDUSTRY legend. - static const uint FORCE_REFRESH_PERIOD = 930; ///< map is redrawn after that many milliseconds. - static const uint BLINK_PERIOD = 450; ///< highlight blinking interval in milliseconds. uint min_number_of_columns; ///< Minimal number of columns in legends. uint min_number_of_fixed_rows; ///< Minimal number of rows in the legends for the fixed layouts only (all except #SMT_INDUSTRY). @@ -87,7 +86,6 @@ protected: int32 subscroll; ///< Number of pixels (0..3) between the right end of the base tile and the pixel at the top-left corner of the smallmap display. int zoom; ///< Zoom level. Bigger number means more zoom-out (further away). - GUITimer refresh; ///< Refresh timer. LinkGraphOverlay *overlay; static void BreakIndustryChainLink(); @@ -156,6 +154,16 @@ protected: return Company::IsValidID(_local_company) ? 1U << _local_company : MAX_UVALUE(CompanyMask); } + /** Blink the industries (if selected) on a regular interval. */ + IntervalTimer blink_interval = {std::chrono::milliseconds(450), [this](auto) { + Blink(); + }}; + + /** Update the whole map on a regular interval. */ + IntervalTimer refresh_interval = {std::chrono::milliseconds(930), [this](auto) { + ForceRefresh(); + }}; + void RebuildColourIndexIfNecessary(); uint GetNumberRowsLegend(uint columns) const; void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0); @@ -178,6 +186,10 @@ protected: int GetPositionOnLegend(Point pt); + void UpdateLinks(); + void Blink(); + void ForceRefresh(); + public: friend class NWidgetSmallmapDisplay; @@ -196,7 +208,6 @@ public: void OnInvalidateData(int data = 0, bool gui_scope = true) override; bool OnRightClick(Point pt, int widget) override; void OnMouseWheel(int wheel) override; - void OnRealtimeTick(uint delta_ms) override; void OnScroll(Point delta) override; void OnMouseOver(Point pt, int widget) override; }; diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 69a71b75f7..021025ddaa 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -25,8 +25,9 @@ #include "statusbar_gui.h" #include "toolbar_gui.h" #include "core/geometry_func.hpp" -#include "guitimer_func.h" #include "zoom_func.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/statusbar_widget.h" @@ -78,19 +79,14 @@ static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left struct StatusBarWindow : Window { bool saving; int ticker_scroll; - GUITimer ticker_timer; - GUITimer reminder_timeout; static const int TICKER_STOP = 1640; ///< scrolling is finished when counter reaches this value - static const int REMINDER_START = 1350; ///< time in ms for reminder notification (red dot on the right) to stay - static const int REMINDER_STOP = 0; ///< reminder disappears when counter reaches this value static const int COUNTER_STEP = 2; ///< this is subtracted from active counters every tick + static constexpr auto REMINDER_START = std::chrono::milliseconds(1350); ///< time in ms for reminder notification (red dot on the right) to stay StatusBarWindow(WindowDesc *desc) : Window(desc) { this->ticker_scroll = TICKER_STOP; - this->ticker_timer.SetInterval(15); - this->reminder_timeout.SetInterval(REMINDER_STOP); this->InitNested(); CLRBITS(this->flags, WF_WHITE_BORDER); @@ -186,7 +182,7 @@ struct StatusBarWindow : Window { } } - if (!this->reminder_timeout.HasElapsed()) { + if (!this->reminder_timeout.HasFired()) { Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, tr.right - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height)); } @@ -207,10 +203,10 @@ struct StatusBarWindow : Window { case SBI_SAVELOAD_START: this->saving = true; break; case SBI_SAVELOAD_FINISH: this->saving = false; break; case SBI_SHOW_TICKER: this->ticker_scroll = 0; break; - case SBI_SHOW_REMINDER: this->reminder_timeout.SetInterval(REMINDER_START); break; + case SBI_SHOW_REMINDER: this->reminder_timeout.Reset(); break; case SBI_NEWS_DELETED: this->ticker_scroll = TICKER_STOP; // reset ticker ... - this->reminder_timeout.SetInterval(REMINDER_STOP); // ... and reminder + this->reminder_timeout.Abort(); // ... and reminder break; } } @@ -224,23 +220,19 @@ struct StatusBarWindow : Window { } } - void OnRealtimeTick(uint delta_ms) override - { + /** Move information on the ticker slowly from one side to the other. */ + IntervalTimer ticker_scroll_interval = {std::chrono::milliseconds(15), [this](uint count) { if (_pause_mode != PM_UNPAUSED) return; - if (this->ticker_scroll < TICKER_STOP) { // Scrolling text - uint count = this->ticker_timer.CountElapsed(delta_ms); - if (count > 0) { - this->ticker_scroll += count; - this->SetWidgetDirty(WID_S_MIDDLE); - } - } - - // Red blot to show there are new unread newsmessages - if (this->reminder_timeout.Elapsed(delta_ms)) { + if (this->ticker_scroll < TICKER_STOP) { + this->ticker_scroll += count; this->SetWidgetDirty(WID_S_MIDDLE); } - } + }}; + + TimeoutTimer reminder_timeout = {REMINDER_START, [this]() { + this->SetWidgetDirty(WID_S_MIDDLE); + }}; }; static const NWidgetPart _nested_main_status_widgets[] = { diff --git a/src/texteff.cpp b/src/texteff.cpp index 1c4722ae61..3235b8720d 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -14,7 +14,9 @@ #include "core/smallvec_type.hpp" #include "viewport_func.h" #include "settings_type.h" -#include "guitimer_func.h" +#include "command_type.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "safeguards.h" @@ -91,11 +93,9 @@ void RemoveTextEffect(TextEffectID te_id) _text_effects[te_id].Reset(); } -void MoveAllTextEffects(uint delta_ms) -{ - static GUITimer texteffecttimer = GUITimer(MILLISECONDS_PER_TICK); - uint count = texteffecttimer.CountElapsed(delta_ms); - if (count == 0) return; +/** Slowly move text effects upwards. */ +IntervalTimer move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) { + if (_pause_mode && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return; for (TextEffect &te : _text_effects) { if (te.string_id == INVALID_STRING_ID) continue; @@ -111,7 +111,7 @@ void MoveAllTextEffects(uint delta_ms) te.top -= count * ZOOM_LVL_BASE; te.MarkDirty(ZOOM_LVL_OUT_8X); } -} +}}; void InitTextEffects() { diff --git a/src/texteff.hpp b/src/texteff.hpp index 56b5933926..f684c3d955 100644 --- a/src/texteff.hpp +++ b/src/texteff.hpp @@ -26,7 +26,6 @@ enum TextEffectMode { typedef size_t TextEffectID; -void MoveAllTextEffects(uint delta_ms); TextEffectID AddTextEffect(StringID msg, int x, int y, uint8 duration, TextEffectMode mode); void InitTextEffects(); void DrawTextEffects(DrawPixelInfo *dpi); diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index b00a8154c2..157a09b59e 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -49,11 +49,12 @@ #include "story_base.h" #include "toolbar_gui.h" #include "framerate_type.h" -#include "guitimer_func.h" #include "screenshot_gui.h" #include "misc_cmd.h" #include "league_gui.h" #include "league_base.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/toolbar_widget.h" @@ -1992,8 +1993,6 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = { /** Main toolbar. */ struct MainToolbarWindow : Window { - GUITimer timer; - MainToolbarWindow(WindowDesc *desc) : Window(desc) { this->InitNested(0); @@ -2004,8 +2003,6 @@ struct MainToolbarWindow : Window { this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button PositionMainToolbar(this); DoZoomInOutWindow(ZOOM_NONE, this); - - this->timer.SetInterval(MILLISECONDS_PER_TICK); } void FindWindowPlacementAndResize(int def_width, int def_height) override @@ -2109,11 +2106,8 @@ struct MainToolbarWindow : Window { _last_started_action = CBF_NONE; } - void OnRealtimeTick(uint delta_ms) override - { - if (!this->timer.Elapsed(delta_ms)) return; - this->timer.SetInterval(MILLISECONDS_PER_TICK); - + /** Refresh the state of pause / game-speed on a regular interval.*/ + IntervalTimer refresh_interval = {std::chrono::milliseconds(30), [this](auto) { if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) { this->ToggleWidgetLoweredState(WID_TN_PAUSE); this->SetWidgetDirty(WID_TN_PAUSE); @@ -2123,7 +2117,7 @@ struct MainToolbarWindow : Window { this->ToggleWidgetLoweredState(WID_TN_FAST_FORWARD); this->SetWidgetDirty(WID_TN_FAST_FORWARD); } - } + }}; void OnTimeout() override { @@ -2353,8 +2347,6 @@ enum MainToolbarEditorHotkeys { }; struct ScenarioEditorToolbarWindow : Window { - GUITimer timer; - ScenarioEditorToolbarWindow(WindowDesc *desc) : Window(desc) { this->InitNested(0); @@ -2363,8 +2355,6 @@ struct ScenarioEditorToolbarWindow : Window { CLRBITS(this->flags, WF_WHITE_BORDER); PositionMainToolbar(this); DoZoomInOutWindow(ZOOM_NONE, this); - - this->timer.SetInterval(MILLISECONDS_PER_TICK); } void FindWindowPlacementAndResize(int def_width, int def_height) override @@ -2495,11 +2485,8 @@ struct ScenarioEditorToolbarWindow : Window { this->SetWidgetDirty(WID_TE_DATE_FORWARD); } - void OnRealtimeTick(uint delta_ms) override - { - if (!this->timer.Elapsed(delta_ms)) return; - this->timer.SetInterval(MILLISECONDS_PER_TICK); - + /** Refresh the state of pause / game-speed on a regular interval.*/ + IntervalTimer refresh_interval = {std::chrono::milliseconds(30), [this](auto) { if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) { this->ToggleWidgetLoweredState(WID_TE_PAUSE); this->SetDirty(); @@ -2509,7 +2496,7 @@ struct ScenarioEditorToolbarWindow : Window { this->ToggleWidgetLoweredState(WID_TE_FAST_FORWARD); this->SetDirty(); } - } + }}; /** * Some data on this window has become invalid. diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 9076b0b56d..c655fdb3a2 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -34,6 +34,8 @@ #include "widgets/dropdown_func.h" #include "town_kdtree.h" #include "town_cmd.h" +#include "timer/timer.h" +#include "timer/timer_window.h" #include "widgets/town_widget.h" @@ -307,10 +309,10 @@ public: } } - void OnHundredthTick() override - { + /** Redraw the whole window on a regular interval. */ + IntervalTimer redraw_interval = {std::chrono::seconds(3), [this](auto) { this->SetDirty(); - } + }}; void OnInvalidateData(int data = 0, bool gui_scope = true) override { @@ -966,11 +968,11 @@ public: this->DrawWidgets(); } - void OnHundredthTick() override - { + /** Redraw the whole window on a regular interval. */ + IntervalTimer rebuild_interval = {std::chrono::seconds(3), [this](auto) { this->BuildSortTownList(); this->SetDirty(); - } + }}; void OnResize() override { diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index d036f3f694..a217e8a850 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -12,8 +12,9 @@ #include "../string_func.h" #include "../strings_func.h" #include "../window_func.h" -#include "../guitimer_func.h" #include "../zoom_func.h" +#include "../timer/timer.h" +#include "../timer/timer_window.h" #include "dropdown_type.h" #include "dropdown_widget.h" @@ -126,7 +127,6 @@ struct DropdownWindow : Window { bool drag_mode; bool instant_close; ///< Close the window when the mouse button is raised. int scrolling; ///< If non-zero, auto-scroll the item list (one time). - GUITimer scrolling_timer; ///< Timer for auto-scroll of the item list. Point position; ///< Position of the topleft corner of the window. Scrollbar *vscroll; @@ -183,7 +183,6 @@ struct DropdownWindow : Window { this->click_delay = 0; this->drag_mode = true; this->instant_close = instant_close; - this->scrolling_timer = GUITimer(MILLISECONDS_PER_TICK); } void Close() override @@ -278,22 +277,19 @@ struct DropdownWindow : Window { } } - void OnRealtimeTick(uint delta_ms) override - { - if (!this->scrolling_timer.Elapsed(delta_ms)) return; - this->scrolling_timer.SetInterval(MILLISECONDS_PER_TICK); + /** Rate limit how fast scrolling happens. */ + IntervalTimer scroll_interval = {std::chrono::milliseconds(30), [this](auto) { + if (this->scrolling == 0) return; - if (this->scrolling != 0) { - int pos = this->vscroll->GetPosition(); + int pos = this->vscroll->GetPosition(); - this->vscroll->UpdatePosition(this->scrolling); - this->scrolling = 0; + this->vscroll->UpdatePosition(this->scrolling); + this->scrolling = 0; - if (pos != this->vscroll->GetPosition()) { - this->SetDirty(); - } + if (pos != this->vscroll->GetPosition()) { + this->SetDirty(); } - } + }}; void OnMouseLoop() override { diff --git a/src/window.cpp b/src/window.cpp index e7db416316..e8bbfbf5d6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -37,7 +37,6 @@ #include "video/video_driver.hpp" #include "framerate_type.h" #include "network/network_func.h" -#include "guitimer_func.h" #include "news_func.h" #include "timer/timer.h" #include "timer/timer_window.h" @@ -1888,14 +1887,9 @@ void ResetWindowSystem() static void DecreaseWindowCounters() { - static byte hundredth_tick_timeout = 100; - if (_scroller_click_timeout != 0) _scroller_click_timeout--; - if (hundredth_tick_timeout != 0) hundredth_tick_timeout--; for (Window *w : Window::Iterate()) { - if (!_network_dedicated && hundredth_tick_timeout == 0) w->OnHundredthTick(); - if (_scroller_click_timeout == 0) { /* Unclick scrollbar buttons if they are pressed. */ for (uint i = 0; i < w->nested_array_size; i++) { @@ -1927,8 +1921,6 @@ static void DecreaseWindowCounters() w->RaiseButtons(true); } } - - if (hundredth_tick_timeout == 0) hundredth_tick_timeout = 100; } static void HandlePlacePresize() @@ -3111,20 +3103,21 @@ static IntervalTimer white_border_interval(std::chrono::millisecond */ void UpdateWindows() { - static std::chrono::steady_clock::time_point last_time = std::chrono::steady_clock::now(); - uint delta_ms = std::chrono::duration_cast(std::chrono::steady_clock::now() - last_time).count(); + static auto last_time = std::chrono::steady_clock::now(); + auto now = std::chrono::steady_clock::now(); + auto delta_ms = std::chrono::duration_cast(now - last_time); - if (delta_ms == 0) return; + if (delta_ms.count() == 0) return; - last_time = std::chrono::steady_clock::now(); + last_time = now; PerformanceMeasurer framerate(PFE_DRAWING); PerformanceAccumulator::Reset(PFE_DRAWWORLD); ProcessPendingPerformanceMeasurements(); - TimerManager::Elapsed(std::chrono::milliseconds(delta_ms)); - CallWindowRealtimeTickEvent(delta_ms); + TimerManager::Elapsed(delta_ms); + CallWindowRealtimeTickEvent(delta_ms.count()); /* Process invalidations before anything else. */ for (Window *w : Window::Iterate()) { @@ -3132,8 +3125,6 @@ void UpdateWindows() w->ProcessHighlightedInvalidations(); } - if (!_pause_mode || _game_mode == GM_EDITOR || _settings_game.construction.command_pause_level > CMDPL_NO_CONSTRUCTION) MoveAllTextEffects(delta_ms); - /* Skip the actual drawing on dedicated servers without screen. * But still empty the invalidation queues above. */ if (_network_dedicated) return; diff --git a/src/window_gui.h b/src/window_gui.h index 00dfd9960a..c9825ab686 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -621,13 +621,6 @@ public: */ virtual void OnGameTick() {} - /** - * Called once every 100 (game) ticks, or once every 3s, whichever comes last. - * In normal game speed the frequency is 1 call every 100 ticks (can be more than 3s). - * In fast-forward the frequency is 1 call every ~3s (can be more than 100 ticks). - */ - virtual void OnHundredthTick() {} - /** * Called periodically. */ From 3ebc7ad16e4ad870fc3132173896254e3e90f302 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 13 Apr 2023 13:56:00 +0200 Subject: [PATCH 03/48] Codechange: migrate all game-time-related timers to the new framework --- src/airport_gui.cpp | 6 ++ src/cheat_gui.cpp | 6 ++ src/company_cmd.cpp | 6 +- src/currency.cpp | 6 +- src/currency.h | 1 - src/date.cpp | 108 ------------------------------ src/disaster_vehicle.cpp | 6 +- src/dock_gui.cpp | 6 ++ src/economy.cpp | 6 +- src/engine.cpp | 11 ++- src/highscore_gui.cpp | 14 ++++ src/industry_cmd.cpp | 10 +-- src/network/network_func.h | 3 - src/network/network_server.cpp | 20 ++++-- src/newgrf_profiling.cpp | 12 ++++ src/openttd.cpp | 18 +++++ src/rail_gui.cpp | 13 ++++ src/road_gui.cpp | 6 ++ src/station_cmd.cpp | 7 +- src/statusbar_gui.cpp | 5 ++ src/subsidy.cpp | 6 +- src/timer/timer_game_calendar.cpp | 11 +++ src/town_cmd.cpp | 11 +-- src/town_gui.cpp | 6 ++ src/vehicle.cpp | 7 +- 25 files changed, 166 insertions(+), 145 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index ca747ca262..30c8115cc6 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -31,6 +31,8 @@ #include "airport_cmd.h" #include "station_cmd.h" #include "zoom_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/airport_widget.h" @@ -581,6 +583,10 @@ public: { CheckRedrawStationCoverage(this); } + + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; }; static const NWidgetPart _nested_build_airport_widgets[] = { diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 34418c9840..a9b19c2f5a 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -30,6 +30,8 @@ #include "error.h" #include "misc_cmd.h" #include "core/geometry_func.hpp" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/cheat_widget.h" @@ -417,6 +419,10 @@ struct CheatWindow : Window { if (value != oldvalue) WriteValue(ce->variable, ce->type, (int64)value); this->SetDirty(); } + + IntervalTimer daily_interval = {{TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetDirty(); + }}; }; /** Window description of the cheats GUI. */ diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 3dcc2bd570..fab43052c2 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -36,6 +36,8 @@ #include "story_base.h" #include "widgets/statusbar_widget.h" #include "company_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -743,7 +745,7 @@ void OnTick_Companies() * A year has passed, update the economic data of all companies, and perhaps show the * financial overview window of the local company. */ -void CompaniesYearlyLoop() +static IntervalTimer _companies_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::COMPANY}, [](auto) { /* Copy statistics */ for (Company *c : Company::Iterate()) { @@ -761,7 +763,7 @@ void CompaniesYearlyLoop() if (_settings_client.sound.new_year) SndPlayFx(SND_00_GOOD_YEAR); } } -} +}); /** * Fill the CompanyNewsInformation struct with the required data. diff --git a/src/currency.cpp b/src/currency.cpp index 841f00d56a..ca75f3d656 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -15,6 +15,8 @@ #include "settings_type.h" #include "date_func.h" #include "string_type.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -138,7 +140,7 @@ uint64 GetMaskOfAllowedCurrencies() /** * Verify if the currency chosen by the user is about to be converted to Euro */ -void CheckSwitchToEuro() +static IntervalTimer _check_switch_to_euro({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) { if (_currency_specs[_settings_game.locale.currency].to_euro != CF_NOEURO && _currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO && @@ -146,7 +148,7 @@ void CheckSwitchToEuro() _settings_game.locale.currency = 2; // this is the index of euro above. AddNewsItem(STR_NEWS_EURO_INTRODUCTION, NT_ECONOMY, NF_NORMAL); } -} +}); /** * Will fill _currency_specs array with diff --git a/src/currency.h b/src/currency.h index 10caa59d3a..1825ababe0 100644 --- a/src/currency.h +++ b/src/currency.h @@ -102,7 +102,6 @@ extern CurrencySpec _currency_specs[CURRENCY_END]; #define _currency ((const CurrencySpec*)&_currency_specs[GetGameSettings().locale.currency]) uint64 GetMaskOfAllowedCurrencies(); -void CheckSwitchToEuro(); void ResetCurrencies(bool preserve_custom = true); StringID *BuildCurrencyDropdown(); byte GetNewgrfCurrencyIdConverted(byte grfcurr_id); diff --git a/src/date.cpp b/src/date.cpp index 9b51a4b01a..23bf5552ff 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -158,111 +158,3 @@ Date ConvertYMDToDate(Year year, Month month, Day day) return DAYS_TILL(year) + days; } - -/** Functions used by the IncreaseDate function */ - -extern void EnginesDailyLoop(); -extern void DisasterDailyLoop(); -extern void IndustryDailyLoop(); - -extern void CompaniesMonthlyLoop(); -extern void EnginesMonthlyLoop(); -extern void TownsMonthlyLoop(); -extern void IndustryMonthlyLoop(); -extern void StationMonthlyLoop(); -extern void SubsidyMonthlyLoop(); - -extern void CompaniesYearlyLoop(); -extern void VehiclesYearlyLoop(); -extern void TownsYearlyLoop(); - -extern void ShowEndGameChart(); - - -/** Available settings for autosave intervals. */ -static const Month _autosave_months[] = { - 0, ///< never - 1, ///< every month - 3, ///< every 3 months - 6, ///< every 6 months - 12, ///< every 12 months -}; - -/** - * Runs various procedures that have to be done yearly - */ -static IntervalTimer _on_new_year({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) -{ - CompaniesYearlyLoop(); - VehiclesYearlyLoop(); - TownsYearlyLoop(); - InvalidateWindowClassesData(WC_BUILD_STATION); - InvalidateWindowClassesData(WC_BUS_STATION); - InvalidateWindowClassesData(WC_TRUCK_STATION); - if (_network_server) NetworkServerYearlyLoop(); - - if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant(); - - /* check if we reached end of the game (end of ending year); 0 = never */ - if (_cur_year == _settings_game.game_creation.ending_year + 1 && _settings_game.game_creation.ending_year != 0) { - ShowEndGameChart(); - } - - /* check if we reached the maximum year, decrement dates by a year */ - if (_cur_year == MAX_YEAR + 1) { - int days_this_year; - - _cur_year--; - days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; - _date -= days_this_year; - for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); - for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); - - /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out - * all of them if the date is set back, else those messages will hang for ever */ - NetworkInitChatMessage(); - } - - if (_settings_client.gui.auto_euro) CheckSwitchToEuro(); -}); - -/** - * Runs various procedures that have to be done monthly - */ -static IntervalTimer _on_new_month({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto) -{ - if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) { - _do_autosave = true; - SetWindowDirty(WC_STATUS_BAR, 0); - } - - SetWindowClassesDirty(WC_CHEATS); - CompaniesMonthlyLoop(); - EnginesMonthlyLoop(); - TownsMonthlyLoop(); - IndustryMonthlyLoop(); - SubsidyMonthlyLoop(); - StationMonthlyLoop(); - if (_network_server) NetworkServerMonthlyLoop(); -}); - -/** - * Runs various procedures that have to be done daily - */ -static IntervalTimer _on_new_day({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) -{ - if (!_newgrf_profilers.empty() && _newgrf_profile_end_date <= _date) { - NewGRFProfiler::FinishAll(); - } - - if (_network_server) NetworkServerDailyLoop(); - - DisasterDailyLoop(); - IndustryDailyLoop(); - - SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_LEFT); - EnginesDailyLoop(); - - /* Refresh after possible snowline change */ - SetWindowClassesDirty(WC_TOWN_VIEW); -}); diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index e91e2fb842..528225cc1a 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -47,6 +47,8 @@ #include "core/random_func.hpp" #include "core/backup_type.hpp" #include "landscape_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -935,14 +937,14 @@ static void ResetDisasterDelay() _disaster_delay = GB(Random(), 0, 9) + 730; } -void DisasterDailyLoop() +static IntervalTimer _disaster_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::DISASTER}, [](auto) { if (--_disaster_delay != 0) return; ResetDisasterDelay(); if (_settings_game.difficulty.disasters != 0) DoDisaster(); -} +}); void StartupDisasters() { diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 2477450fa3..5b71a648cb 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -30,6 +30,8 @@ #include "station_cmd.h" #include "water_cmd.h" #include "waypoint_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/dock_widget.h" @@ -477,6 +479,10 @@ public: { CheckRedrawStationCoverage(this); } + + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; }; /** Nested widget parts of a build dock station window. */ diff --git a/src/economy.cpp b/src/economy.cpp index bf15a9f232..3b633d0fca 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -52,6 +52,8 @@ #include "company_cmd.h" #include "economy_cmd.h" #include "vehicle_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/pricebase.h" @@ -1983,7 +1985,7 @@ void LoadUnloadStation(Station *st) /** * Monthly update of the economic data (of the companies as well as economic fluctuations). */ -void CompaniesMonthlyLoop() +static IntervalTimer _companies_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto) { CompaniesGenStatistics(); if (_settings_game.economy.inflation) { @@ -1992,7 +1994,7 @@ void CompaniesMonthlyLoop() } CompaniesPayInterest(); HandleEconomyFluctuations(); -} +}); static void DoAcquireCompany(Company *c) { diff --git a/src/engine.cpp b/src/engine.cpp index c05bbc89e6..3ca54291cf 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -30,6 +30,8 @@ #include "articulated_vehicles.h" #include "error.h" #include "engine_base.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/engines.h" @@ -878,7 +880,7 @@ static bool IsVehicleTypeDisabled(VehicleType type, bool ai) } /** Daily check to offer an exclusive engine preview to the companies. */ -void EnginesDailyLoop() +static IntervalTimer _engines_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::ENGINE}, [](auto) { for (Company *c : Company::Iterate()) { c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, _date); @@ -915,7 +917,7 @@ void EnginesDailyLoop() } } } -} +}); /** * Clear the 'hidden' flag for all engines of a new company. @@ -1110,6 +1112,11 @@ void EnginesMonthlyLoop() } } +static IntervalTimer _engines_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::ENGINE}, [](auto) +{ + EnginesMonthlyLoop(); +}); + /** * Is \a name still free as name for an engine? * @param name New name of an engine. diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index f61bf46f37..8bc256067f 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -22,6 +22,9 @@ #include "hotkeys.h" #include "zoom_func.h" #include "misc_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" +#include "date_func.h" #include "widgets/highscore_widget.h" @@ -250,3 +253,14 @@ void ShowEndGameChart() CloseWindowByClass(WC_ENDSCREEN); new EndGameWindow(&_endgame_desc); } + +static IntervalTimer _check_end_game({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) +{ + /* 0 = never */ + if (_settings_game.game_creation.ending_year == 0) return; + + /* Show the end-game chart at the end of the ending year (hence the + 1). */ + if (_cur_year == _settings_game.game_creation.ending_year + 1) { + ShowEndGameChart(); + } +}); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 3facbb85d2..4afee2c4a8 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -44,6 +44,8 @@ #include "industry_cmd.h" #include "landscape_cmd.h" #include "terraform_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/industry_land.h" @@ -2947,7 +2949,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) * For small maps, it implies that less than one change per month is required, while on bigger maps, * it would be way more. The daily loop handles those changes. */ -void IndustryDailyLoop() +static IntervalTimer _industries_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::INDUSTRY}, [](auto) { _economy.industry_daily_change_counter += _economy.industry_daily_increment; @@ -2987,9 +2989,9 @@ void IndustryDailyLoop() /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); -} +}); -void IndustryMonthlyLoop() +static IntervalTimer _industries_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::INDUSTRY}, [](auto) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); @@ -3009,7 +3011,7 @@ void IndustryMonthlyLoop() /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); -} +}); void InitializeIndustries() diff --git a/src/network/network_func.h b/src/network/network_func.h index 618adc1949..73050737ea 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -65,9 +65,6 @@ void NetworkPrintClients(); void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode); /*** Commands ran by the server ***/ -void NetworkServerDailyLoop(); -void NetworkServerMonthlyLoop(); -void NetworkServerYearlyLoop(); void NetworkServerSendConfigUpdate(); void NetworkServerUpdateGameInfo(); void NetworkServerShowStatusToConsole(); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 3a61cab445..0d3a5aeaed 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -31,6 +31,8 @@ #include "../core/random_func.hpp" #include "../company_cmd.h" #include "../rev.h" +#include "../timer/timer.h" +#include "../timer/timer_game_calendar.h" #include #include @@ -1812,26 +1814,32 @@ void NetworkServer_Tick(bool send_frame) } /** Yearly "callback". Called whenever the year changes. */ -void NetworkServerYearlyLoop() +static IntervalTimer _network_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkCheckRestartMap(); NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY); -} +}); /** Monthly "callback". Called whenever the month changes. */ -void NetworkServerMonthlyLoop() +static IntervalTimer _network_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkAutoCleanCompanies(); NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY); if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY); -} +}); /** Daily "callback". Called whenever the date changes. */ -void NetworkServerDailyLoop() +static IntervalTimer _network_daily({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) { + if (!_network_server) return; + NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY); if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY); -} +}); /** * Get the IP address/hostname of the connected client. diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp index 7f93e1d765..451af9a18e 100644 --- a/src/newgrf_profiling.cpp +++ b/src/newgrf_profiling.cpp @@ -14,6 +14,8 @@ #include "console_func.h" #include "spritecache.h" #include "walltime_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include @@ -158,3 +160,13 @@ uint32 NewGRFProfiler::FinishAll() return total_microseconds; } + +/** + * Check whether profiling is active and should be finished. + */ +static IntervalTimer _check_profiling_finished({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](auto) +{ + if (_newgrf_profilers.empty() || _newgrf_profile_end_date > _date) return; + + NewGRFProfiler::FinishAll(); +}); diff --git a/src/openttd.cpp b/src/openttd.cpp index f719a4dcd5..d61a4145ee 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -101,6 +101,15 @@ bool _save_config = false; bool _request_newgrf_scan = false; NewGRFScanCallback *_request_newgrf_scan_callback = nullptr; +/** Available settings for autosave intervals. */ +static const Month _autosave_months[] = { + 0, ///< never + 1, ///< every month + 3, ///< every 3 months + 6, ///< every 6 months + 12, ///< every 12 months +}; + /** * Error handling for fatal user errors. * @param s the string to print. @@ -1432,6 +1441,15 @@ void StateGameLoop() assert(IsLocalCompany()); } +static IntervalTimer _autosave_interval({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::AUTOSAVE}, [](auto) +{ + if (_settings_client.gui.autosave == 0) return; + if ((_cur_month % _autosave_months[_settings_client.gui.autosave]) != 0) return; + + _do_autosave = true; + SetWindowDirty(WC_STATUS_BAR, 0); +}); + /** * Create an autosave. The default name is "autosave#.sav". However with * the setting 'keep_all_autosave' the name defaults to company-name + date diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 8532a04bd7..fa639344c7 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -40,6 +40,8 @@ #include "tunnelbridge_cmd.h" #include "waypoint_cmd.h" #include "rail_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "station_map.h" #include "tunnelbridge_map.h" @@ -1505,6 +1507,10 @@ public: CheckRedrawStationCoverage(this); } + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetDirty(); + }}; + static HotkeyList hotkeys; }; @@ -2201,6 +2207,13 @@ void ResetSignalVariant(int32 new_value) } } +static IntervalTimer _check_reset_signal({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [](auto) +{ + if (_cur_year != _settings_client.gui.semaphore_build_before) return; + + ResetSignalVariant(); +}); + /** * Resets the rail GUI - sets default railtype to build * and resets the signal GUI diff --git a/src/road_gui.cpp b/src/road_gui.cpp index ed5c0dc36f..a955fa27d7 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -39,6 +39,8 @@ #include "sortlist_type.h" #include "stringfilter_type.h" #include "string_func.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "widgets/road_widget.h" @@ -1586,6 +1588,10 @@ public: CheckRedrawStationCoverage(this); } + IntervalTimer yearly_interval = {{TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->InvalidateData(); + }}; + static HotkeyList hotkeys; }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8735687fba..430ae942ee 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -60,6 +60,8 @@ #include "landscape_cmd.h" #include "rail_cmd.h" #include "newgrf_roadstop.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -4007,7 +4009,7 @@ void OnTick_Station() } /** Monthly loop for stations. */ -void StationMonthlyLoop() +static IntervalTimer _stations_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::STATION}, [](auto) { for (Station *st : Station::Iterate()) { for (CargoID i = 0; i < NUM_CARGO; i++) { @@ -4016,8 +4018,7 @@ void StationMonthlyLoop() ClrBit(ge->status, GoodsEntry::GES_CURRENT_MONTH); } } -} - +}); void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius) { diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 021025ddaa..ef5d16c488 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -27,6 +27,7 @@ #include "core/geometry_func.hpp" #include "zoom_func.h" #include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_window.h" #include "widgets/statusbar_widget.h" @@ -233,6 +234,10 @@ struct StatusBarWindow : Window { TimeoutTimer reminder_timeout = {REMINDER_START, [this]() { this->SetWidgetDirty(WID_S_MIDDLE); }}; + + IntervalTimer daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) { + this->SetWidgetDirty(WID_S_LEFT); + }}; }; static const NWidgetPart _nested_main_status_widgets[] = { diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 6b56feead2..25832a19b4 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -25,6 +25,8 @@ #include "string_func.h" #include "tile_cmd.h" #include "subsidy_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -477,7 +479,7 @@ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) } /** Perform the monthly update of open subsidies, and try to create a new one. */ -void SubsidyMonthlyLoop() +static IntervalTimer _subsidies_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::SUBSIDY}, [](auto) { bool modified = false; @@ -547,7 +549,7 @@ void SubsidyMonthlyLoop() modified |= passenger_subsidy || town_subsidy || industry_subsidy; if (modified) InvalidateWindowData(WC_SUBSIDIES_LIST, 0); -} +}); /** * Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 6ab290eb13..6fe804ecc8 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -86,4 +86,15 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) timer->Elapsed(TimerGameCalendar::YEAR); } } + + /* check if we reached the maximum year, decrement dates by a year */ + if (_cur_year == MAX_YEAR + 1) { + int days_this_year; + + _cur_year--; + days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + _date -= days_this_year; + for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); + for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); + } } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 81732f3941..265f10aecb 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -52,6 +52,8 @@ #include "road_cmd.h" #include "terraform_cmd.h" #include "tunnelbridge_cmd.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" #include "table/town_land.h" @@ -3756,7 +3758,7 @@ CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType return CommandCost(); } -void TownsMonthlyLoop() +static IntervalTimer _towns_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::TOWN}, [](auto) { for (Town *t : Town::Iterate()) { if (t->road_build_months != 0) t->road_build_months--; @@ -3770,17 +3772,16 @@ void TownsMonthlyLoop() UpdateTownRating(t); UpdateTownUnwanted(t); } +}); -} - -void TownsYearlyLoop() +static IntervalTimer _towns_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::TOWN}, [](auto) { /* Increment house ages */ for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; IncrementHouseAge(t); } -} +}); static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { diff --git a/src/town_gui.cpp b/src/town_gui.cpp index c655fdb3a2..c9231288ae 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -35,6 +35,7 @@ #include "town_kdtree.h" #include "town_cmd.h" #include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_window.h" #include "widgets/town_widget.h" @@ -596,6 +597,11 @@ public: Command::Post(STR_ERROR_CAN_T_RENAME_TOWN, this->window_number, str); } + + IntervalTimer daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) { + /* Refresh after possible snowline change */ + this->SetDirty(); + }}; }; static const NWidgetPart _nested_town_game_view_widgets[] = { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index a979d4de3f..ea53dfacf3 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -56,6 +56,8 @@ #include "train_cmd.h" #include "vehicle_cmd.h" #include "newgrf_roadstop.h" +#include "timer/timer.h" +#include "timer/timer_game_calendar.h" #include "table/strings.h" @@ -2826,7 +2828,7 @@ void Vehicle::RemoveFromShared() this->previous_shared = nullptr; } -void VehiclesYearlyLoop() +static IntervalTimer _vehicles_yearly({TimerGameCalendar::YEAR, TimerGameCalendar::Priority::VEHICLE}, [](auto) { for (Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { @@ -2851,8 +2853,7 @@ void VehiclesYearlyLoop() SetWindowClassesDirty(WC_SHIPS_LIST); SetWindowClassesDirty(WC_ROADVEH_LIST); SetWindowClassesDirty(WC_AIRCRAFT_LIST); -} - +}); /** * Can this station be used by the given engine type? From 387d5eb74fb9af45ee93a0c46e6d173ecaa7bc76 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 13 Apr 2023 19:26:17 +0200 Subject: [PATCH 04/48] Codechange: validate the developer didn't schedule two timers on the same trigger/priority --- src/timer/timer_game_calendar.cpp | 17 +++++++++++++++++ src/timer/timer_game_calendar.h | 1 + src/timer/timer_manager.h | 19 +++++++++++++++++++ src/timer/timer_window.cpp | 7 +++++++ 4 files changed, 44 insertions(+) diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 6fe804ecc8..5d080b6237 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -98,3 +98,20 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); } } + +#ifdef WITH_ASSERT +template<> +void TimerManager::Validate(TimerGameCalendar::TPeriod period) +{ + if (period.priority == TimerGameCalendar::Priority::NONE) return; + + /* Validate we didn't make a developer error and scheduled more than one + * entry on the same priority/trigger. There can only be one timer on + * a specific trigger/priority, to ensure we are deterministic. */ + for (const auto &timer : TimerManager::GetTimers()) { + if (timer->period.trigger != period.trigger) continue; + + assert(timer->period.priority != period.priority); + } +} +#endif /* WITH_ASSERT */ diff --git a/src/timer/timer_game_calendar.h b/src/timer/timer_game_calendar.h index f7dd3dd499..76de11216b 100644 --- a/src/timer/timer_game_calendar.h +++ b/src/timer/timer_game_calendar.h @@ -26,6 +26,7 @@ * For example: * IntervalTimer({TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [](uint count){}); * + * @note Callbacks are executed in the game-thread. */ class TimerGameCalendar { public: diff --git a/src/timer/timer_manager.h b/src/timer/timer_manager.h index 2efe583ad9..8d1200abea 100644 --- a/src/timer/timer_manager.h +++ b/src/timer/timer_manager.h @@ -28,6 +28,7 @@ class BaseTimer; template class TimerManager { public: + using TPeriod = typename TTimerType::TPeriod; using TElapsed = typename TTimerType::TElapsed; /* Avoid copying this object; it is a singleton object. */ @@ -40,6 +41,9 @@ public: * @param timer The timer to register. */ static void RegisterTimer(BaseTimer &timer) { +#ifdef WITH_ASSERT + Validate(timer.period); +#endif /* WITH_ASSERT */ GetTimers().insert(&timer); } @@ -52,6 +56,21 @@ public: GetTimers().erase(&timer); } +#ifdef WITH_ASSERT + /** + * Validate that a new period is actually valid. + * + * For most timers this is not an issue, but some want to make sure their + * period is unique, to ensure deterministic game-play. + * + * This is meant purely to protect a developer from making a mistake. + * As such, assert() when validation fails. + * + * @param period The period to validate. + */ + static void Validate(TPeriod period); +#endif /* WITH_ASSERT */ + /** * Called when time for this timer elapsed. * diff --git a/src/timer/timer_window.cpp b/src/timer/timer_window.cpp index dff0b45b8a..f99d6372b3 100644 --- a/src/timer/timer_window.cpp +++ b/src/timer/timer_window.cpp @@ -58,3 +58,10 @@ void TimerManager::Elapsed(TimerWindow::TElapsed delta) timer->Elapsed(delta); } } + +#ifdef WITH_ASSERT +template<> +void TimerManager::Validate(TimerWindow::TPeriod period) +{ +} +#endif /* WITH_ASSERT */ From b19f42ecd92226bb7959c5f5bc1c9676fe8b980b Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sat, 15 Apr 2023 15:11:41 +0200 Subject: [PATCH 05/48] Codechange: Replace some p1/p2 parameter names with better names (#10658) --- src/cheat_gui.cpp | 60 +++++++++++++++++++++--------------------- src/settings_table.cpp | 4 +-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index a9b19c2f5a..be931e6c1a 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -52,30 +52,30 @@ static int32 _money_cheat_amount = 10000000; * Note that the amount of money of a company must be changed through a command * rather than by setting a variable. Since the cheat data structure expects a * variable, the amount of given/taken money is used for this purpose. - * @param p1 not used. - * @param p2 is -1 or +1 (down/up) + * @param new_value not used. + * @param change_direction is -1 or +1 (down/up) * @return Amount of money cheat. */ -static int32 ClickMoneyCheat(int32 p1, int32 p2) +static int32 ClickMoneyCheat(int32 new_value, int32 change_direction) { - Command::Post(Money(_money_cheat_amount) * p2); + Command::Post(Money(_money_cheat_amount) * change_direction); return _money_cheat_amount; } /** * Handle changing of company. - * @param p1 company to set to - * @param p2 is -1 or +1 (down/up) + * @param new_value company to set to + * @param change_direction is -1 or +1 (down/up) * @return The new company. */ -static int32 ClickChangeCompanyCheat(int32 p1, int32 p2) +static int32 ClickChangeCompanyCheat(int32 new_value, int32 change_direction) { - while ((uint)p1 < Company::GetPoolSize()) { - if (Company::IsValidID((CompanyID)p1)) { - SetLocalCompany((CompanyID)p1); + while ((uint)new_value < Company::GetPoolSize()) { + if (Company::IsValidID((CompanyID)new_value)) { + SetLocalCompany((CompanyID)new_value); return _local_company; } - p1 += p2; + new_value += change_direction; } return _local_company; @@ -83,13 +83,13 @@ static int32 ClickChangeCompanyCheat(int32 p1, int32 p2) /** * Allow (or disallow) changing production of all industries. - * @param p1 new value - * @param p2 unused + * @param new_value new value + * @param change_direction unused * @return New value allowing change of industry production. */ -static int32 ClickSetProdCheat(int32 p1, int32 p2) +static int32 ClickSetProdCheat(int32 new_value, int32 change_direction) { - _cheats.setup_prod.value = (p1 != 0); + _cheats.setup_prod.value = (new_value != 0); InvalidateWindowClassesData(WC_INDUSTRY_VIEW); return _cheats.setup_prod.value; } @@ -98,19 +98,19 @@ extern void EnginesMonthlyLoop(); /** * Handle changing of the current year. - * @param p1 Unused. - * @param p2 +1 (increase) or -1 (decrease). + * @param new_value Unused. + * @param change_direction +1 (increase) or -1 (decrease). * @return New year. */ -static int32 ClickChangeDateCheat(int32 p1, int32 p2) +static int32 ClickChangeDateCheat(int32 new_value, int32 change_direction) { YearMonthDay ymd; ConvertDateToYMD(_date, &ymd); - p1 = Clamp(p1, MIN_YEAR, MAX_YEAR); - if (p1 == _cur_year) return _cur_year; + new_value = Clamp(new_value, MIN_YEAR, MAX_YEAR); + if (new_value == _cur_year) return _cur_year; - Date new_date = ConvertYMDToDate(p1, ymd.month, ymd.day); + Date new_date = ConvertYMDToDate(new_value, ymd.month, ymd.day); for (auto v : Vehicle::Iterate()) v->ShiftDates(new_date - _date); LinkGraphSchedule::instance.ShiftDates(new_date - _date); SetDate(new_date, _date_fract); @@ -126,19 +126,19 @@ static int32 ClickChangeDateCheat(int32 p1, int32 p2) /** * Allow (or disallow) a change of the maximum allowed heightlevel. - * @param p1 new value - * @param p2 unused + * @param new_value new value + * @param change_direction unused * @return New value (or unchanged old value) of the maximum * allowed heightlevel value. */ -static int32 ClickChangeMaxHlCheat(int32 p1, int32 p2) +static int32 ClickChangeMaxHlCheat(int32 new_value, int32 change_direction) { - p1 = Clamp(p1, MIN_MAP_HEIGHT_LIMIT, MAX_MAP_HEIGHT_LIMIT); + new_value = Clamp(new_value, MIN_MAP_HEIGHT_LIMIT, MAX_MAP_HEIGHT_LIMIT); /* Check if at least one mountain on the map is higher than the new value. * If yes, disallow the change. */ for (TileIndex t = 0; t < Map::Size(); t++) { - if ((int32)TileHeight(t) > p1) { + if ((int32)TileHeight(t) > new_value) { ShowErrorMessage(STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN, INVALID_STRING_ID, WL_ERROR); /* Return old, unchanged value */ return _settings_game.construction.map_height_limit; @@ -146,7 +146,7 @@ static int32 ClickChangeMaxHlCheat(int32 p1, int32 p2) } /* Execute the change and reload GRF Data */ - _settings_game.construction.map_height_limit = p1; + _settings_game.construction.map_height_limit = new_value; ReloadNewGRFData(); /* The smallmap uses an index from heightlevels to colours. Trigger rebuilding it. */ @@ -171,10 +171,10 @@ enum CheatNumbers { /** * Signature of handler function when user clicks at a cheat. - * @param p1 The new value. - * @param p2 Change direction (+1, +1), \c 0 for boolean settings. + * @param new_value The new value. + * @param change_direction Change direction (+1, +1), \c 0 for boolean settings. */ -typedef int32 CheckButtonClick(int32 p1, int32 p2); +typedef int32 CheckButtonClick(int32 new_value, int32 change_direction); /** Information of a cheat. */ struct CheatEntry { diff --git a/src/settings_table.cpp b/src/settings_table.cpp index c1d335f6f4..72c2128810 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -96,7 +96,7 @@ static void v_PositionStatusbar(int32 new_value) /** * Redraw the smallmap after a colour scheme change. - * @param p1 Callback parameter. + * @param new_value Callback parameter. */ static void RedrawSmallmap(int32 new_value) { @@ -112,7 +112,7 @@ static void UpdateLinkgraphColours(int32 new_value) MarkWholeScreenDirty(); } -static void StationSpreadChanged(int32 p1) +static void StationSpreadChanged(int32 new_value) { InvalidateWindowData(WC_SELECT_STATION, 0); InvalidateWindowData(WC_BUILD_STATION, 0); From b282664242758575e413b7680d66d54cf1b0d113 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Sat, 1 May 2021 21:06:17 +0100 Subject: [PATCH 06/48] Codechange: Replace all usages of alloca/AllocaM with more modern/less discouraged alternatives --- src/network/core/host.cpp | 1 + src/newgrf.cpp | 78 ++++++++++++++++++--------------- src/newgrf_sound.cpp | 4 +- src/os/windows/crashlog_win.cpp | 18 ++++---- src/os/windows/font_win32.cpp | 22 ++++++---- src/os/windows/win32.cpp | 24 +++++----- src/saveload/saveload.cpp | 13 +++--- src/screenshot.cpp | 5 ++- src/script/squirrel.cpp | 3 +- src/settings.cpp | 21 ++++----- src/spritecache.cpp | 3 +- src/station_cmd.cpp | 8 ++-- src/strgen/strgen_base.cpp | 10 ++--- src/tgp.cpp | 2 +- src/timetable_gui.cpp | 8 ++-- src/townname.cpp | 6 +-- src/video/win32_v.cpp | 28 +++++++----- src/waypoint_cmd.cpp | 3 +- 18 files changed, 135 insertions(+), 122 deletions(-) diff --git a/src/network/core/host.cpp b/src/network/core/host.cpp index b55f5f5ec8..6644e95297 100644 --- a/src/network/core/host.cpp +++ b/src/network/core/host.cpp @@ -9,6 +9,7 @@ #include "../../stdafx.h" #include "../../debug.h" +#include "../../core/alloc_func.hpp" #include "address.h" #include "../../safeguards.h" diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 108eef1c96..d295e6e8ae 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -865,13 +865,11 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS; dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags - uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1); - uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1); - MemSetT(max_sprite_offset, 0, num_building_sprites + 1); - MemSetT(max_palette_offset, 0, num_building_sprites + 1); + std::vector max_sprite_offset(num_building_sprites + 1, 0); + std::vector max_palette_offset(num_building_sprites + 1, 0); /* Groundsprite */ - TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset); + TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset.data(), max_palette_offset.data()); if (_cur.skip_sprites < 0) return true; if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) { @@ -886,7 +884,7 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us for (uint i = 0; i < num_building_sprites; i++) { DrawTileSeqStruct *seq = const_cast(&dts->seq[i]); - flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1); + flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset.data() + i + 1, max_palette_offset.data() + i + 1); if (_cur.skip_sprites < 0) return true; if (flags & ~valid_flags) { @@ -5620,7 +5618,7 @@ static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount) } } - EngineID *engines = AllocaM(EngineID, idcount); + std::vector engines; for (uint i = 0; i < idcount; i++) { Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte()); if (e == nullptr) { @@ -5631,7 +5629,7 @@ static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount) return; } - engines[i] = e->index; + engines.push_back(e->index); if (!wagover) last_engines[i] = engines[i]; } @@ -5679,9 +5677,10 @@ static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount) static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount) { - CanalFeature *cfs = AllocaM(CanalFeature, idcount); + std::vector cfs; + cfs.reserve(idcount); for (uint i = 0; i < idcount; i++) { - cfs[i] = (CanalFeature)buf->ReadByte(); + cfs.push_back((CanalFeature)buf->ReadByte()); } uint8 cidcount = buf->ReadByte(); @@ -5711,9 +5710,10 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *stations = AllocaM(uint8, idcount); + std::vector stations; + stations.reserve(idcount); for (uint i = 0; i < idcount; i++) { - stations[i] = buf->ReadByte(); + stations.push_back(buf->ReadByte()); } uint8 cidcount = buf->ReadByte(); @@ -5768,9 +5768,10 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *houses = AllocaM(uint8, idcount); + std::vector houses; + houses.reserve(idcount); for (uint i = 0; i < idcount; i++) { - houses[i] = buf->ReadByte(); + houses.push_back(buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -5799,9 +5800,10 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *industries = AllocaM(uint8, idcount); + std::vector industries; + industries.reserve(idcount); for (uint i = 0; i < idcount; i++) { - industries[i] = buf->ReadByte(); + industries.push_back(buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -5830,9 +5832,10 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *indtiles = AllocaM(uint8, idcount); + std::vector indtiles; + indtiles.reserve(idcount); for (uint i = 0; i < idcount; i++) { - indtiles[i] = buf->ReadByte(); + indtiles.push_back(buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -5856,9 +5859,10 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount) { - CargoID *cargoes = AllocaM(CargoID, idcount); + std::vector cargoes; + cargoes.reserve(idcount); for (uint i = 0; i < idcount; i++) { - cargoes[i] = buf->ReadByte(); + cargoes.push_back((CargoID)buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -5889,9 +5893,10 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *objects = AllocaM(uint8, idcount); + std::vector objects; + objects.reserve(idcount); for (uint i = 0; i < idcount; i++) { - objects[i] = buf->ReadByte(); + objects.push_back(buf->ReadByte()); } uint8 cidcount = buf->ReadByte(); @@ -5939,10 +5944,11 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount) { - uint8 *railtypes = AllocaM(uint8, idcount); + std::vector railtypes; + railtypes.reserve(idcount); for (uint i = 0; i < idcount; i++) { uint8 id = buf->ReadByte(); - railtypes[i] = id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE; + railtypes.push_back(id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE); } uint8 cidcount = buf->ReadByte(); @@ -5972,10 +5978,11 @@ static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType { RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map; - uint8 *roadtypes = AllocaM(uint8, idcount); + std::vector roadtypes; + roadtypes.reserve(idcount); for (uint i = 0; i < idcount; i++) { uint8 id = buf->ReadByte(); - roadtypes[i] = id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE; + roadtypes.push_back(id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE); } uint8 cidcount = buf->ReadByte(); @@ -6008,9 +6015,10 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *airports = AllocaM(uint8, idcount); + std::vector airports; + airports.reserve(idcount); for (uint i = 0; i < idcount; i++) { - airports[i] = buf->ReadByte(); + airports.push_back(buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -6039,9 +6047,10 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *airptiles = AllocaM(uint8, idcount); + std::vector airptiles; + airptiles.reserve(idcount); for (uint i = 0; i < idcount; i++) { - airptiles[i] = buf->ReadByte(); + airptiles.push_back(buf->ReadByte()); } /* Skip the cargo type section, we only care about the default group */ @@ -6070,9 +6079,10 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) return; } - uint8 *roadstops = AllocaM(uint8, idcount); + std::vector roadstops; + roadstops.reserve(idcount); for (uint i = 0; i < idcount; i++) { - roadstops[i] = buf->ReadByte(); + roadstops.push_back(buf->ReadByte()); } uint8 cidcount = buf->ReadByte(); @@ -9830,10 +9840,8 @@ static void FinalisePriceBaseMultipliers() /* Evaluate grf overrides */ int num_grfs = (uint)_grf_files.size(); - int *grf_overrides = AllocaM(int, num_grfs); + std::vector grf_overrides(num_grfs, -1); for (int i = 0; i < num_grfs; i++) { - grf_overrides[i] = -1; - GRFFile *source = _grf_files[i]; uint32 override = _grf_id_overrides[source->grfid]; if (override == 0) continue; diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp index fce0ba9e11..f47f9f023b 100644 --- a/src/newgrf_sound.cpp +++ b/src/newgrf_sound.cpp @@ -81,8 +81,8 @@ bool LoadNewGRFSound(SoundEntry *sound) if (file.ReadByte() != 0xFF) return false; uint8 name_len = file.ReadByte(); - char *name = AllocaM(char, name_len + 1); - file.ReadBlock(name, name_len + 1); + std::string name(name_len + 1, '\0'); + file.ReadBlock(name.data(), name_len + 1); /* Test string termination */ if (name[name_len] != 0) { diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 9079267358..e5c5cd6b88 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -124,22 +124,20 @@ struct DebugFileInfo { SYSTEMTIME file_time; }; -static uint32 *_crc_table; +static uint32 _crc_table[256]; -static void MakeCRCTable(uint32 *table) +static void MakeCRCTable() { uint32 crc, poly = 0xEDB88320L; int i; int j; - _crc_table = table; - for (i = 0; i != 256; i++) { crc = i; for (j = 8; j != 0; j--) { crc = (crc & 1 ? (crc >> 1) ^ poly : crc >> 1); } - table[i] = crc; + _crc_table[i] = crc; } } @@ -206,7 +204,8 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) /* virtual */ char *CrashLogWindows::LogModules(char *output, const char *last) const { - MakeCRCTable(AllocaM(uint32, 256)); + MakeCRCTable(); + output += seprintf(output, last, "Module information:\n"); HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); @@ -426,7 +425,8 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c memcpy(&ctx, ep->ContextRecord, sizeof(ctx)); /* Allocate space for symbol info. */ - IMAGEHLP_SYMBOL64 *sym_info = (IMAGEHLP_SYMBOL64*)alloca(sizeof(IMAGEHLP_SYMBOL64) + MAX_SYMBOL_LEN - 1); + char sym_info_raw[sizeof(IMAGEHLP_SYMBOL64) + MAX_SYMBOL_LEN - 1]; + IMAGEHLP_SYMBOL64 *sym_info = (IMAGEHLP_SYMBOL64*)sym_info_raw; sym_info->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); sym_info->MaxNameLength = MAX_SYMBOL_LEN; @@ -698,7 +698,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA len += wcslen(convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))) + 2; len += wcslen(convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))) + 1; - wchar_t *text = AllocaM(wchar_t, len); + static wchar_t text[lengthof(_crash_desc) + 3 * MAX_PATH * 2 + 7]; int printed = _snwprintf(text, len, _crash_desc, convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf))); if (printed < 0 || (size_t)printed > len) { MessageBox(wnd, L"Catastrophic failure trying to display crash message. Could not perform text formatting.", L"OpenTTD", MB_ICONERROR); @@ -729,7 +729,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA if (CrashLogWindows::current->WriteSavegame(filename, lastof(filename))) { convert_to_fs(filename, filenamebuf, lengthof(filenamebuf)); size_t len = lengthof(_save_succeeded) + wcslen(filenamebuf) + 1; - wchar_t *text = AllocaM(wchar_t, len); + static wchar_t text[lengthof(_save_succeeded) + MAX_PATH * 2 + 1]; _snwprintf(text, len, _save_succeeded, filenamebuf); MessageBox(wnd, text, L"Save successful", MB_ICONINFORMATION); } else { diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index aa81a65466..d819088c20 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -71,7 +71,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) HKEY hKey; LONG ret; wchar_t vbuffer[MAX_PATH], dbuffer[256]; - wchar_t *pathbuf; const char *font_path; uint index; size_t path_len; @@ -122,12 +121,12 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) * contain multiple fonts inside this single file. GetFontData however * returns the whole file, so we need to check each font inside to get the * proper font. */ - path_len = wcslen(vbuffer) + wcslen(dbuffer) + 2; // '\' and terminating nul. - pathbuf = AllocaM(wchar_t, path_len); - _snwprintf(pathbuf, path_len, L"%s\\%s", vbuffer, dbuffer); + std::wstring pathbuf(vbuffer); + pathbuf += L"\\"; + pathbuf += dbuffer; /* Convert the path into something that FreeType understands. */ - font_path = GetShortPath(pathbuf); + font_path = GetShortPath(pathbuf.c_str()); index = 0; do { @@ -374,7 +373,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) HGDIOBJ old = SelectObject(this->dc, temp); UINT size = GetOutlineTextMetrics(this->dc, 0, nullptr); - LPOUTLINETEXTMETRIC otm = (LPOUTLINETEXTMETRIC)AllocaM(BYTE, size); + LPOUTLINETEXTMETRIC otm = (LPOUTLINETEXTMETRIC)new BYTE[size]; GetOutlineTextMetrics(this->dc, size, otm); /* Font height is minimum height plus the difference between the default @@ -383,6 +382,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) /* Clamp() is not used as scaled_height could be greater than MAX_FONT_SIZE, which is not permitted in Clamp(). */ pixels = std::min(std::max(std::min(otm->otmusMinimumPPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height), MAX_FONT_SIZE); + delete[] (BYTE*)otm; SelectObject(dc, old); DeleteObject(temp); } @@ -405,7 +405,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) /* Query the font metrics we needed. */ UINT otmSize = GetOutlineTextMetrics(this->dc, 0, nullptr); - POUTLINETEXTMETRIC otm = (POUTLINETEXTMETRIC)AllocaM(BYTE, otmSize); + POUTLINETEXTMETRIC otm = (POUTLINETEXTMETRIC)new BYTE[otmSize]; GetOutlineTextMetrics(this->dc, otmSize, otm); this->units_per_em = otm->otmEMSquare; @@ -418,6 +418,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) this->fontname = FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFaceName)); Debug(fontcache, 2, "Loaded font '{}' with size {}", this->fontname, pixels); + delete[] (BYTE*)otm; } /** @@ -449,7 +450,7 @@ void Win32FontCache::ClearFontCache() if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large"); /* Call GetGlyphOutline again with size to actually render the glyph. */ - byte *bmp = AllocaM(byte, size); + byte *bmp = new byte[size]; GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat); /* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */ @@ -498,6 +499,8 @@ void Win32FontCache::ClearFontCache() this->SetGlyphPtr(key, &new_glyph); + delete[] bmp; + return new_glyph.sprite; } @@ -589,10 +592,11 @@ void LoadWin32Font(FontSize fs) /* Try to query an array of LOGFONTs that describe the file. */ DWORD len = 0; if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) { - LOGFONT *buf = (LOGFONT *)AllocaM(byte, len); + LOGFONT *buf = (LOGFONT *)new byte[len]; if (GetFontResourceInfo(fontPath, &len, buf, 2)) { logfont = *buf; // Just use first entry. } + delete[] (byte *)buf; } } diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 6b612ac404..bb93c01ba0 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -544,10 +544,9 @@ std::string FS2OTTD(const std::wstring &name) int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length(); int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0, nullptr, nullptr); if (len <= 0) return std::string(); - char *utf8_buf = AllocaM(char, len + 1); - utf8_buf[len] = '\0'; - WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf, len, nullptr, nullptr); - return std::string(utf8_buf, static_cast(len)); + std::string utf8_buf(len, '\0'); // len includes terminating null + WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf.data(), len, nullptr, nullptr); + return utf8_buf; } /** @@ -562,10 +561,9 @@ std::wstring OTTD2FS(const std::string &name) int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length(); int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0); if (len <= 0) return std::wstring(); - wchar_t *system_buf = AllocaM(wchar_t, len + 1); - system_buf[len] = L'\0'; - MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf, len); - return std::wstring(system_buf, static_cast(len)); + std::wstring system_buf(len, L'\0'); // len includes terminating null + MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf.data(), len); + return system_buf; } @@ -669,13 +667,13 @@ int OTTDStringCompare(const char *s1, const char *s2) int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, nullptr, 0); if (len_s1 != 0 && len_s2 != 0) { - LPWSTR str_s1 = AllocaM(WCHAR, len_s1); - LPWSTR str_s2 = AllocaM(WCHAR, len_s2); + std::wstring str_s1(len_s1, L'\0'); // len includes terminating null + std::wstring str_s2(len_s2, L'\0'); - MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1, len_s1); - MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2, len_s2); + MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1.data(), len_s1); + MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2.data(), len_s2); - int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1, -1, str_s2, -1, nullptr, nullptr, 0); + int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1.c_str(), -1, str_s2.c_str(), -1, nullptr, nullptr, 0); if (result != 0) return result; } } diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 354ffc6f99..3681054f69 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1048,24 +1048,21 @@ static void SlStdString(void *ptr, VarType conv) return; } - char *buf = AllocaM(char, len + 1); - SlCopyBytes(buf, len); - buf[len] = '\0'; // properly terminate the string + str->resize(len + 1); + SlCopyBytes(str->data(), len); + (*str)[len] = '\0'; // properly terminate the string StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK; if ((conv & SLF_ALLOW_CONTROL) != 0) { settings = settings | SVS_ALLOW_CONTROL_CODE; if (IsSavegameVersionBefore(SLV_169)) { - str_fix_scc_encoded(buf, buf + len); + str_fix_scc_encoded(str->data(), str->data() + len); } } if ((conv & SLF_ALLOW_NEWLINE) != 0) { settings = settings | SVS_ALLOW_NEWLINE; } - StrMakeValidInPlace(buf, buf + len, settings); - - // Store sanitized string. - str->assign(buf); + *str = StrMakeValid(*str, settings); } case SLA_PTRS: break; diff --git a/src/screenshot.cpp b/src/screenshot.cpp index aed36ee7cb..569ec8fcb1 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -182,8 +182,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user uint maxlines = Clamp(65536 / (w * pixelformat / 8), 16, 128); // number of lines per iteration uint8 *buff = MallocT(maxlines * w * pixelformat / 8); // buffer which is rendered to - uint8 *line = AllocaM(uint8, bytewidth); // one line, stored to file - memset(line, 0, bytewidth); + uint8 *line = CallocT(bytewidth); // one line, stored to file /* Start at the bottom, since bitmaps are stored bottom up */ do { @@ -211,6 +210,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user } /* Write to file */ if (fwrite(line, bytewidth, 1, f) != 1) { + free(line); free(buff); fclose(f); return false; @@ -218,6 +218,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user } } while (h != 0); + free(line); free(buff); fclose(f); diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp index a57d364fb4..cd98739071 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.cpp @@ -491,10 +491,11 @@ bool Squirrel::CallBoolMethod(HSQOBJECT instance, const char *method_name, bool if (prepend_API_name) { size_t len = strlen(class_name) + strlen(engine->GetAPIName()) + 1; - char *class_name2 = (char *)alloca(len); + char *class_name2 = MallocT(len); seprintf(class_name2, class_name2 + len - 1, "%s%s", engine->GetAPIName(), class_name); sq_pushstring(vm, class_name2, -1); + free(class_name2); } else { sq_pushstring(vm, class_name, -1); } diff --git a/src/settings.cpp b/src/settings.cpp index fd8823b843..bab8e2d095 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1345,12 +1345,11 @@ StringList GetGRFPresetList() */ GRFConfig *LoadGRFPresetFromConfig(const char *config_name) { - size_t len = strlen(config_name) + 8; - char *section = (char*)alloca(len); - seprintf(section, section + len - 1, "preset-%s", config_name); + std::string section("preset-"); + section += config_name; ConfigIniFile ini(_config_file); - GRFConfig *config = GRFLoadConfig(ini, section, false); + GRFConfig *config = GRFLoadConfig(ini, section.c_str(), false); return config; } @@ -1363,12 +1362,11 @@ GRFConfig *LoadGRFPresetFromConfig(const char *config_name) */ void SaveGRFPresetToConfig(const char *config_name, GRFConfig *config) { - size_t len = strlen(config_name) + 8; - char *section = (char*)alloca(len); - seprintf(section, section + len - 1, "preset-%s", config_name); + std::string section("preset-"); + section += config_name; ConfigIniFile ini(_config_file); - GRFSaveConfig(ini, section, config); + GRFSaveConfig(ini, section.c_str(), config); ini.SaveToDisk(_config_file); } @@ -1378,12 +1376,11 @@ void SaveGRFPresetToConfig(const char *config_name, GRFConfig *config) */ void DeleteGRFPresetFromConfig(const char *config_name) { - size_t len = strlen(config_name) + 8; - char *section = (char*)alloca(len); - seprintf(section, section + len - 1, "preset-%s", config_name); + std::string section("preset-"); + section += config_name; ConfigIniFile ini(_config_file); - ini.RemoveGroup(section); + ini.RemoveGroup(section.c_str()); ini.SaveToDisk(_config_file); } diff --git a/src/spritecache.cpp b/src/spritecache.cpp index aee8661c4d..1474f13575 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -426,7 +426,7 @@ static void *ReadRecolourSprite(SpriteFile &file, uint num) byte *dest = (byte *)AllocSprite(std::max(RECOLOUR_SPRITE_SIZE, num)); if (file.NeedsPaletteRemap()) { - byte *dest_tmp = AllocaM(byte, std::max(RECOLOUR_SPRITE_SIZE, num)); + byte *dest_tmp = new byte[std::max(RECOLOUR_SPRITE_SIZE, num)]; /* Only a few recolour sprites are less than 257 bytes */ if (num < RECOLOUR_SPRITE_SIZE) memset(dest_tmp, 0, RECOLOUR_SPRITE_SIZE); @@ -436,6 +436,7 @@ static void *ReadRecolourSprite(SpriteFile &file, uint num) for (uint i = 1; i < RECOLOUR_SPRITE_SIZE; i++) { dest[i] = _palmap_w2d[dest_tmp[_palmap_d2w[i - 1] + 1]]; } + delete[] dest_tmp; } else { file.ReadBlock(dest, num); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 430ae942ee..ce5fb8cb1e 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1387,7 +1387,6 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp if (flags & DC_EXEC) { TileIndexDiff tile_delta; - byte *layout_ptr; byte numtracks_orig; Track track; @@ -1405,18 +1404,19 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); track = AxisToTrack(axis); - layout_ptr = AllocaM(byte, numtracks * plat_len); - GetStationLayout(layout_ptr, numtracks, plat_len, statspec); + std::vector layouts(numtracks * plat_len); + GetStationLayout(layouts.data(), numtracks, plat_len, statspec); numtracks_orig = numtracks; Company *c = Company::Get(st->owner); + size_t layout_idx = 0; TileIndex tile_track = tile_org; do { TileIndex tile = tile_track; int w = plat_len; do { - byte layout = *layout_ptr++; + byte layout = layouts[layout_idx++]; if (IsRailStationTile(tile) && HasStationReservation(tile)) { /* Check for trains having a reservation for this tile. */ Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index ccd043adfa..7d37c3b4e6 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -362,7 +362,7 @@ char *ParseWord(char **buf) /* Forward declaration */ static int TranslateArgumentIdx(int arg, int offset = 0); -static void EmitWordList(Buffer *buffer, const char * const *words, uint nw) +static void EmitWordList(Buffer *buffer, const std::vector &words, uint nw) { buffer->AppendByte(nw); for (uint i = 0; i < nw; i++) buffer->AppendByte((byte)strlen(words[i]) + 1); @@ -377,7 +377,7 @@ void EmitPlural(Buffer *buffer, char *buf, int value) int argidx = _cur_argidx; int offset = -1; int expected = _plural_forms[_lang.plural_form].plural_count; - const char **words = AllocaM(const char *, std::max(expected, MAX_PLURALS)); + std::vector words(std::max(expected, MAX_PLURALS), nullptr); int nw = 0; /* Parse out the number, if one exists. Otherwise default to prev arg. */ @@ -442,7 +442,7 @@ void EmitGender(Buffer *buffer, char *buf, int value) buffer->AppendUtf8(SCC_GENDER_INDEX); buffer->AppendByte(nw); } else { - const char *words[MAX_NUM_GENDERS]; + std::vector words(MAX_NUM_GENDERS, nullptr); /* This is a {G 0 foo bar two} command. * If no relative number exists, default to +0 */ @@ -947,11 +947,11 @@ void LanguageWriter::WriteLength(uint length) */ void LanguageWriter::WriteLang(const StringData &data) { - uint *in_use = AllocaM(uint, data.tabs); + std::vector in_use; for (size_t tab = 0; tab < data.tabs; tab++) { uint n = data.CountInUse((uint)tab); - in_use[tab] = n; + in_use.push_back(n); _lang.offsets[tab] = TO_LE16(n); for (uint j = 0; j != in_use[tab]; j++) { diff --git a/src/tgp.cpp b/src/tgp.cpp index 8608febfd5..863fb60327 100644 --- a/src/tgp.cpp +++ b/src/tgp.cpp @@ -580,7 +580,7 @@ static void HeightMapCurves(uint level) float factor = sqrt((float)_height_map.size_x / (float)_height_map.size_y); uint sx = Clamp((int)(((1 << level) * factor) + 0.5), 1, 128); uint sy = Clamp((int)(((1 << level) / factor) + 0.5), 1, 128); - byte *c = AllocaM(byte, static_cast(sx) * sy); + std::vector c(static_cast(sx) * sy); for (uint i = 0; i < sx * sy; i++) { c[i] = Random() % lengthof(curve_maps); diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index bb1efed006..4c6d371683 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -85,9 +85,9 @@ static bool CanDetermineTimeTaken(const Order *order, bool travelling) * @param table Fill in arrival and departures including intermediate orders * @param offset Add this value to result and all arrivals and departures */ -static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, TimetableArrivalDeparture *table, Ticks offset) +static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector &table, Ticks offset) { - assert(table != nullptr); + assert(!table.empty()); assert(v->GetNumOrders() >= 2); assert(start < v->GetNumOrders()); @@ -179,7 +179,7 @@ struct TimetableWindow : Window { * @param table the table to fill * @return if next arrival will be early */ - static bool BuildArrivalDepartureList(const Vehicle *v, TimetableArrivalDeparture *table) + static bool BuildArrivalDepartureList(const Vehicle *v, std::vector &table) { assert(HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)); @@ -429,7 +429,7 @@ struct TimetableWindow : Window { Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) break; - TimetableArrivalDeparture *arr_dep = AllocaM(TimetableArrivalDeparture, v->GetNumOrders()); + std::vector arr_dep(v->GetNumOrders()); const VehicleOrderID cur_order = v->cur_real_order_index % v->GetNumOrders(); VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID; diff --git a/src/townname.cpp b/src/townname.cpp index 86954b933c..fa4449df7f 100644 --- a/src/townname.cpp +++ b/src/townname.cpp @@ -1063,8 +1063,8 @@ char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 se const TownNameGeneratorParams *par = &_town_name_generators[lang]; if (last >= buf + par->min) return par->proc(buf, last, seed); - char *buffer = AllocaM(char, par->min + 1); - par->proc(buffer, buffer + par->min, seed); + std::string buffer(par->min + 1, '\0'); + par->proc(buffer.data(), buffer.data() + par->min, seed); - return strecpy(buf, buffer, last); + return strecpy(buf, buffer.c_str(), last); } diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 07743255c6..75bbdb2a74 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -328,9 +328,9 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) if (lParam & GCS_RESULTSTR) { /* Read result string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, nullptr, 0); // Length is always in bytes, even in UNICODE build. - wchar_t *str = (wchar_t *)_alloca(len + sizeof(wchar_t)); - len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len); - str[len / sizeof(wchar_t)] = '\0'; + std::wstring str(len + 1, L'\0'); + len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str.data(), len); + str[len / sizeof(wchar_t)] = L'\0'; /* Transmit text to windowing system. */ if (len > 0) { @@ -346,18 +346,18 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) if ((lParam & GCS_COMPSTR) && DrawIMECompositionString()) { /* Read composition string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, nullptr, 0); // Length is always in bytes, even in UNICODE build. - wchar_t *str = (wchar_t *)_alloca(len + sizeof(wchar_t)); - len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len); - str[len / sizeof(wchar_t)] = '\0'; + std::wstring str(len + 1, L'\0'); + len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str.data(), len); + str[len / sizeof(wchar_t)] = L'\0'; if (len > 0) { static char utf8_buf[1024]; - convert_from_fs(str, utf8_buf, lengthof(utf8_buf)); + convert_from_fs(str.c_str(), utf8_buf, lengthof(utf8_buf)); /* Convert caret position from bytes in the input string to a position in the UTF-8 encoded string. */ LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, nullptr, 0); const char *caret = utf8_buf; - for (const wchar_t *c = str; *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) { + for (const wchar_t *c = str.c_str(); *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) { /* Skip DBCS lead bytes or leading surrogates. */ if (Utf16IsLeadSurrogate(*c)) { c++; @@ -1056,8 +1056,7 @@ bool VideoDriver_Win32GDI::AllocateBackingStore(int w, int h, bool force) if (!force && w == _screen.width && h == _screen.height) return false; - BITMAPINFO *bi = (BITMAPINFO *)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256); - memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256); + BITMAPINFO *bi = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256](); bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi->bmiHeader.biWidth = this->width = w; @@ -1071,7 +1070,10 @@ bool VideoDriver_Win32GDI::AllocateBackingStore(int w, int h, bool force) HDC dc = GetDC(0); this->dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID **)&this->buffer_bits, nullptr, 0); - if (this->dib_sect == nullptr) usererror("CreateDIBSection failed"); + if (this->dib_sect == nullptr) { + delete[] bi; + usererror("CreateDIBSection failed"); + } ReleaseDC(0, dc); _screen.width = w; @@ -1079,6 +1081,7 @@ bool VideoDriver_Win32GDI::AllocateBackingStore(int w, int h, bool force) _screen.height = h; _screen.dst_ptr = this->GetVideoPointer(); + delete[] bi; return true; } @@ -1092,7 +1095,7 @@ void VideoDriver_Win32GDI::MakePalette() { CopyPalette(_local_palette, true); - LOGPALETTE *pal = (LOGPALETTE*)alloca(sizeof(LOGPALETTE) + (256 - 1) * sizeof(PALETTEENTRY)); + LOGPALETTE *pal = (LOGPALETTE *)new char[sizeof(LOGPALETTE) + (256 - 1) * sizeof(PALETTEENTRY)](); pal->palVersion = 0x300; pal->palNumEntries = 256; @@ -1105,6 +1108,7 @@ void VideoDriver_Win32GDI::MakePalette() } this->gdi_palette = CreatePalette(pal); + delete[] pal; if (this->gdi_palette == nullptr) usererror("CreatePalette failed!\n"); } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index b04a570d2b..9793d63681 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -264,7 +264,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis wp->UpdateVirtCoord(); const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index); - byte *layout_ptr = AllocaM(byte, count); + byte *layout_ptr = new byte[count]; if (spec == nullptr) { /* The layout must be 0 for the 'normal' waypoints by design. */ memset(layout_ptr, 0, count); @@ -291,6 +291,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis)); } DirtyCompanyInfrastructureWindows(wp->owner); + delete[] layout_ptr; } return cost; From 6fc28d649eed7a192b43669e7bd6458f118d7a6d Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Tue, 11 Apr 2023 08:40:50 +0100 Subject: [PATCH 07/48] Cleanup: Unused alloca definitions and includes --- src/animated_tile.cpp | 1 - src/core/alloc_func.hpp | 5 ----- src/core/smallvec_type.hpp | 1 - src/newgrf_storage.h | 1 + src/os/windows/crashlog_win.cpp | 1 - src/saveload/animated_tile_sl.cpp | 1 - src/saveload/strings_sl.cpp | 1 + src/script/api/script_cargo.cpp | 1 + src/script/squirrel_helper.hpp | 2 +- src/script/squirrel_std.cpp | 1 - src/stdafx.h | 10 ---------- src/strgen/strgen_base.cpp | 1 + src/stringfilter.cpp | 1 + 13 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/animated_tile.cpp b/src/animated_tile.cpp index 5329b2b506..e31d1b8e03 100644 --- a/src/animated_tile.cpp +++ b/src/animated_tile.cpp @@ -8,7 +8,6 @@ /** @file animated_tile.cpp Everything related to animated tiles. */ #include "stdafx.h" -#include "core/alloc_func.hpp" #include "core/smallvec_type.hpp" #include "tile_cmd.h" #include "viewport_func.h" diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp index e8436e28d7..dc3ed483eb 100644 --- a/src/core/alloc_func.hpp +++ b/src/core/alloc_func.hpp @@ -128,9 +128,4 @@ static inline T *ReallocT(T *t_ptr, size_t num_elements) return t_ptr; } -/** alloca() has to be called in the parent function, so define AllocaM() as a macro */ -#define AllocaM(T, num_elements) \ - (CheckAllocationConstraints(num_elements), \ - (T*)alloca((num_elements) * sizeof(T))) - #endif /* ALLOC_FUNC_HPP */ diff --git a/src/core/smallvec_type.hpp b/src/core/smallvec_type.hpp index 92fd938be5..087f217971 100644 --- a/src/core/smallvec_type.hpp +++ b/src/core/smallvec_type.hpp @@ -10,7 +10,6 @@ #ifndef SMALLVEC_TYPE_HPP #define SMALLVEC_TYPE_HPP -#include "alloc_func.hpp" #include "mem_func.hpp" #include diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index 819e8d9394..0c2f0e33a0 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -10,6 +10,7 @@ #ifndef NEWGRF_STORAGE_H #define NEWGRF_STORAGE_H +#include "core/alloc_func.hpp" #include "core/pool_type.hpp" #include "tile_type.h" diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index e5c5cd6b88..6479f60a99 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -10,7 +10,6 @@ #include "../../stdafx.h" #include "../../crashlog.h" #include "win32.h" -#include "../../core/alloc_func.hpp" #include "../../core/math_func.hpp" #include "../../string_func.h" #include "../../fileio_func.h" diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 282968f9b4..a36366125a 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -13,7 +13,6 @@ #include "compat/animated_tile_sl_compat.h" #include "../tile_type.h" -#include "../core/alloc_func.hpp" #include "../core/smallvec_type.hpp" #include "../safeguards.h" diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index 512a743d98..6e4d779687 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -8,6 +8,7 @@ /** @file strings_sl.cpp Code handling saving and loading of strings */ #include "../stdafx.h" +#include "../core/alloc_func.hpp" #include "../string_func.h" #include "../strings_func.h" #include "saveload_internal.h" diff --git a/src/script/api/script_cargo.cpp b/src/script/api/script_cargo.cpp index aad2425461..b0377a3e0e 100644 --- a/src/script/api/script_cargo.cpp +++ b/src/script/api/script_cargo.cpp @@ -10,6 +10,7 @@ #include "../../stdafx.h" #include "script_cargo.hpp" #include "../../economy_func.h" +#include "../../core/alloc_func.hpp" #include "../../core/bitmath_func.hpp" #include "../../strings_func.h" #include "../../settings_type.h" diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index 47c5eb62a0..02b584fe49 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -11,7 +11,7 @@ #define SQUIRREL_HELPER_HPP #include "squirrel.hpp" -#include "../core/smallvec_type.hpp" +#include "../core/alloc_func.hpp" #include "../economy_type.h" #include "../string_func.h" #include "../tile_type.h" diff --git a/src/script/squirrel_std.cpp b/src/script/squirrel_std.cpp index 82943e5268..e04ebf4cc9 100644 --- a/src/script/squirrel_std.cpp +++ b/src/script/squirrel_std.cpp @@ -12,7 +12,6 @@ #include #include "../debug.h" #include "squirrel_std.hpp" -#include "../core/alloc_func.hpp" #include "../core/math_func.hpp" #include "../string_func.h" diff --git a/src/stdafx.h b/src/stdafx.h index d7da1ad8fc..b636e2d7bf 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -118,10 +118,6 @@ # define strcasecmp stricmp #endif -#if defined(SUNOS) || defined(HPUX) || defined(__CYGWIN__) -# include -#endif - /* Stuff for GCC */ #if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) # define NORETURN __attribute__ ((noreturn)) @@ -172,10 +168,6 @@ # include #endif /* __WATCOMC__ */ -#if defined(__MINGW32__) -# include // alloca() -#endif - #if defined(_WIN32) # define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #endif @@ -199,7 +191,6 @@ # pragma warning(disable: 6011) // code analyzer: Dereferencing NULL pointer 'pfGetAddrInfo': Lines: 995, 996, 998, 999, 1001 # pragma warning(disable: 6326) // code analyzer: potential comparison of a constant with another constant # pragma warning(disable: 6031) // code analyzer: Return value ignored: 'ReadFile' -# pragma warning(disable: 6255) // code analyzer: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead # pragma warning(disable: 6246) // code analyzer: Local declaration of 'statspec' hides declaration of the same name in outer scope. For additional information, see previous declaration at ... # if (_MSC_VER == 1500) // Addresses item #13 on http://blogs.msdn.com/b/vcblog/archive/2008/08/11/tr1-fixes-in-vc9-sp1.aspx, for Visual Studio 2008 @@ -207,7 +198,6 @@ # include # endif -# include // alloca() # define NORETURN __declspec(noreturn) # if (_MSC_VER < 1900) # define inline __forceinline diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 7d37c3b4e6..84122fe4ba 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -8,6 +8,7 @@ /** @file strgen_base.cpp Tool to create computer readable (stand-alone) translation files. */ #include "../stdafx.h" +#include "../core/alloc_func.hpp" #include "../core/endian_func.hpp" #include "../string_func.h" #include "../table/control_codes.h" diff --git a/src/stringfilter.cpp b/src/stringfilter.cpp index 4765a880e1..28a12eab2c 100644 --- a/src/stringfilter.cpp +++ b/src/stringfilter.cpp @@ -8,6 +8,7 @@ /** @file stringfilter.cpp Searching and filtering using a stringterm. */ #include "stdafx.h" +#include "core/alloc_func.hpp" #include "string_func.h" #include "strings_func.h" #include "stringfilter_type.h" From 27b40da06a73771179147e919c5209078da58073 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 15 Apr 2023 18:39:48 +0000 Subject: [PATCH 08/48] Update: Translations from eints catalan: 14 changes by J0anJosep portuguese: 20 changes by azulcosta portuguese (brazilian): 15 changes by ericandradex --- src/lang/afrikaans.txt | 4 ---- src/lang/arabic_egypt.txt | 1 - src/lang/belarusian.txt | 4 ---- src/lang/brazilian_portuguese.txt | 28 ++++++++++++----------- src/lang/bulgarian.txt | 1 - src/lang/catalan.txt | 26 +++++++++++---------- src/lang/croatian.txt | 4 ---- src/lang/czech.txt | 4 ---- src/lang/danish.txt | 4 ---- src/lang/dutch.txt | 4 ---- src/lang/english_AU.txt | 4 ---- src/lang/english_US.txt | 4 ---- src/lang/estonian.txt | 4 ---- src/lang/finnish.txt | 4 ---- src/lang/french.txt | 4 ---- src/lang/frisian.txt | 1 - src/lang/gaelic.txt | 4 ---- src/lang/galician.txt | 4 ---- src/lang/german.txt | 4 ---- src/lang/greek.txt | 4 ---- src/lang/hebrew.txt | 4 ---- src/lang/hungarian.txt | 4 ---- src/lang/indonesian.txt | 4 ---- src/lang/irish.txt | 4 ---- src/lang/italian.txt | 4 ---- src/lang/japanese.txt | 4 ---- src/lang/korean.txt | 4 ---- src/lang/latin.txt | 4 ---- src/lang/latvian.txt | 4 ---- src/lang/lithuanian.txt | 4 ---- src/lang/luxembourgish.txt | 4 ---- src/lang/norwegian_bokmal.txt | 4 ---- src/lang/polish.txt | 4 ---- src/lang/portuguese.txt | 38 ++++++++++++++++--------------- src/lang/romanian.txt | 4 ---- src/lang/russian.txt | 4 ---- src/lang/serbian.txt | 4 ---- src/lang/simplified_chinese.txt | 4 ---- src/lang/slovak.txt | 4 ---- src/lang/slovenian.txt | 4 ---- src/lang/spanish.txt | 4 ---- src/lang/spanish_MX.txt | 4 ---- src/lang/swedish.txt | 4 ---- src/lang/thai.txt | 4 ---- src/lang/traditional_chinese.txt | 4 ---- src/lang/turkish.txt | 4 ---- src/lang/ukrainian.txt | 4 ---- src/lang/vietnamese.txt | 4 ---- src/lang/welsh.txt | 4 ---- 49 files changed, 49 insertions(+), 218 deletions(-) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index e3a3724527..5647bce944 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -1800,10 +1800,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Geen STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Aanvanklike stad grootte multiplier: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Normale stede groote relatief na normale dorpe aan die begin van speletjie -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Herreken die verspreingskaart elke {STRING}{NBSP}da{P 0:2 g e} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tyd tussen daaropvolgende herrekeninge van die verspreidingskaart. Elke herrekening is vir een komponent van die hele kaart, so net 'n gedeelte is dan op datum, nie die hele kaart nie. Hoe korter hierdie stelling is, hoe meer verwerkingskrag word benodig, hoe langer hierdie stelling is, hoe langer vat dit vir die vrag om op nuwe roetes te versprei. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Neem {STRING}{NBSP}da{P 0:2 g e} om verspreidingskaart te herreken -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tyd benodig vir die herrekening van elke komponent van die verspreidingskaart. Elke berekening kan vir hierdie aantal dae hardloop, as hierdie stelling te kort is en die berekening is nie klaar nie, dan kan die spel stop tot die berekening klaar gedoen is. Hoe meer tyd toegelaat word vir hierdie berekeninge, hoe langer vat dit vir die verspreidingskaart om te verander as roetes verander. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Verspreidingsmodel vir passasiers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simmetries" beteken dat ongeveer dieselfde hoeveelheid passasiers tussen twee stasies gestuur word. "asimmetries" beteken passasiers word na willekeur tussen twee stasies gestuur. "handmatig" beteken dat passasiers nie outomaties versprei word nie. diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 1311ab5fba..49f1bceda4 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -1645,7 +1645,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 في {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :مضاعف المدن المبدئي: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :الوقت بين عمليات إعادة الحساب المتتابعة للرسم البياني الرابط. تحسب كل عملية إعادة حساب الخطط لمكون واحد من الرسم البياني. هذا يعني أن القيمة X لهذا الإعداد لا تعني أنه سيتم تحديث الرسم البياني كل X أيام. إلا بعض المكونات. كلما قمت بتعيينه أقل، كلما زاد وقت الCPU لحسابها. كلما قمت بضبطها لفترة أطول ، كلما اسغرق الوقت حتى يتم بدأ توزيع البضائع على طرق جديدة. ###length 3 diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index c7e74707c0..a927ed9661 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -2119,10 +2119,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :нiводнае STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Першапачатковы множнік памеру населенага пункта: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Адносная колькасьць гарадоў у параўнаньні з мястэчкамі на пачатку гульні. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Абнаўляць ґраф размеркаваньня раз у {STRING}{NBSP}д{P 0:2 зень ні зён} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Перыяд пераразьліку ґрафаў размеркаваньня. У кожным цыкле разьлічваецца не ґраф цалкам, а толькі адзін зь яго кампанэнтаў. Чым менш гэта значэньне, тым больш будзе нагрузка на працэсар. Чым больш значэньне, тым больш часу пройдзе перад пачаткам разьліку ґрафаў для новых маршрутаў. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Пералічваць ґраф разьмеркаваньня раз у {STRING}{NBSP}д{P 0:2 зень ні зён} -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Час, адведзены для пераразьліку кампанэнтаў ґрафа. Разьлік запускаецца асобным патокам і працягваецца на працягу паказанай колькасьці гульнявых дзён. Калі значэньне будзе надта малым, то, магчыма, разьлік не пасьпее завяршыцца, і гульня будзе чакаць завяршэньня (гэта прывядзе да затрымак). Пры вялікіх значэньнях ґрафы размеркаваньня будуць павольней абнаўляцца пры зьменах маршрутаў. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Разьмеркаваньне пасажыраў: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :«Сымэтрычнае» азначае, што прыкладна аднолькавая колькасьць пасажыраў будзе накіроўвацца па прамым і зваротным маршрутам.{}«Несымэтрычнае» азначае, што пасажырапатокі ў любых кірунках не будуць залежаць адзін ад аднаго.{}«Уручную» — не выкарыстоўваць аўтаматычнае разьмеркаваньне для пасажыраў. diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 7af39b8b38..e16b9dfcbc 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -196,6 +196,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mp STR_UNITS_VELOCITY_METRIC :{COMMA}{NBSP}km/h STR_UNITS_VELOCITY_SI :{COMMA}{NBSP}m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}quadrados/dia +STR_UNITS_VELOCITY_KNOTS :{COMMA}{NBSP}nós STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv @@ -344,9 +345,9 @@ STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Abrir a ###length 31 STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pausar jogo STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Acelerar o jogo -STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opções -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Salvar jogo, abandonar jogo, sair -STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Exibir mapa, janela extra ou lista de placas +STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opções e definições +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Salvar, carregar ou abandonar o jogo, sair do jogo +STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Exibir mapa, janela de exibição extra, fluxo de carga ou lista de sinais STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Exibir lista de cidades STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Exibir subsídios STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Exibir lista de estações da empresa @@ -354,9 +355,9 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Exibir i STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Exibir informações gerais da empresa STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Exibe o livro de histórias STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Exibie a lista de objetivos -STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Exibir gráficos +STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Exibir gráficos da empresa e taxas de pagamento de carga STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Exibir tabela de classificação das empresas -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fundar construção de nova indústria or listar todas as indústrias +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Examina indústrias ou financia a construção de uma nova indústria STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Exibir lista de trens da empresa. Ctrl+Clique alterna a abertura da lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Exibir lista de veículos rodoviários da empresa. Ctrl+Clique alterna a abertura da lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Exibir lista de embarcações da empresa. Ctrl+Clique alterna a abertura da lista de grupos/veículos @@ -370,8 +371,8 @@ STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construi STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construir aeroportos STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Abrir a barra de paisagismo para elevar ou abaixar terreno, plantar árvores, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Exibir janela de som/música -STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Exibir a última mensagem/notícia, exibir opções de mensagem -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informações sobre o terreno, console, depurar scripts, capturas de tela, sobre OpenTTD +STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar a última mensagem/notícia, histórico de mensagens ou apagar todas as mensagens +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informações da área de terreno, captura de tela, sobre o OpenTTD e ferramentas de desenvolvedor STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Trocar a barra de ferramentas # Extra tooltips for the scenario editor toolbar @@ -1809,7 +1810,9 @@ STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Se ativado, per STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Idade mínima da companhia para trocar ações: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Defina a idade mínima de uma companhia para as outras estarem aptas a comprar e vender ações entre elas. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_VALUE :{COMMA} ano{P "" s} ###setting-zero-is-special +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_NO_MIN :Sem mínimo STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentagem paga em cada etapa em sistemas de baldeação: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentagem do lucro dado a cada estação de baldeação em sistemas de mais de um transporte, dando mais controle de lucro @@ -1924,10 +1927,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nenhum STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador do tamanho inicial da cidade: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamanho médio das cidades grandes em relação às cidades no início do jogo -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Atualizar gráfico de distribuição a cada {STRING}{NBSP}dia{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tempo tomado entre recálculos subsequentes de cada gráfico. Cada recálculo calcula os planos para cada componente do gráfico. Isso significa que um valor X para essa configuração não indica que o gráfico todo será atualizado a cada X dias. Apenas alguns componentes irão. Quanto mais curto você o definir, mais tempo de CPU será necessário para calculá-lo. Quanto mais longo, mais tempo levará até que a distribuição de carga começe em novas rotas. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Demore {STRING}{NBSP}dia{P 0:2 "" s} para recálculo do gráfico de distribuição -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo tomado para cada recálculo de um componente de um gráfico. Quando um recálculo começa, um processo é criado e é executado por esse número de dias. Quanto menos dias você define, maior a chance do processo não terminar quando era para ter terminado. Nesse caso, o jogo irá parar até ele terminar ("lag"). Quanto maior você definir isso, mais tempo leva para a distribuição ser atualizada quando as rotas mudarem. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribuição para passageiros: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que aproximadamente o mesmo número de passageiros irá de uma estação A para uma estação B como de B para A. "Assimétrico" significa que um número arbitrário de passageiros pode ir em qualquer direção. "Manual" significa que não haverá distribuição automática para os passageiros. @@ -1953,13 +1952,15 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Definir isso pa STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Saturação de caminhos curtos antes de usar caminhos de alta capacidade: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Frequentemente há múltiplos caminhos entre duas estações. Cargodist irá saturar o caminho mais curto primeiro, depois usar o segundo caminho mais curto até saturá-lo, e assim por diante. Saturação é determinada pela estimação da capacidade de do uso planejado. Ao saturar todos os caminhos, se ainda houver demanda, irá sobrecarregar todos os caminhos, com preferência aos de maior capacidade. No entanto, na maior parte do tempo o algorítimo não irá estimar a capacidade corretamente. Essa configuração permite você definir até que porcentagem um caminho mais curto deverá ser saturado na primeira passada antes do algorítimo proceder ao próxido. Defina-o para menos de 100% para evitar estações sobrecarregadas no caso de capacidade superestimada. -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unidade de velocidade: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unidades de velocidade (terrestre): {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :Unidades de velocidade (náutica): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Sempre que uma velocidade for exibida na interface do usuário, será exibida na unidade selecionada ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Imperial (mph) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :Métrico (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :SI (m/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :Unidades de jogo (quadr./dia) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :Nós STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Unidade de potência veicular: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Sempre que a potência de um veículo for exibida na interface de usuário, será exibida na unidade selecionada @@ -4586,6 +4587,7 @@ STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}As IAs q STR_AI_CONFIG_HUMAN_PLAYER :Jogador humano STR_AI_CONFIG_RANDOM_AI :IA aleatória STR_AI_CONFIG_NONE :{G=m}(nenhum) +STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Número máximo de concorrentes: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Subir @@ -4599,7 +4601,7 @@ STR_AI_CONFIG_AI :{G=f}{SILVER}IA STR_AI_CONFIG_CHANGE_AI :{BLACK}Selecionar IA STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selecionar Script do Jogo -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script. Ctrl+Clique para mostrar todas as versões disponíveis STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parâmetros do Script diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 76022dc347..d978e00f1a 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -1754,7 +1754,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Без STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Множител за големината на града: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Относителен размер на мегаполисите в сравнение с градовете в началото на играта -STR_CONFIG_SETTING_LINKGRAPH_TIME :Вземи {STRING}{NBSP}дни{P 0:2 "" s} за преизчисляване на графа за резпределение STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"симетрично" означава, че приблизително един и същ брой пътници ще пътуват от спирка А до спирка Б и обратно. "асиметрично" означава, че произволен брой пътници могат да пътуват във всяка от посоките. "ръчно" означава, че няма да има автоматично разпределение за пътниците. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Режим на разпределение на други класове товари: {STRING} diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 99f8f6e0d3..cb10d70d1d 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -196,6 +196,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mp STR_UNITS_VELOCITY_METRIC :{COMMA}{NBSP}km/h STR_UNITS_VELOCITY_SI :{COMMA}{NBSP}m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}cel·les/dia +STR_UNITS_VELOCITY_KNOTS :{COMMA}{NBSP}{P nus nusos} STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}cv STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv @@ -344,9 +345,9 @@ STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Obre la ###length 31 STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Posa en pausa o reprèn la partida STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Avança la partida el més ràpid possible -STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opcions -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Desa la partida, abandona-la o surt del programa -STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Mostra el mapa, finestres de visualització o llista de senyals, entre d'altres +STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opcions i configuració +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Desa o carrega una partida, abandona-la o surt del programa. +STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Mostra el mapa, vistes addicionals, la llista de senyals o el flux de càrrega. STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostra la llista de poblacions STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Mostra les subvencions STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Mostra la llista d'estacions de la companyia @@ -356,7 +357,7 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Mostra e STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Mostra la llista d'objectius STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Mostra gràfics de l'evolució de les companyies i les tarifes de transport. STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostra la taula de la lliga de companyies. -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finança la construcció d'una nova indústria +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Examina les indústries o finança la construcció d'una indústria nova. STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Mostra la llista de trens de la companyia. Ctrl+Clic commuta l'obertura de la llista de grups/vehicles. STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Mostra la llista de vehicles de la companyia. Ctrl+Clic commuta l'obertura de la llista de grups/vehicles. STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Mostra la llista de vaixells de la companyia. Ctrl+Clic canvia entre l'obertura de la llista de grups/vehicles. @@ -370,8 +371,8 @@ STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construe STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construeix aeroports STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Obre la barra d'eines del terreny per elevar/rebaixar el terreny, plantar arbres, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostra la finestra de so/música -STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostra els darrers missatges/notícies i l'historial disponible -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informació de terreny, consola, depuració de scripts, captures de pantalla, informació de l'OpenTTD... +STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostra els darrers missatges/notícies i l'historial disponible o esborra tots els missatges. +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informació de terreny, captures de pantalla i informació sobre l'OpenTTD i eines de desenvolupament. STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Commuta barres d'eines # Extra tooltips for the scenario editor toolbar @@ -1809,7 +1810,9 @@ STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Permet comprar STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Edat mínima de la companyia per negociar participacions: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Estableix l'edat mínima d'una companyia per tal que els altres competidors puguin comprar-ne o vendre accions. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_VALUE :{COMMA} any{P "" s} ###setting-zero-is-special +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_NO_MIN :Sense mínim STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentatge del benefici total a pagar en transferències: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentatge del benefici donat a branques intermediàries dins els sistemes, donant més control sobre els beneficis @@ -1924,10 +1927,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Cap STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador de mida inicial de ciutats: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :La grandària mitjana de les ciutats en relació als pobles a l'inici de la partida. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualitza el graf de distribució cada {STRING}{NBSP}di{P 0:2 a es} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Temps entre recàlculs successius del graf de distribució. Cada recàlcul calcula els plans per un component del graf. Això significa que un valor X per aquest paràmetre no implica que tot el graf serà actualitzat cada X dies. Només alguns components ho seran. Com més curt el valor, més temps de processador es requerirà per calcular-ho. Com més llarg, més temps passarà fins que la distribució de càrregues comenci en noves rutes. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Empra {STRING}{NBSP}di{P 0:2 a es} per al recàlcul del graf de distribució -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Temps dedicat a cada recàlcul d'un component del graf de connexions. Quan un recàlcul s'inicia, el programa crea un fil que pot executar-se durant aquest nombre de dies. Com més curt el valor, més probable que el fil no hagi acabat quan s'espera. Aleshores el programa s'atura fins que el fil acaba ("ralentització"). Com més llarg el valor, més temps requereix l'actualització de la distribució quan les rutes canvien. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Mode de distribució per passatgers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simètric" vol dir que aproximadament el mateix nombre de passatgers aniran des de l'estació A a la B que de B a A. "Asimètric" significa que un nombre arbitrari de passatgers poden anar en qualsevol dels dos sentits. "Manual" vol dir que no s'aplicarà una distribució automàtica pels passatgers. @@ -1953,13 +1952,15 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Indicant menys STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Saturació de camins curts abans d'usar camins d'alta capacitat: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Sovint hi ha diversos camins entre dues estacions donades. Cargodist primer saturarà el camí més curt, després usarà el segon camí més curt fins a saturar-lo i així successivament. La saturació és determinada per una estimació de la capacitat i l'ús previst. Un cop ha saturat tots els camins, si encara hi ha demanda, sobrecarregarà tots els camins, preferint aquells de major capacitat. No obstant, molt sovint l'algoritme no farà una estimació acurada de la capacitat. Aquest paràmetre us permet especificar fins a quin percentatge un camí més curt ha de ser saturat en la primera ronda abans d'escollir el següent en longitud. Indiqueu menys del 100% per evitar la superpoblació d'estacions en cas de capacitat sobreestimada. -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unitats de velocitat: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unitats de velocitat (terrestres): {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :Unitats de velocitat (nàutiques): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Quan es mostren velocitats a la interfície d'usuari, presenta-les en les unitats seleccionades ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Imperial (mph) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :Mètric (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :SI (m/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :Unitats del joc (cel·les/dia) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :Nusos STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Unitats de potència dels vehicles: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Quan es mostra la potència d'un vehicle a la interfície d'usuari, presenta-la en les unitats seleccionades @@ -4586,6 +4587,7 @@ STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Aquesta STR_AI_CONFIG_HUMAN_PLAYER :Jugador humà STR_AI_CONFIG_RANDOM_AI :IA aleatòria STR_AI_CONFIG_NONE :(cap) +STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Nombre màxim de competidors: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mou amunt @@ -4599,7 +4601,7 @@ STR_AI_CONFIG_AI :{SILVER}IA STR_AI_CONFIG_CHANGE_AI :{BLACK}Trieu una IA STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Tria un script de partida -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carrega un altre script +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carrega un altre script. Si feu Ctrl + clic, es mostraran totes les versions disponibles. STR_AI_CONFIG_CONFIGURE :{BLACK}Configura STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configura els paràmetres de l'script diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 836720e999..eec916b16b 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -1919,10 +1919,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nijedan STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Početni množitelj veličine grada: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Prosječna veličina gradova u donosu na naselja kod početka igre -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Ažuriraj povezni grafikon svakih {STRING}{NBSP}dan{P 0:2 a a a} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Vrijeme između slijedećih rekalkulacija poveznog grafikona. Svaka rekalkulacija izračunava planove za jednu komponentu grafikona. To znači da vrijednost X za ovu postavku ne mora značiti i ažuriranje kompletnog grafikona unutar X dana. Samo neke komponente će biti ažurirane. Čim kraće vrijeme odredite, više će biti potrebno resursa CPU-a za izračun. Čim duže vrijeme odredite, trebati će više vremena za pokretanje distribucije po novim rutama. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Uzmi {STRING}{NBSP}dan{P 0:2 a a a} za rekalkulaciju poveznog grafikona -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Vrijeme potrebno za rekalkulaciju komponente poveznog grafikona. Kada se rekalkulacija pokrene, stvara se slijed koji može raditi broj dana koliko ovdje odredite. Čim kraće vrijeme odredite, postoji mogućnost da slijed neće biti gotov kada bi trebao. Tada se igra usporava odnosno zaustavlja dok ne bude gotovo. Čim duže vrijeme odredite, potrebno je duže da se distribucija ažurira kad se izmijene rute. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Način distribucije za putnike: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetrično" znači da će se otprilike isti broj putnika slati od stanice A prema stanici B ako od B prema A. "Asimetrično" znači da će se proizvoljni brojevi putnika slati u oba smjera. "Ručno" znači da se distribucija za putnike neće vršiti automatski. diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 7a0792a94e..615ad24546 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -2010,10 +2010,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Žádné STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Činitel základní velikosti města: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Průměrná velikost větších měst v porovnání s ostatními městy na začátku hry -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualizovat distribuční graf po {STRING}{P 0:2 dni dnech dnech} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Čas mezi přepočítáváním částí grafu spojení. Každý přepočet přepočítává plány jedné části grafu. To znamená, že hodnota X u toho nastavení nezpůsobí, že se každých X dní přepočítá celý graf, ale pouze určité části. Čím kratší interval nastavíš, tím více času CPU bude potřeba ke spočítání. Čím delší nastavíš, tím déle bude trvat dokud si distribuce nákladu najde nové trasy. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Zaber si {STRING}{NBSP}{P 0:2 "den" "dny" "dní"} na přepočet grafu spojení -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Čas vyhrazený pro každý přepočet části grafu spojení. Pokud přepočet začne, je vytvořeno nové vlákno, které má dovoleno běžet po zvolený počet dnů. Čím nižší hodnotu nastavíš tím je pravděpodobnější, že vlákno nebude dokončeno kdy má. Pokud se tak stane, hra se zastaví ("lagne") dokud dokončeno nebude. Čím vyšší hodnotu nastavíš, tím déle bude trvat aktualizace grafu pokud se trasy změní. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Mód distribuce pro cestující: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství cestujících chce cestovat ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný" znamená, že libovolné množství cestujících může cestovat v jakémkoliv směru. "Manuální" znamená, že zde nebude žádná automatická distribuce pro cestující. diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 12d6e49f83..c9eb339a0f 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -1926,10 +1926,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ingen STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Startværdi for bystørrelsesfaktor: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Gennemsnitlig størrelse af storbyer i forhold til normale byer ved start af spillet -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Opdatér distributionsgraf hver {STRING} dag{P 0:2 "" e} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tid mellem efterfølgende genberegninger af forbindelsesgrafen. Hver genberegning beregner planerne for et komponent af grafen. Det betyder, at en værdi X for denne indstilling ikke betyder at hele grafen vil blive opdateret hver X dage. Kun nogle komponenter vil. Jo kortere du sætter indstillingen, jo mere CPU-tid vil være nødvendig for at beregne forbindelsesgrafen. Jo længere du sætter indstillingen, jo længere vil det tage før lastdistribution starter på nye ruter. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Tag {STRING} dag{P 0:2 "" e} for genberegning af distributionsgraf -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tid taget for hver genberegning af et forbindelsesgrafkomponent. Når en genberegning startes, skabes en tråd som er tilladt at køre dette antal dage. Jo kortere du sætter denne indstilling, jo mere sandsynligt er det at tråden ikke er færdig når det er meningen. Så stopper spillet indtil den er ("lag"). Jo længere du sætter denne indstilling, jo længere tager det for distributionen at blive opdateret når ruter ændres. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributionsmodel for passagerer: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetrisk" betyder, at omtrent det samme antal passagerer vil gå fra en station A til en station B som fra B til A. "Asymmetrisk" betyder, at vilkårlige antal passagerer kan gå i begge retninger. "Manuel" betyder, at der ikke finder nogen automatisk distribution sted for passagerer. diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index ace17b4eae..86a5938263 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -1926,10 +1926,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Geen STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Beginfactor voor stadsgroei: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Gemiddelde grootte van steden in vergelijking tot normale steden bij het begin van het spel. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Werk distributiegrafiek elke {STRING}{NBSP}dag{P 0:2 "" en} bij -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tijd tussen opeenvolgende herberekeningen van de koppelinggrafiek. Elke herberekening berekent de plannen voor een component van de grafiek. Dat betekent dat een waarde X voor deze instelling niet betekent dat de hele grafiek elke X dagen wordt bijgewerkt. Alleen een component wordt bijgewerkt. Hoe korter je dit instelt, hoe meer CPU-tijd nodig is om de berekening te maken. Hoe langer je dit instelt, hoe langer het duurt voordat de vrachtdistributie op nieuwe routes start. -STR_CONFIG_SETTING_LINKGRAPH_TIME :{STRING}{NBSP}dag{P 0:2 "" en} gebruiken voor herberekening van de distributiegrafiek -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tijd die wordt gebruikt voor een herberekening van een component van een koppelinggrafiek . Wanneer een herberekening wordt gestart, wordt een draad voortgebracht die dit aantal dagen mag lopen. Hoe korter je dit instelt, hoe waarschijnlijker het is dat de draad niet is voltooid als dat zou moeten. Dan stopt het spel totdat het 'bij' is ('lag'). Hoe langer je dit instelt, hoe langer het duurt voordat de distributie wordt aangepast als een route wijzigt. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributiemodus voor passagiers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :'Symmetrisch' betekent dat ongeveer hetzelfde aantal passagiers van station A naar station B gaat als van B naar A. 'Asymmetrisch' betekent dat willekeurige aantallen passagiers reizen in beide richtingen. 'Handmatig' betekent dat er geen automatische distributie plaatsvindt voor passagiers. diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 17b9cdfa10..ab7d6f6207 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -1926,10 +1926,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :None STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Initial city size multiplier: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Average size of cities relative to normal towns at start of the game -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Update distribution graph every {STRING}{NBSP}day{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Time between subsequent recalculations of the link graph. Each recalculation calculates the plans for one component of the graph. That means that a value X for this setting does not mean the whole graph will be updated every X days. Only some component will. The shorter you set it the more CPU time will be necessary to calculate it. The longer you set it the longer it will take until the cargo distribution starts on new routes. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Take {STRING}{NBSP}day{P 0:2 "" s} for recalculation of distribution graph -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Time taken for each recalculation of a link graph component. When a recalculation is started, a thread is spawned which is allowed to run for this number of days. The shorter you set this the more likely it is that the thread is not finished when it's supposed to. Then the game stops until it is ("lag"). The longer you set it the longer it takes for the distribution to be updated when routes change. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribution mode for passengers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "Asymmetric" means that arbitrary numbers of passengers can go in either direction. "Manual" means that no automatic distribution will take place for passengers. diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index fddffa76a3..f417b60c98 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -1926,10 +1926,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :None STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Initial city size multiplier: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Average size of cities relative to normal towns at start of the game -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Update distribution graph every {STRING}{NBSP}day{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Time between subsequent recalculations of the link graph. Each recalculation calculates the plans for one component of the graph. That means that a value X for this setting does not mean the whole graph will be updated every X days. Only some component will. The shorter you set it the more CPU time will be necessary to calculate it. The longer you set it the longer it will take until the cargo distribution starts on new routes. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Take {STRING}{NBSP}day{P 0:2 "" s} for recalculation of distribution graph -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Time taken for each recalculation of a link graph component. When a recalculation is started, a thread is spawned which is allowed to run for this number of days. The shorter you set this the more likely it is that the thread is not finished when it's supposed to. Then the game stops until it is ("lag"). The longer you set it the longer it takes for the distribution to be updated when routes change. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribution mode for passengers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "Asymmetric" means that arbitrary numbers of passengers can go in either direction. "Manual" means that no automatic distribution will take place for passengers. diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 5b3f1ee73b..7dda278f20 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -1979,10 +1979,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Mitte ühtegi STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Algne linnade suuruskordaja: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Keskmine linna suurus võrreldes tavalise asulaga mängu alguses -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Jaotusgraafikuid uuendatakse igal {STRING}. päeval -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Aega ahelgraafikute koostamise vahel. Koostamine uuendab plaane ainult ühes graafiku osas. Seega X väärtusega ei uuendata graafikut iga X päeva tagant. Uuendatakse vaid ühte osa. Väiksema arvuga kasutatakse protsessorit rohkem. Suurema arvuga läheb kauem aega, kuni uuel teel alustatakse kaubavedu. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Jaotusgraafikud koostatakse {STRING} päeva jooksul -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Aega ahelgraafiku osa koostamiseks. Koostamise algul käivitatakse protsess, mis võib töötada määratud arv päevi. Väiksema väärtusega on suurem võimalus, et protsess lõppe. Kui protsess ei ole lõppenud, siis mäng seisatakse protsessi lõppemiseni (tekib viivitusi). Suurema arvuga läheb kauem, kuni muudetud teel uuendatakse kaubajaotust. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Reisijate jaotuse viis: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Kui jaamast A läheb jaama B umbes sama hulk reisijaid, kui jaamast B jaama A, siis jaotus on «Sümeetriline». Kui mõlemas suunas võib liikuda ükskõik, kui palju resijaid, siis jaotus on «Asümeetriline». Kui reisijate liikumist ei jaotata, siis jaotus on «Väljas». diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index d46379bc12..ce7a0e95d7 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -1926,10 +1926,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ei yhtään STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Kasvukerroin alussa: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Kaupunkien keskimääräinen koko suhteessa muihin kuntiin pelin alussa -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Päivitä rahdin jakautuminen {STRING}{NBSP}päivän välein -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Yhteyskuvaajan uudelleenlaskujen välinen aika. Kukin uudelleenlasku laskee yhden kuvaajan komponentin. Tämä tarkoittaa sitä, että koko kuvaajaa ei lasketa uudelleen määrittämäsi ajan välein, vaan ainoastaan yksi komponentti. Mitä lyhyemmäksi määrität asetuksen, sitä enemmän prosessoriaikaa komponentin laskemiseen vaaditaan. Mitä pidemmäksi määrität sen, sitä pidempi aika kuluu, kunnes rahdin jakaminen alkaa uusilla reiteillä. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Käytä {STRING}{NBSP}päivä{P 0:2 "" ä} rahtijakauman päivittämiseen -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Jokaisen yhteyskuvaajan komponentin uudelleenlaskemiseen käytettävä aika. Uudelleenlaskun alkaessa käynnistetään uusi säie, jonka annetaan toimia näin monta päivää. Mitä lyhyemmäksi määrität tämän, sitä todennäköisempää on, että säie ei ole valmis ajoissa. Tällöin peli pysähtyy kunnes lasku on suoritettu loppuun (peli pätkii). Mitä pidemmäksi määrität asetuksen, sitä pitempään rahdin jakauman päivittämiseen kuluu aikaa reittien muuttuessa. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Matkustajien jakautuminen: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että matkustajia voi kulkea mielivaltainen määrä kumpaankin suuntaan. ”Manuaalinen” tarkoittaa, että automaattista jakautumista ei sovelleta matkustajiin. diff --git a/src/lang/french.txt b/src/lang/french.txt index f178177477..7819134765 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -1927,10 +1927,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Aucune STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicateur initial pour la taille des métropoles{NBSP}: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Taille moyenne des métropoles par rapport aux villes normales au début de la partie -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Recalculer le graphe de distribution tous les {STRING}{NBSP}jour{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Intervalle entre le recalcul du graphe de distribution. À chaque itération, une seule composante du graphe est recalculée. Donc, une valeur X pour ce réglage ne signifie pas que le graphe est réactualisé entièrement tous les X jours. Plus l'intervalle est court, plus de temps CPU est nécessaire pour la recalcul. Plus il est long, et plus de temps sera nécessaire pour que la distribution s'effectue sur de nouvelles routes. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Prendre {STRING}{NBSP}jour{P 0:2 "" s} pour recalculer le graphe de distribution -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Durée maximale (en jours) du recalcul d'une composante du graphe. À chaque itération, un thread est initié, qui a une durée maximale définie par ce réglage. Plus celui-ci est court, plus la probabilité que le thread ne termine pas sa tâche à temps est élevée. Le jeu s'interrompt alors jusqu'à la fin du recalcul ("lag"). Plus le réglage est long, et moins rapidement la distribution sera réactualisée en cas de changement de routes. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Type de distribution pour les passagers{NBSP}: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symétrique" signifie qu'autant de passagers iront d'une station A vers une station B, que de la station B vers la station A. "Asymétrique" signifie qu'un nombre arbitraire de passagers peut être envoyé dans les deux directions. "Manuel" signifie qu'aucune distribution n'est mise en place pour les passagers. diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index a131730b8d..a1f449cdb3 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -1758,7 +1758,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 in {COMMA} STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Gjin STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Begjin stêdgrutte fermenigfuldiger: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Wurkje by de grafyk fan distribúsje eltse{STRING}{NBSP}dagen{P 0:2 "" s} STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribusjemodus foar pazzazjiers: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distribusjemodus foar post: {STRING} diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 4cc506f957..bc34a57eef 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -1969,10 +1969,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Chan eil gin STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Iomadaichear meud nam bailtean aig an toiseach: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Am meud cuibheasach dhe mhòr-bhailtean an coimeas ri bailtean àbhaisteach aig toiseach a' gheama -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Ùraich graf an sgaoilidh gach {STRING}{NBSP}{P 0:2 latha latha làithean latha} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :An ùine eadar dà ath-àireamhachadh dhe ghraf nan ceangal. Àireamhaichidh gach ath-àireamhachadh na planaichean airson co-phàirt dhen ghraf. Is ciall dha seo nach tèid an graf air fad ùrachadh gach X latha nuair a bhios an luach seo suidhichte air X, ach nach tèid ach co-phàirt ath-àireamhachadh. Mar as giorra a shuidhicheas tu e, ’s ann nas motha dhe ùine an CPU a bhios a dhìth airson an àireamhachadh. Mar as fhaide a shuidhicheas tu e, ’s ann nas fhaide a bheir e gus an tòisich sgaoileadh a' charago air slighean ùra. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Thoir {STRING}{NBSP}{P 0:2 latha latha làithean latha} airson graf an sgaoilidh ath-àireamhachadh -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :An ùine a bheir gach ath-àireamhachadh aig co-phàirt dhe ghraf nan ceangal. Nuair a thòisichear air ath-àireamhachadh, thèid sreath ùr a ghintinn a ruitheas fad na h-àireimh seo dhe làithean. Mar as giorra a shuidhicheas tu seo, ’s ann nas coltaiche a bhios e nach bi sreath deiseil nuair a bu chòir. Stadaidh an geama an uairsin gus am bidh an sreath deiseil (“dàil”). Mas as fhaide a shuidhicheas tu seo, ’s ann nas fhaide a bheir e gus an tèid an sgaoileadh ùrachadh nuair a dh'atharraicheas slighe. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Am modh sgaoilidh airson taistealaich: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Is ciall dha “co-chothromach” gun tèid cha mhòr an aon uiread dhe thaistealaich a chur o stèisean A gu stèisean B ’s a thèid a chur o stèisean B gu stèisean A. Is ciall dha “neo-chothromach” gun tèid uiread air thuaiream dhe thaistealaich a chur dhan dà chomhair. Is ciall dha “a làimh” nach tèid sgaoileadh fèin-obrachail sam bith a dhèanamh airson taistealaich. diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 599e4a6c41..b4c4b768f8 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -1924,10 +1924,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ningunha STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial do tamaño da cidade: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Relación entre o tamaño medio das cidades e o dos pobos ao inicio da partida -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualiza o gráfico de distribución cada {STRING}{NBSP}day{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tempo entre recálculos subseguintes do gráfico de ligazóns. Cada recálculo calcula os plans para unha compoñente do gráfico. Isto non significa que un valor de X para esta opción supoña que o gráfico completo será actualizado cada X días. Só algunhas compoñentes o serán. Canto máis curto sexa, máis tempo de CPU será necesario para calculalo. Canto máis longo sexa, máis tempo levará ata que a distribución das mercadorías comeza para rutas novas. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Leva {STRING}{NBSP}día{P 0:2 "" s} recalcular o gráfico de distribución -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo empregado para cada recálculo dunha compoñente do gráfico de ligazóns. Cando comeza un recálculo, creáse un fío que funciona por este número de días. Canto máis pequeno sexa este, é máis probable que o fío non remate cando se supón. Nese intre o xogo para para compensar este retardo. Canto máis longo sexa, máis tempo leva actualizar a distribución cando cambian as rutas. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasaxeiros: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que máis ou menos o mesmo número de pasaxeiros irán dende a estación A cada a estación B e tamén da B cara a A. "Asimétrico" significa que calquera número de pasaxeiros pode ir en calquera dirección. "manual" significa que non haberá distribución automática para os pasaxeiros. diff --git a/src/lang/german.txt b/src/lang/german.txt index 8302533c33..322000de67 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -1924,10 +1924,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Keine STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Größe von Großstädten bei Spielbeginn: {STRING}× STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Durchschnittliche Größe von Großstädten relativ zu normalen Städten bei Spielbeginn -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Neuberechnung der Warenverteilung alle: {STRING}{NBSP}Tag{P 0:2 "" e} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Zeit zwischen zwei Neuberechnungen des Verteilungsgraphen. Jede Neuberechnung berechnet die Verteilungspläne für eine Komponente des Graphen. Das heißt dass ein Wert X für diese Einstellung nicht zu einer Neuberechnung der gesamten Verteilung alle X Tage führt, sofern es mehrere getrennte Komponenten gibt. Je kleiner der Wert, desto rechenaufwändiger ist die Berechnung. Je größer er ist, desto länger dauert es bis Änderungen an den Fahrplänen sich auf die Verteilung auswirken. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Laufzeit für jede Neuberechnung der Warenverteilung: {STRING}{NBSP}Tag{P 0:2 "" e} -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Laufzeit für jede Neuberechnung des Verteilungsgraphen. Für jede Neuberechnung wird ein Thread gestartet, der diese Zeit bekommt, um fertig zu werden. Wenn die Zeit gering ist, ist die Wahrscheinlichkeit hoch, dass er zum gegebenen Zeitpunkt noch nicht fertig ist. Das manifestiert sich darin, dass das Spiel „stehen bleibt“, bis der Thread fertig wird. Wenn die Zeit sehr lang ist, dauert es länger bis Änderungen an den Fahrplänen sich auf die Verteilung auswirken. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Verteilungsschema für Passagiere: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :„Symmetrisch“ heißt, dass etwa die selbe Zahl von Passagieren von einer Station A zu einer anderen Station B reisen, wie von B nach A. „Asymmetrisch“ heißt, dass Passagiere in beliebigen Zahlen hin- und her fahren können. „Manuell“ heißt, dass keine automatische Verteilung der Passagiere stattfindet. diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 958b6fed27..565b6fa653 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -2027,10 +2027,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Καμία STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Αρχικός πολλαπλασιαστής μεγέθους πόλης: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Μέσο μέγεθος μεγάλων πόλεων σε σχέση με τις κανονικές στην αρχή του παιχνιδιού -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Ενημέρωση γραφήματος κάθε {STRING}{NBSP}μέρ{P 0:2 α ες} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Χρόνος που μεσολαβεί μεταξύ επαναυπολογισμών του γραφήματος συνδέσμου. Κάθε επαναυπολογισμός υπολογίζει το σχέδιο για ένα τμήματος του γραφήματος. Αυτό σημαίνει ότι μια τιμή Χ για αυτή τη ρύθμιση δεν σημαίνει ότι ολόκληρο το γράφημα θα ενημερώνεται κάθε Χ ημέρες, μονάχα κάποια τμήματα. Όσο μικρότερη ρύθμιση τεθεί τόσο μεγαλύτερος χρόνος επεξεργαστή απαιτείται για τον υπολογσιμό του. Όσο μεγαλύτερη ρύθμιση τεθεί τόσο περισσότερο θα πάρει για να ξεκινήσει η διανομή φορτίου σε νέες διαδρομές. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Πάρε {STRING}{NBSP}μέρ{P 0:2 α ες} για επανυπολογσιμό του γραφήματος διανομής -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Χρόνος που απαιτείται για επαναυπολογισμούς τμήματος γραφήματος συνδέσμου. Όταν ένας επαναυπολογισμός αρχίζει, προκύπτει ένα νήμα το οποίο επιτρέπεται να τρέξει για έναν συγκεκριμένο αριθμό ημερών. Όσο μικρότερος αριθμός τόσο μεγαλύτερες πιθανότητες ότι το νήμα δεν τελείωνει όταν πρέπει. Τότε το παιχνίδι σταματά μέχρι να ολοκληρωθεί («λαγκάρει»). Όσο μεγαλύτερος αριθμός τόσο μεγαλύτερο χρόνο παίρνει για να για να ενημερωθεί διανομή όταν αλλάζουν οι διαδρομές. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Τρόπος διανομής επιβατών: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Το «συμμετρικό» σημαίνει ότι περίπου ο ίδιος αριθμός επιβατών θα σταλέι από έναν σταθμό Α σε ένα σταθμό Β όσο από τον Β στον Α. Το «ασυμμετρικό» σημαίνει ότι αυθαίρετος αριθμός επιβατών μπορεί να σταλούν σε οποιαδήποτε εκ των δύο κατευθύνσεων. Το «χειροκίνητο» σημαίνει ότι καμία αυτόματη διανομή δε θα γίνεται για τους επιβάτες. diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 20011d2666..3cb271db99 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -1818,10 +1818,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :ללא STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :{STRING} :מכפיל התחלתי של גודל העיירות STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :גודל ממוצע של ערים יחסית לעיירות רגילות בתחילת המשחק -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :עדכן את הגרף מדי {STRING} {P 0:2 יום ימים} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :זמן לחישוב מחדש של גרף הקישור. כל חישוב מחדש מחשב את התכניות של פריט יחיד בגרף. כלומר, בהגדרה של ערך X אין הכרח שכל הגרף יתעדכן מדי X ימים. רק פריט ממנו יתעדכן. ערך קטן יותר דורש יותר זמן מעבד לחישוב. ערך גבוה קובע זמן ארוך יותר עד שחלוקת המטען מתחילה בנתיב חדש. -STR_CONFIG_SETTING_LINKGRAPH_TIME :המתן {STRING} י{P 0:2 ום מים} לחישוב מחדש של גרף החלוקה -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :הזמן לחישוב מחדש של נקודה בגרף. החישוב מורשה לרוץ במשך מספר ימים זה. בקביעת זמן קצר, החישוב עלול שלא להסתיים במועד. המשחק נעצר עד הסיום (השהיה). בקביעת זמן ארוך, עדכון הערך יתעכב זמן ארוך יותר לאחר שינוי מסלולים. STR_CONFIG_SETTING_DISTRIBUTION_PAX :אופן החלוקה עבור נוסעים: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"סימטרי" הכוונה שמספר הנוסעים מתחנה א' לתחנה ב' הוא פחות או יותר אותו מספר הנוסעים מתחנה ב' לתחנה א'. "אסימטרי" הכוונה שמספר נוסעים שרירותי יכול ליסוע כל אחד מהכיוונים. "ידני" הכוונה שאין חלוקה אוטומטית עבור נוסעים. diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 7a84ceef57..2dfe80d35e 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -1985,10 +1985,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :nincs STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Kezdeti városméret-szorzó: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Átlagos városméret a normál településekhez képest a játék kezdetén -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :A szétosztási gráf frissítése {STRING}{NBSP}naponként -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :A kapcsolati gráf egyes újraszámításai között eltelő idő. Minden számítás a gráf egy adott komponensére vonatkozik. Egy adott X beállítás esetén nem fog a teljes gráf X naponként frissülni, csak egy komponense. Minél rövidebb ez az idő, annál több CPU időre lesz szükség a számítás elvégzéséhez. Minél hosszabb ez az idő, annál több ideig fog tartani, mire a szétosztás megindul az új útvonalakon. -STR_CONFIG_SETTING_LINKGRAPH_TIME :A szétosztási gráf újraszámolására szánt idő: {STRING}{NBSP}nap -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :A kapcsolati gráf egy komponensének újraszámítására szánt idő. Az újraszámítás egy külön szálon indul el, és a megadott számú napig fut. Minél rövidebb ez az időtartam, annál valószínűbb, hogy a számítás nincs kész az idő lejártakor, ekkor a játék megáll a számítás befejeződéséig (ettől a játék akadhat). Minél hosszabb ez az időtartam, annál több idő kell a szétosztás frissüléséhez, amikor megváltoznak az útvonalak. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Utasok szétosztása: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :A "szimmetrikus" azt jelenti, hogy megközelítóleg ugyanannyi utas megy majd A-ból B-be, mint B-ből A-ba. Az "aszimmetrikus" beállítás esetén a különbözö irányokba tetszőleges mennyiségű utas mehet. "Kézi" esetben az utasok nem lesznek automatikusan szétosztva. diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index f955ee9ff9..e9dc5414e3 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -1921,10 +1921,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Tidak ada STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Faktor kali ukuran kota awal: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Ukuran rata-rata kota besar terhadap kota kecil saat permainan dimulai -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Perbarui grafik distribusi setiap {STRING}{NBSP}hari -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Waktu diantara dua penghitungan linkgraph berurutan. Setiap penghitungan hanya menghitung satu komponen perencanaan dari grafik. Namun, angka yang diberikan untuk seting ini bukan berarti seluruh grafik akan diperbaharui dalam angka hari yang sama, hanya beberapa bagian. Semakin sedikit semakin banyak proses CPU yang diperlukan untuk menghitung. Semakin banyak semakin lama waktu sebelum cargo distribution dimulai pada rute baru. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Ambil {STRING}{NBSP}hari untuk menghitung grafik distribusi -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Waktu dibutuhkan untuk setiap perhitungan dari komponen 'linkgraph'. Ketika perhitungan dimulai, ada utas 'dibuat' yang boleh dijalankan untuk jumlah hari ini. Semakin pendek anda mengatur ini lebih mungkin utas ini belum selesai ketika itu seharusnya. Kemudian permainan berhenti sampai itu ("lag"). Semakin lama anda mengatur semakin lama itu untuk distribusinya untuk memperbarui ketika rute mengganti. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modus distribusi untuk penumpang: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetris" berarti kira-kira jumlah penumpang sama akan pergi dari stasiun A ke stasiun B sebagaimana dari B ke A. "Asimetris" berarti jumlah penumpang pergi pada kedua arah bisa berbeda-beda. "Manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk penumpang. diff --git a/src/lang/irish.txt b/src/lang/irish.txt index b0abe30339..e4e8135e93 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -1882,10 +1882,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ceann ar bith STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Iolraitheoir tosaigh mhéid na gcathracha: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Meánmhéid na gcathracha i gcomórtas le gnáthbhailte ag tús an chluiche -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Nuashonraigh an graf dáileacháin gach {STRING}{NBSP}lá -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :An t-aga idir gach athríomh ina dhiadh sin ar ghraf na nasc. Déantar na pleananna a ríomh do chomhpháirt amháin den ghraf gach uair a dhéantar athríomh. Mar sin, má shocraíonn tú luach X don socrú seo, ní chiallaíonn sé go ndéanfar an graf iomlá a thabhairt cothrom le dáta gach X lá, ní thabharfar ach comhpháirteanna áirithe de cothrom le dáta. Dá ghiorra an luach a shocraíonn tú is é is mó ama CPU a thógfaidh sé chun é a ríomh. Dá fhaide a shocraíonn tú é is é is faide a thógfaidh sé chun an dáileadh lastais a thosú ar bhealaí nua. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Tóg {STRING}{NBSP}lá chun an graf dáileacháin a athríomh -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :An t-am a thógfar ar gach athríomh ar chomhpháirt de ghraf na nasc. Nuair a thosaítear ar athríomh, gintear snáithe agus ligfear don snáithe sin rith ar feadh an líon sin laethanta. Dá ghiorra an luach a shocróidh tú anseo is mó an seans nach mbeidh an snáithe críochnaithe nuair atá sé in ainm is a bheith. Ansin stopfaidh an cluiche go dtí go mbeidh sé críochnaithe (i.e. beidh "moill" ann). Dá fhaide a shocraíonn tú é is é is faide a thógfaidh sé chun an dáileachán a thabhairt cothrom le dáta nuair nuair a athraíonn na bealaí. STR_CONFIG_SETTING_DISTRIBUTION_PAX :An mód dáileacháin do phaisinéirí: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Ciallaíonn "siméadrach" go rachaidh thart ar an méid céanna paisinéirí ó stáisiún A go stáisiún B agus a rachaidh ó B go A. Ciallaíonn "neamhshiméadrach" gur féidir méideanna neamhshrianta paisinéiri dul i gceachtar den dá threo. Ciallaíonn "de láimh" nach ndéanfar dáileadh uathoibríoch ar phaisinéirí. diff --git a/src/lang/italian.txt b/src/lang/italian.txt index 9e4b5b142c..2b4c9b33a8 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -1958,10 +1958,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nessuna STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Moltiplicatore iniziale dimensioni metropoli: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Dimensione media delle metropoli in rapporto alle normali città all'inizio della partita. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aggiorna il grafo di distribuzione ogni {STRING}{NBSP}giorn{P 0:2 o i} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tempo fra due ricalcoli consecutivi del grafo delle rotte. Ad ogni ricalcolo vengono generati i piani per una sola componente del grafo. Ciò significa che un valore X per questa impostazione non causa il ricalcolo dell'intero grafo ogni X giorni, ma solo di una componente. Più breve l'intervallo impostato, più tempo la CPU consuma per calcolare il grafo. Più lungo l'intervallo, più a lungo bisogna attendere prima che la distribuzione abbia inizio su nuovi percorsi. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Impiega {STRING}{NBSP}giorn{P 0:2 o i} per il ricalcolo del grafo di distribuzione -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo impiegato per il ricalcolo di una singola componente del grafo. All'avvio di un ricalcolo viene creato un thread che è mantenuto in esecuzione per il numero di giorni impostato. Più corto è l'intervallo impostato, più è probabile che il thread non termini in tempo. In questo caso, il gioco si interrompe attendendo la fine del thread (causando un rallentamento). Più l'intervallo impostato è lungo, più tempo è necessario affinché la distribuzione venga aggiornata quando le rotte cambiano. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modalità di distribuzione dei passeggeri: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :In modalità "Simmetrica" il numero di passeggeri che viaggiano da una stazione A ad una stazione B è approssimativamente lo stesso di quelli che viaggiano da B ad A. In modalità "Asimmetrica" è consentito il viaggio di un numero di passeggeri arbitrario in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica dei passeggeri. diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index fc5ddb598e..dac89946ad 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :変化なし STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初期の都市サイズ乗数: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ゲーム開始時に都市が普通の街に比べて平均して何倍の人口規模になるかを設定します -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :分配グラフの更新頻度: {STRING}日 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :リンクグラフを再計算する時間間隔を設定します。それぞれの再計算では、グラフの単一要素に関わる経路計画だけを計算します。つまり、グラフの一部が更新されるだけで、全体が設定した間隔で更新されるという訳ではありません。この間隔を短くすると再計算のためにCPUへの負荷が大きくなります。長くすると、新たなルートが貨物分配に組み込まれるのに時間がかかるようになります。 -STR_CONFIG_SETTING_LINKGRAPH_TIME :分配グラフの再計算時間: {STRING}日 -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :グラフの単一要素に関わる再計算にかけられる時間を設定します。再計算が開始されると、この日数のみ実行可能なスレッドが生成されます。この設定が短いと、期日までにスレッドが終了していない可能性が高くなり、終了するまでゲームが停止します(ラグ)。長くした場合、経路が変更された場合に分配が更新されるまでに時間がかかるようになります STR_CONFIG_SETTING_DISTRIBUTION_PAX :旅客の行先分配法: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :旅客がどのように行き先別に分配されるかを設定します。「対称」ではAからBへ向かう乗客とほぼ同数が、BからAに向かうようになります。 「非対称」ではそれぞれの方向に向かう旅客数は独立に決められます。「無効」では行き先別分配をしなくなります。 diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 866b1c293e..c5be21ae1b 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -1927,10 +1927,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :없음 STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :초기 대도시 크기 비율: 일반 도시보다 {STRING}배 크게 시작 STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :게임을 시작했을 때 일반 도시에 대한 대도시의 평균 크기를 설정합니다 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :분배 상태를 매 {STRING}일 마다 갱신 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :다음 연결 상태를 재계산하기까지의 시간입니다. 한 번의 재계산할 때마다 그래프의 한 요소를 위한 계획을 계산합니다. 이는 이 설정의 X값에 따라 모든 그래프가 매 X일마다 갱신되는 것이 아니라는 것을 뜻합니다. 일부 요소만 재계산된다는 뜻입니다. 값이 작으면 작을 수록 CPU가 계산해야 할 횟수가 늘어납니다. 값을 크게 설정할 수록 화물 분배 상태가 새롭게 지정되는 데 더 오랜 시간이 걸립니다. -STR_CONFIG_SETTING_LINKGRAPH_TIME :화물 분배 연결 상태를 {STRING}일마다 다시 계산 -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :각 연결 상태 요소의 재계산을 위해 필요한 시간입니다. 재계산이 시작될 때, 이 날짜만큼 작동하는 스레드가 생성됩니다. 이 값이 작으면 작을수록, 스레드가 끝나야할 때에 스레드가 끝나지 않게 됩니다. 그러면 게임이 랙에 걸려 멈추게 됩니다. 값을 크게 설정할수록 경로가 바뀔 때 분배 상태가 업데이트 되는 시간이 오래 걸리게 됩니다. STR_CONFIG_SETTING_DISTRIBUTION_PAX :승객에 대한 분배 형식: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"대칭"은 A역에서 B역으로 가려는 승객의 수가 B에서 A로 가려는 승객의 수와 비슷하다는 뜻입니다. "비대칭"은 승객이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 승객 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 55368a8778..e9054c7ea4 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -1971,10 +1971,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nulla STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicator magnitudinis initialis urbis: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Quam maiores sunt urbes quam oppida in initio ludi -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Recensere formulam partitionis {STRING} quoque die -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tempus inter recensiones formulae partitionis. Quaeque recensio calculat rationes unius partis formulae. Ergo valor X huius electionis non facit ut cuncta formula recenseatur X quoque die; modo aliquot pars/partes recensebuntur. Valoribus minoribus, plus tempus CPU requiritur. Valoribus maioribus, plus tempus erit ad onerum partitionem incipiendam novis itineribus. -STR_CONFIG_SETTING_LINKGRAPH_TIME :{STRING}{NBSP}die{P 0:2 "" s} ad formulam partitionis recalculandam -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempus cuiusque recalculationis partis partitionis. Cum recalculatio incipitur, linea generatur quae agitur hos dies electos. Paucis diebus, magis probabilis est lineam non finiri cum debet esse finitam; tunc ludus intermittitur usque ad finitur ("segnitia"). Pluribus diebus, plus tempus requiritur ad partitionem mutandam cum itinera mutantur. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modus partitionis vectoribus: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Partitio "symmetrica" facit ut fere eadem copia vectorum mittatur a statione A ad stationem B quam a B ad A. Partitio "asymmetrica" facit ut quaelibet copia vectorum mittatur inter A et B. In partitione "manu" vectores non automatice partiuntur. diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index db7a8c08f3..5a5aeee827 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -1925,10 +1925,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :neviena STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Pilsētu sākuma lieluma reizinātājs: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Pilsētu vidējais lielums attiecībā pret parastām apdzīvotām vietām spēles sākumā -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Atjaunināt sadales grafu ik pa {STRING}{NBSP}dien{P 0:2 ai ām ām} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Laiks starp secīgām saišu grafa pārrēķināšanām. Katra pārrēķināšana izskaitļo plānos vienai grafa komponentei. Tas nozīmē, ka šim iestatījumam vērtība X nenozīmē, ka viss grafs tiks atjaunināts ir pēc X dienām. Tikai dažas komponentes tiks pārrēķinātas. Jo mazāka iestatītā vērtība, jo vairāk laika CPU pavadīs rēķinot. Jo lielāka iestatītā vērtība, jo ilgāk nevarēs sākties kravu izplatīšana jaunos maršrutos. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Dot {STRING}{NBSP}dien{P 0:2 u as u} izplatīšanas grafa pārrēķināšanai -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Laiks, ko aizņem katra saišu grafa komponenšu pārrēķināšana. Kad sākas pārrēķināšana, tiek izveidots pavediens, kuram ir atļauts darboties norādīto dienu skaitu. Jo īsāku skaitli šeit ievadīsiet, jo lielāka iespēja, ka pavediens nebūs laicīgi paveicis savu darbu. Tādā gadījumā spēle apstāsies (“iebremzēs”) līdz darbs būs pabeigts. Jo lielāku skaitli šeit iestatīsiet, jo ilgāk aizņems izplatīšanas atjaunināšana, kad tiks mainīti maršruti. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Pasažieru izplatīšanas režīms: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simetriska" nozīmē, ka apmēram vienāds daudzums pasažieri vēlēsies doties virzienā no stacijas A uz B, cik no B uz A. "asimetriska" nozīmē, ka patvaļīgs pasažieru daudzums var vēlēties nokļūt katrā no virzieniem. "manuāli" nozīmē, ka pasažieriem netiks veikta automātiska izplatīšana. diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 3ab3f00afa..3cf751fa80 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -2109,10 +2109,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nenaudojamas STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Pradinis miestų dydžio daugiklis: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Vidutinis miestų dydis santykiu su normaliais miestais žaidimo pradžioje -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Pasiskirstymo grafą atnaujinti kas {STRING}{NBSP}dien{P 0:2 ą as ų} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Laiko trukmė tarp grafo mazgų perskaičiavimo operacijų. Kiekviena operacija perskaičiuoja tik vieną mazgą, o ne visą grafą; tad jei šioje nuostatoje nurodytą, kad, pavyzdžiui, grafas bus atnaujinamas kas 4-ias dienas, tai nereiškia, kad jis visas bus atnaujintas, o atnaujinti bus tik kai kurie mazgai. Kuo trumpesnė trukmė tarp perskaičiavimų, tuo daugiau grafo perskaičiavimas sueikvos procesoriaus išteklių, tačiau pats grafas geriau atspindės realią situaciją. Kita vertus, ilgesnė trukmė mažiau apkraus procesorių, tačiau gali tekti ilgėliau palaukti, kol nauji maršrutai bus įtraukti į grafą. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Pasiskirstymo grafo perskaičiavimas užtruks {STRING}{NBSP}dien{P 0:2 ą as ų} -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Laiko trukmė skirta pilnam krovinių paskirstymo grafui perskaičiuoti. Nustačius per mažą reikšmę, žaidimas gali trumpam pakibti, kol bus baigti skaičiavimai. Kita vertus, kuo ilgesnė ši trukmė, tuo vėliau į grafą bus įtraukti maršrutų pakeitimai. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Keleivių paskirstymas: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :„Simetriškas“ reiškia, jog iš stoties A į stotį B keliaus apytiksliai toks pat keleivių srautas, kaip ir iš B į A. „Asimetriško“ režimo atveju, srautai pirmyn ir atgal gali skirtis. „Originalus“ reiškia, kad srautai nebus reguliuojami ir veiks kaip ir originaliame TTD žaidime. diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 9d1ca0db14..5b6e2ab0d2 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Keng STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Ufangs-Gréisst vu Stied multiplizéiren mat: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Duerchschnëttsgréisst vu Stied an Proportioun zu normalen Dierfer um Spillstart -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualiséier d'Verdeelungsgrafik all {STRING}{NBSP}D{P 0:2 ag eeg} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Zäit tëscht nofolgenden Neiberechnungen vun der Linkgrafik. All Neiberechnung rechent d'Pläng fir eng Komponent vun der Grafik. Dat heescht, dass en Wert X fir dës Astellung net all X Deeg aktualiséiert gëtt. Nëmmen een Komponent gëtt aktualiséiert. Wat méi kuerz gesat, wat méi CPU Rechenzäit gebraucht gëtt. Wat se méi laang gesat gëtt, wat méi Zäit vergeet bis Wuereverdeelung op enger neier Route gestart gëtt. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Benotz {STRING}{NBSP}D{P 0:2 ag eeg} fir d'Neiberechnung vum Verdeelungsgraf -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Zäit déi gebraucht gëtt fir all Neiberechnung vun enger Linkgrafikkomponent. Wann eng Neiberechnung ufenkt, gëtt en Thread erstallt dee fir dës Unzuel un Deeg leeft. Wann de Wäert ze kleng ass, kann den Thread net an der gewënschter Zäit faerdeg ginn an et kënnt zu engem Lag. Wann de Wäert méi héich gesat gëtt, brauch d'Verdeelung méi lang fir erneiert ze ginn wann eng Streck ännert STR_CONFIG_SETTING_DISTRIBUTION_PAX :Verdeelungsmodus fir Passagéier: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetresch" heescht, dass ongeféier d'selwecht vill Passagéier vun A op B wéi vu B op A geschéckt ginn. "Asymmetresch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt fir Passagéier diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 79ba643032..9fe4350928 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -1896,10 +1896,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :ingen STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Innledende bystørrelsesmultiplikator: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Gjennomsnittsstørrelse på (stor)byer i forhold til vanlige byer ved begynnelsen av spillet -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Oppdater distribusjonsgraf hver {STRING}{NBSP}dag{P 0:2 "" er} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tid mellom påfølgende reberegning av koblingsgrafen. Hver reberegning beregner planene for en del av grafen. Det betyr at en verdi X for denne innstillingen ikke betyr at hele grafen vil bli oppdatert for hver X. dag. Bare noen komponenter vil. Jo kortere du setter det, dess mer CPU tid bil være nødvendig for å beregne det. Jo lenger du setter den, dess lenger vil det ta før last-distribusjonen begynner på nye ruter. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Benytt {STRING}{NBSP}dag{P 0:2 "" er} for omberegning av distribusjonsgraf -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiden det tar for hver ny reberegning av en graf-link komponent. Når en reberegning iverksettes, blir en tråd startet som tillates å kjøre for dette antall dager. Jo kortere du setter dette, desto mer sannsynlig er det at tråden ikke er ferdig til ønsket tid. Da stopper spillet ("etterslep"). Jo lenger du setter den, desto lenger tid tar det for distribusjonen å bli oppdatert når rutene endres. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribusjonsmodus for passasjerer: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetrisk" betyr at omtrent like mange passasjerer vil reise fra stasjon A til stasjon B som omvendt (fra B til A). "asymmetrisk" betyr at et vilkårlig antall passasjerer vil reise i begge retninger. "manuelt" betyr at det ikke vil forekomme automatisk distribusjon for passasjerene diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 95e4a9c260..fbb53a3726 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -2306,10 +2306,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Żadne STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Początkowy mnożnik rozmiarów metropolii: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Średni rozmiar metropolii w porównaniu do normalnych miast na początku gry -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualizuj graf dystrybucji co {STRING}{NBSP}{P 0:2 dzień dni dni} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Czas pomiędzy kolejnymi przeliczeniami grafu połączeń. Każde przeliczenie oblicza plany dla jednego komponentu grafu. Wartość X dla tego ustawienia nie oznacza, że cały graf będzie aktualizowany co X dni. Aktualizowane będą tylko niektóre komponenty. Im mniejszą wartość ustawisz, tym więcej czasu będzie potrzebował procesor, aby wykonać obliczenia. Im większą wartość ustawisz, tym więcej czasu upłynie, zanim rozpocznie się dystrybucja ładunków po nowych trasach. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Przeznacz {STRING}{NBSP}{P 0:2 dzień dni dni} na przeliczenie grafu dystrybucji -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Czas potrzebny na każde przeliczenie komponentu grafu połączeń. Po rozpoczęciu przeliczania tworzony jest wątek, który może działać przez podaną liczbę dni. Im mniejszą wartość ustawisz, tym większe prawdopodobieństwo, że wątek nie zostanie ukończony w wyznaczonym czasie. Wtedy gra zatrzymuje się do czasu jego zakończenia („lag”). Im większą wartość ustawisz, tym dłużej będzie trwała aktualizacja dystrybucji, gdy zmienią się trasy. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Tryb dystrybucji dla pasażerów: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Tryb „symetryczny” oznacza, że mniej więcej tyle samo pasażerów będzie podróżować ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach może podróżować różna liczba pasażerów. Tryb „ręczny” oznacza, że dla pasażerów nie będzie przeprowadzana dystrybucja automatyczna. diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 7fecb3bae0..3a1ed850f9 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -196,6 +196,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph STR_UNITS_VELOCITY_METRIC :{COMMA} km/h STR_UNITS_VELOCITY_SI :{COMMA} m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP} blocos / dia +STR_UNITS_VELOCITY_KNOTS :{COMMA}{NBSP}nós STR_UNITS_POWER_IMPERIAL :{COMMA}cv STR_UNITS_POWER_METRIC :{COMMA}cv @@ -344,9 +345,9 @@ STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Abrir a ###length 31 STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pausa STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Aumentar velocidade do jogo -STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opções -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar jogo, abandonar jogo, sair -STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Mostrar mapa +STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opções e definições +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Guardar, carregar ou abandonar o jogo, sair do programa +STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Exibir mapa, visualizador extra, fluxo de cargas ou lista de sinais STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Mostrar lista de localidades STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Mostrar subsídios STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Mostrar lista de estações da empresa @@ -354,9 +355,9 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Mostrar STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Mostrar informações gerais da empresa STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Mostrar livro de história STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Mostrar lista de objetivos -STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Mostrar gráficos +STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Exibir gráficos da empresa e taxas de pagamento de carga STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostrar tabela de classificação de empresas -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiar a construção de uma nova indústria +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Examina indústrias ou financia a construção de uma nova indústria STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Mostrar lista de comboios da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Mostrar lista de veículos rodoviários da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Mostrar lista de navios da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos @@ -370,8 +371,8 @@ STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construi STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construir aeroportos STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Abra a barra de modelação ambiental para elevar ou baixar terreno, plantar árvores, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostrar janela som/música -STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar última mensagem/notícia, mostrar opções de mensagens -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informações do terreno, consola, depuração de scripts, capturas, sobre o OpenTTD +STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Mostrar a última mensagem/notícia, histórico de mensagens ou eliminar todas as mensagens +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Informações do terreno, captura de ecrã, sobre o OpenTTD e ferramentas de desenvolvedor STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Trocar barras de ferramentas # Extra tooltips for the scenario editor toolbar @@ -1809,7 +1810,9 @@ STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Quando ativo, p STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Idade mínima da empresa para negociar ações: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Definir a idade mínima de uma companhia a partir da qual outros jogadores poderão comprar ou vender ações da mesma. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_VALUE :{COMMA} ano{P "" s} ###setting-zero-is-special +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_NO_MIN :Sem mínimo STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentagem do lucro do serviço a pagar em trajectos de um transporte que alimenta outro transporte: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentagem da receita dada a trajectos intermédios em sistemas em que um transporte alimenta outro, dando maior controlo sobre a receita @@ -1924,10 +1927,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nenhum STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial para a dimensão das metrópoles: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamanho relativo das cidades em relação ao tamanho normal das localidades aquando o início do jogo -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar gráfico de distribuição a cada {STRING} dia{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tempo entre recalculos subsequentes de cada gráfico. Cada recalculo calcula os planos para cada componente do gráfico. Isto significa que um valor X para essa configuração não indica que o gráfico será todo actualizado a cada X dias. Apenas alguns componentes serão. Quanto mais curto o definir, mais tempo será necessário ao CPU para o calcular. Quanto mais longo, mais tempo levará até que a distribuição da carga inicie em novas rotas. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Requer {STRING} dia{P 0:2 "" s} para recalculo do gráfico de distribuição -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo para cada recalculo de um componente de um gráfico. Quando um recalculo começa, um processo é criado e é executado para esse número de dias. Quantos menos dias forem definidos, maior a probabilidade do processo não terminar quando já deveria ter terminado. Neste caso, o jogo irá parar até ele terminar ("lag"). Quanto maior o definir, mais tempo levará para a distribuição ser actualizada quando as rotas mudarem. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribuição para os passageiros: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que aproximadamente o mesmo numero de passageiros irá de uma estação A para uma estação B e de B para A. "Assimétrico" significa que um numero arbitrário de passageiros poderá seguir em qualquer direção. "Manual" significa que nenhuma distribuição automática terá lugar para passageiros. @@ -1953,13 +1952,15 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Definir isto pa STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Saturação de percursos curtos antes de usar percursos de grande capacidade: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Frequentemente existem múltiplos trajectos entre duas estações. Cargodist irá saturar o trajecto mais curto primeiro, depois usar o segundo trajecto mais curto até o saturar, e assim por diante. A saturação é determinada pelo estimativa da capacidade do uso planeado. Ao saturar todos os caminhos, se ainda existir procura, irá sobrecarregar todos os trajectos, com preferência pelos de maior capacidade. No entanto, grande parte das vezes o algoritmo não irá estimar correctamente a capacidade. Esta configuração permite definir até que percentagem um trajecto mais curto deverá ser saturado na primeira passagem antes do algoritmo proceder ao próximo. Defina-o para menos de 100% para evitar estações sobrecarregadas no caso de capacidade super-estimada. -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unidades de velocidade: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unidades de velocidade (terrestre): {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :Unidades de velocidade (náutica): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Quando uma velocidade é mostrada no interface de utilizador, mostrar na unidade selecionada ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Imperial (mph) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :Métrico (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :SI (m/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :Unidades do jogo (quadrados/dia) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :Nós STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Unidades de potência de veículos: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Quando a potência de um veículo é mostrada no interface de utilizador, mostrar na unidade seleccionada @@ -2125,7 +2126,7 @@ STR_CHEAT_NO_JETCRASH :{LTBLUE}Aviões STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Editar altura máxima do mapa: {ORANGE}{NUM} STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Editar altura máxima de montanhas no mapa STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar data: {ORANGE}{DATE_SHORT} -STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Alterar ano actual +STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Alterar ano atual STR_CHEAT_SETUP_PROD :{LTBLUE}Ativar modificação de valores de produção: {ORANGE}{STRING} # Livery window @@ -3078,7 +3079,7 @@ STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Quantid STR_FRAMERATE_GL_LANDSCAPE :{BLACK} World ticks: STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Atraso no gráfico de ligação: STR_FRAMERATE_DRAWING :{BLACK}Renderização gráfica: -STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Janelas de exibição do mundo: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Visualizadores do mundo: STR_FRAMERATE_VIDEO :{BLACK}Saída de video: STR_FRAMERATE_SOUND :{BLACK}Mistura de Som: STR_FRAMERATE_ALLSCRIPTS :{BLACK} SJ/IA total: @@ -3095,7 +3096,7 @@ STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Quantidade de a STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Quantidade de Atraso no Percurso Mundial STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Atraso no gráfico de ligação STR_FRAMETIME_CAPTION_DRAWING :Renderização gráfica -STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderização de janela de exibição do mundo +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderização de visualizador do mundo STR_FRAMETIME_CAPTION_VIDEO :Saída de video STR_FRAMETIME_CAPTION_SOUND :Mistura de Som STR_FRAMETIME_CAPTION_ALLSCRIPTS :total scripts GS/AI @@ -4586,6 +4587,7 @@ STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}As IAs q STR_AI_CONFIG_HUMAN_PLAYER :Jogador humano STR_AI_CONFIG_RANDOM_AI :IA aleatória STR_AI_CONFIG_NONE :(nenhum) +STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Número máximo de oponentes: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mover para cima @@ -4599,7 +4601,7 @@ STR_AI_CONFIG_AI :{SILVER}IAs STR_AI_CONFIG_CHANGE_AI :{BLACK}Selecionar IA STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selecionar Script de Jogo -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script. Ctrl+Clique para mostrar todas as versões disponíveis STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parâmetros do script @@ -4619,12 +4621,12 @@ STR_AI_LIST_CANCEL :{BLACK}Cancelar STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Não mudar o script STR_SCREENSHOT_CAPTION :{WHITE}Tirar uma captura de ecrã -STR_SCREENSHOT_SCREENSHOT :{BLACK}Captura de tela normal +STR_SCREENSHOT_SCREENSHOT :{BLACK}Captura de ecrã normal STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Ampliação máxima STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Ampliação padrão STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Mapa completo STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Mapa de alturas -STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de ecrã do minimapa # Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parâmetros diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index dcb8fdc52d..8f074c764b 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :deloc STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicator iniţial dimensiune oraş: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Dimensiunea medie a orașelor mari față de orașele normale, la începutul jocului -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizează graficul de distribuţie la fiecare {STRING}{NBSP}{P 0:2 zi zile "de zile"} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Interval de timp între recalculările graficului de conexiuni. Fiecare recalculare calculează planurile unei componente ale graficului. Asta înseamnă că o valoare X pentru această setare nu va duce la actualizarea întregului grafic la fiecare X zile, ci doar o componentă va fi actualizată. Cu cât e mai mică valoarea, cu atât mai mult timp va fi necesar pentru calcule. Cu cât e mai mare valoarea, cu atât va dura mai mult până va începe distribuția mărfii pe rute noi. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Acordă {STRING}{NBSP}{P 0:2 zi zile "de zile"} pentru recalcularea graficului de distribuţie -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Timpul necesar pentru fiecare recalculare a unei componente a graficului de legătură. Când se începe o recalculare, este generat un fir de execuție căruia i se permite să ruleze pentru acest număr de zile. Cu cât setați acest lucru mai scurt, cu atât este mai probabil ca firul să nu fie terminat atunci când trebuie. Apoi jocul se oprește până când este ("lag"). Cu cât îl setați mai mult, cu atât este nevoie de mai mult pentru ca distribuția să fie actualizată când se schimbă rutele. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modalitatea de distribuire a pasagerilor: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetric" înseamnă că aproximativ același număr de pasageri va fi transportat din stația A spre stația B, precum de la B la A. "Asimetric" presupune transportul unui număr arbitrar de pasageri în fiecare direcție. "Manual" înseamnă că repartizarea pasagerilor nu va fi automatizată. diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 0a113796ca..55d2cd8ed6 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -2077,10 +2077,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :нет STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Стартовый множитель размера мегаполисов: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Средний размер мегаполисов по сравнению с остальными городами в начале игры -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Обновлять граф распределения раз в {STRING}{NBSP}д{P 0:2 ень ня ней} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Период перерасчёта графов распределения. В каждом цикле рассчитывается не граф полностью, а только один из его компонентов. Чем меньше это значение, тем больше будет нагрузка на процессор. Чем больше значение, тем больше времени пройдёт перед началом расчёта графов для новых маршрутов. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Пересчитывать граф распределения раз в {STRING}{NBSP}д{P 0:2 ень ня ней} -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Время, отведённое для перерасчёта компонентов графа. Расчёт запускается отдельным потоком и продолжается в течение указанного количества игровых дней. Если значение будет слишком маленьким, то, возможно, расчёт не успеет завершиться, и игра будет ждать завершения (это приведёт к задержкам). При больших значениях графы распределения будут медленнее обновляться при изменениях маршрутов. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Распределение пассажиров: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :«Симметричное» означает, что примерно одинаковое количество пассажиров будет направляться по прямому и обратному маршрутам.{}«Несимметричное» означает, что пассажиропотоки в любых направлениях не будут зависеть друг от друга.{}«Вручную» - не использовать автоматическое распределение для пассажиров. diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index ea61087285..6cf07fd6cc 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -2116,10 +2116,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nijedan STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Inicijalni množilac rasta gradova: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Prosečna veličina naselja relativno u odnosu na gradove na početku igre -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Ažuriraj grafikon distribucije svakih {STRING}{NBSP}dan{P 0:2 a a a} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Vreme između sledećih preračuna grafikona. Svaki preračun izračunava planove za jednu komponentu grafikona. To znači da vrednost X za ovu postavku ne mora da znači i ažuriranje celog grafikona unutar X dana. Samo neke komponente će biti ažurirane. Što je vreme kraće, to će biti potrebno više procesorskih resursa za proračun. Što je vreme duže, više će vremena biti potrebno da se distribucija tereta započne na novim putanjama. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Uzmi {STRING}{NBSP}dan{P 0:2 a a a} za preračun grafikona -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Vreme potrebno za preračun komponente grafikona. Kada se preračun pokrene, stvara se sled koji može raditi broj dana koliko ovdje odredite. Čim kraće vreme odredite, postoji mogućnost da sled neće biti gotov kada bi trebao. Tada se igra usporava odnosno zaustavlja dok ne bude gotovo. Čim duže vreme odredite, potrebno je duže da se distribucija ažurira kada se izmene rute. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Način distribucije putnika: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetrično" znači da će se otprilike isti broj putnika slati od stanice A prema stanici B kao i od B prema A. "Asimetrično" znači da će se proizvoljan broj putnika slati u oba smera. "Ručno" znači da se distribucija putnika neće vršiti automatski. diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 343ea67ef4..8e2bab288f 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :没有 STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初始城市规模因子:{STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :游戏开局时,城市的平均规模相对于普通城镇的比值 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :每 {STRING}{NBSP}天刷新一次分配图 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :指定每次计算货物分配图之间的时间。由于每次重新计算只会处理一个货物分配图元件,因此本设定不代表“每若干日重新计算整个货物分配图”。{}如果此设定赋值越小,則系统需要使用更多处理器时间计算货物分配图。相反,如果此设定赋值越大,則货物被派往新路线所需的时间越长。 -STR_CONFIG_SETTING_LINKGRAPH_TIME :容许系统用 {STRING}{NBSP}天时间刷新货物分配图 -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :当刷新货物分配图时,系统会创建一条线程。此处设定的数值即该线程的持续时间。{}赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,赋值越大,则货物分配功能需要较长时间反映线路网变动的影晌。 STR_CONFIG_SETTING_DISTRIBUTION_PAX :乗客分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的乗客数量与乙站往甲站的乘客数量大致相同。“不对称”指任何一站往另一站的乘客数量皆由系统随意决定。“手动”指系统不会自动分配乘客的目的地。 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 4788833852..bca60fd327 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -1991,10 +1991,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :žiadne STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Násobok počiatočnej veľkosti mesta: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Priemerná veľkosť veľkomiest v porovnaní k mestám na začiatku hry. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualizovať distribučný graf každ{P 0:2 "ý" "é" "ých"} {STRING} {P 0:2 "deň" "dni" "dní"} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Čas medzi nasledujúcimi prepočtami grafu spojení. Každý prepočet počíta plány pre jednu súčasť grafu. To znamená, že hodnota X pre toto nastavenie neznamená sa celý graf aktualizuje každých X dní, ale iba jedna súčasť. Čím menej nastavíte, tým viac procesorového času bude potrebného na výpočet. Čím viac nastavíte, tým dlhšie bude trvať, kým sa začne distribuovať na nové trasy. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Použiť {STRING} {P 0:2 "deň" "dni" "dní"} na prepočítanie distribučného grafu -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Čas potrebný pre každé prepočítanie grafu spojov. Pri štarte prepočtu je vytvorené vlákno, ktoré môže bežať uvedený počet dní. Čím menej nastavíte, tým je pravdepodobnejšie, že vlákno nestihne skončiť, kým je to možné. Potom sa hra na nejaký čas zasekne. Čím viac nastavíte, tým dlhšie trvá aktualizácia rozdelenia po zmene trasy. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Druh distribúcie pre cestujúcich: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symetricky" znamená, že približne rovnaké množstvo pasažierov bude cestovať zo stanice A do stanice B ako z B do A. "Asymetricky" znamená, že v oboch smeroch môže cestovať ľubovoľné množstvo pasažierov. "Manuálne" znamená, že sa pre pasažierov nevykoná automatická distribúcia. diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index c9edbef303..9331bab1a7 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -1920,10 +1920,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Noben STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Začetni faktor rasti mesta: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Povprečna velikost mest relativno gledano na normalna naselja na začetku igre. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Posodobi graf razporeda v razmaku {STRING} d{P 0:2 an neva ni ni} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Čas med ponovnimi izračuni za L-G. Vsak preračun izračuna načrte ene komponente grafa. To pomeni da vrednost X za to nastavitev ne pomeni, da bo celotni graf posodobljen vsakih X dni ampak samo nekatere komponente bodo. Krajša nastavitev pomeni več moči za izračun. Daljša pomeni, da bo pozneje tovor razporejen na nove poti. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Porabi {STRING} d{P 0:2 an neva neve dni} za preračun grafa razporeda -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Čas preračuna za vsak izračun L-G komponent. Ko se zažene preračun, se pojavi nit, ki lahko teče za to število dni. Krajša kot je nastavitev, več je možnosti, da se nit ne dokonča kadar bi se morala. Igra se ustavi do zaključka izračuna. Dlje kot je nastavljeno, dlje se osvežuje razpored, ko je pot spremenjena. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Razporedni način za potnike: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "asymmetric" means that arbitrary numbers of passengers can go in either direction. "manual" means that no automatic distribution will take place for passengers. diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 1af71c2630..3c916581d3 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -1924,10 +1924,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ninguna STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial del tamaño de ciudad: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades en relación a los pueblos normales al comienzo de la partida -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar el grafo de distribución cada {STRING}{NBSP}día{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos consecutivos del grafo de distribución. Esta opción se refiere a los cálculos para cada uno de los componentes del grafo, por lo cual fijar un valor no quiere decir que el grafo completo se actualice tras ese número de días. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular el grafo de distribución. Cuanto mayor sea, más tardará el grafo de distribución en adaptarse a nuevas rutas. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo del grafo de distribución -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del grafo de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasajeros: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de pasajeros de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. "Manual" significa que no se realiza una distribución automática para los pasajeros. diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 48330a8a56..9b0128cf81 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -1924,10 +1924,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ninguno STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial de tamaño de ciudad: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades relativo a las localidades al inicio del juego -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar la gráfica de distribución cada {STRING}{NBSP}día{P 0:2 "" s} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos consecutivos de la gráfica de distribución. Esta opción se refiere a los cálculos para cada uno de los componentes de la gráfica, por lo cual establecer un valor no quiere decir que la gráfica completa se actualizará tras ese número de días, solo algún componente lo hará. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular la gráfica distribución. Cuanto mayor sea, más tardará la gráfica en adaptarse a nuevas rutas -STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo de la gráfica de distribución -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo requerido en el cálculo de cada uno de los componentes de la gráfica de distribución. Cuanto menor sea este valor, más probable es que el juego sea más lento. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se produzcan cambios en las rutas STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasajeros: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de pasajeros de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en cualquier direccion. "Manual" significa que no se realiza una distribución automática para los pasajeros. diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 8d92544efc..223259f4fa 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Inga STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Initial stadsstorleks-multiplikator: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Storstäders genomsnittliga storlek i relation till vanliga städers vid spelets början -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Uppdatera distributionsgrafen var {STRING}:e{NBSP}dag -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Tid mellan efterföljande omräkningar av länkgrafen. Varje omräkning beräknar planerna för en komponent i grafen. Det medför att ett värde X för den här inställningen inte innebär att hela grafen uppdateras var X:e dag, utan bara vissa komponenter. Ju kortare intervall du ställer in desto mer processorkraft kommer att behövas för beräkningarna. Ju längre intervall du ställer in desto längre tid kommer det att ta innan distributionen av last börjar använda nya rutter. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Avsätt {STRING}{NBSP}dag{P 0:2 "" ar} för omberäkning av distributionsgraf -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Den tid varje omberäkning av en länkgrafkomponent tillåts ta. När en omberäkning startas skapas en tråd som tillåts löpa detta antal dagar. Ju kortare du sätter denna, desto mer troligt är det att tråden inte är hinner bli färdig i tid. Då kommer spelet att stanna tills den är klar (vilket gör att det laggar). Ju längre du sätter denna, desto längre tid tar det för distributionen att uppdateras när rutter ändras. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributionssätt för passagerare: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetriskt" innebär att ungefär samma antal passagerare färdas från station A till station B som från B till A. "Asymmetriskt" innebär att en godtycklig mängd passagerare kan färdas i vardera riktningen. "Manuellt" innebär att ingen automatisk distribution av passagerare sker. diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 9a3cd42ad0..73830d8c02 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -1790,10 +1790,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :ไม่มี STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :ตัวคูณขนาดเมืองเริ่มต้น: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ขนาดโดยเฉลี่ยของเมืองใหญ่ที่สัมพันธ์กับเมืองปกติ -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :อัพเดทกราฟการกระจายสินค้าทุกๆ {STRING} วัน -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :เวลาระหว่างการคำนวณหาเส้นทางการเชื่อมต่อของกราฟ. ทุกครั้งที่มีำการคำนวณใหม่ มีการวางแผนสำหรับหนึ่งชิ้นส่วนในกราฟ ค่าที่ตั้งไว้นี้ คือค่าที่จะให้มีการอัพเดททุกๆเวลากี่วัน การตั้งให้คำนวณถี่มากๆจะกินทรัพยากรเครื่องของท่าน -STR_CONFIG_SETTING_LINKGRAPH_TIME :ใช้เวลา {STRING} วัน{P 0:2 s} ในการคำนวนกราฟการกระจายสินค้า -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :เวลาในการคำนวณการกระจายสินค้าสู่จุดหมายต่างๆที่แสดงเป็นเส้นกราฟบนแผนที่ การตั้งค่าถี่เกินไปอาจก่อให้เกิดอาการ lag ได้ STR_CONFIG_SETTING_DISTRIBUTION_PAX :โหมตการกระจายสินค้าสำหรับผู้โดยสาร: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :ผู้โดยสารจากเมืองหนึ่งเมื่อเดินทางออกไปที่ใดก็ตาม จะต้องย้อนกลับเข้ามายังจุดเริ่มค้น การตั้งค่าเป็นแบบ "สมมาตร" จะทำให้เกิดวงจรปกติเหมือนกับการโดยสารของผู้โดยสาร diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 36ffe9cb30..b06170468a 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :無 STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初始城市規模倍率:{STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :設定遊戲開始時城市的大小 (相對於一般市鎮而言)。 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :每{STRING}日更新貨物分配圖 -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :指定每次計算貨物分配圖之間的時間。由於每次重新計算只會處理一個貨物分配圖元件,因此本設定不代表「每若干日重新計算整個貨物分配圖」。{}如果此設定賦值越小,則系統需要使用更多處理器時間計算貨物分配圖。相反,如果此設定賦值越大,則貨物被派往新路線所需的時間越長。 -STR_CONFIG_SETTING_LINKGRAPH_TIME :用 {STRING}{NBSP}天更新貨物分配圖 -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :當更新貨物分配圖時,系統會衍生一條執行緒。本設定的值即為執行緒的持續時間。{}這設定賦值越小,執行緒越有可能在應當停止的時候仍未完成運算,遊戲會暫停運行至執行緒完成工作。相反,這設定賦值越大,則貨物分配功能需要較長時間反映路線網絡變動的影響。 STR_CONFIG_SETTING_DISTRIBUTION_PAX :乘客分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :設使有交通路線連接甲、乙兩站。「對稱」指甲站往乙站的乘客數量與乙站往甲站的乘客數量大致相同。「不對稱」指任何一站往另一站的乘客數量皆由系統隨意決定。「手動」指系統不會自動分配乘客的目的地。 diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 23fd6a0a2c..6265117af5 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -1924,10 +1924,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Hiçbiri STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Birincil şehir büyüklüğü çarpanı: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Oyun başlangıcında şehirlerin normal kasabalara kıyasla ortalama büyüklüğü -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Dağıtım grafiğini her {STRING}{NBSP}günde bir güncelle -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Bağlantı grafiğinin tekrar hesaplamaları arasında geçen süre. Her tekrar hesaplama grafiğin öğelerinden biri için planları hesaplar. Yani bu ayar için girdiğiniz X değeri tüm grafiğin her X günde bir güncelleneceği manasına gelmez; sadece grafiğin öğelerinden biri güncellenir. Daha kısa sürelere ayarladıkça hesaplamalar için daha fazla işlemci süresi gerekir. Daha uzun süreler seçtikçe yeni güzergahlardaki kargo dağıtımının başlaması da daha uzun sürer. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Dağıtım grafiğini {STRING}{NBSP}güne göre tekrar hesapla -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Bağlantı grafiğini oluşturan parçaların her tekrar hesaplaması için kullanılan zaman. Tekrar hesaplama başlatıldığında bu kadar gün sürecek bir işlem başlatılmış olur. Buraya daha kısa süreler girdikçe işlemin bitmesi gerekirken bitmemiş olma ihtimali artar. Ardından oyun ("lag") olana dek durur. Daha uzun süreler girdiğinizde güzergahlar değiştikçe dağıtımın güncellenmesi daha uzun sürer. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Yolcular için dağıtım kipi: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetrik" seçildiğinde A durağından B durağına taşınan ile B'den A'ya taşınan yolcu miktarı kabaca eşit olur. "Asimetrik" seçildiğinde iki yönde de rastgele miktarda yolcu gönderilebilir. "el ile" seçildiğinde yolcular için otomatik dağıtım yapılmaz. diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index e009e73b6c..be0d09713e 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -2049,10 +2049,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Жодного STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Множник розміру мегаполісів: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Середньостатистичне відношення початкового розміру мегаполісів порівняно зі звичайними містами. -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Оновлювати графік доставки раз на {STRING}{NBSP}д{P 0:2 "ень" "ні" "нів"} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Час між послідовними обрахунками зв'язків на графіку. Кожен обрахунок здійснюється для одного параметра графіку. Тобто значення Х у налаштуваннях не означає, що графік оновлюється кожні Х днів. Лише деякі складові. При виборі параметру "часто" ЦП потрібно більше часу для обрахунку. При виборі параметру "рідко" наступний обрахунок почнеться після запуску доставки за новим маршрутом. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Обраховувати графік доставки раз на {STRING}{NBSP}д{P 0:2 "ень" "ні" "нів"} -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Час, який займає переобчислення кожного зв'язку з компонентом графу. При запуску переобчислення створюється потік, якому дозволяється працювати декілька днів. Чим менше ви поставите це, тим більш можливо, що потік не буде завершено вчасно. Тоді гра зупиниться на час "лагу". Чим довше ви поставите, тим довше займе розподіл доставки при зміні маршрутів. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Режим розподілу для пасажирів: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :В "симетричному" режимі від станції A до станції B відправлятиметься приблизно стільки ж пасажирів, як від B до A. В "асиметричному" режимі дозволяється відправляти довільну кількість пасажирів в обох напрямках. Ручний режим означає, що розподіл пасажирів не здійснюватиметься автоматично. diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 6d10b93186..d8d9815f25 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -1923,10 +1923,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Không STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Hệ số quy mô đô thị coi là thành phố: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Kích thước trung bình của thành phố tỉ lệ với đô thị lúc bắt đầu trò chơi -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Cập nhật đồ thị phân phối mỗi {STRING}{NBSP}ngày -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Thời gian giữa các lần tính toán đồ thị. Mỗi lần tính sẽ tính một phần của đồ thị. Nhưng không có nghĩa là giá trị X này sẽ khiến việc tính toán toàn bộ xảy ra sau X ngày, chỉ có một phần thôi. Nếu nhỏ thì CPU cần để tính sẽ nhiều hơn, lớn thì việc tính toán lại phân phối hàng hóa mỗi khi có đường mới sẽ chậm hơn. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Dùng {STRING}{NBSP}ngày để tính toán lại đồ thị phân phối -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Thời gian cần thiết cho mỗi bước tính toán đồ thị liên kết. Mỗi khi bắt đầu, chương trình tính toán sẽ được phép chạy trong một số ngày nào đó tùy theo giá trị này. Nếu quá ít có thể không đủ để tính toán, mà nếu quá nhiều thì nó sẽ kéo dài việc tính toán lại phân phối mỗi khi đường đi thay đổi. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Chế độ phân phối đối với hành khách: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Đối xứng" có nghĩa là số lượng hành khách đi từ nhà ga A đến nhà ga B và từ B đến A sẽ tương đương nhau . "Không đối xứng" có nghĩa là số lượng hành khách tùy ý có thể đi theo một trong hai hướng. "Thủ công" có nghĩa là hành khách sẽ không được phân phối tự động. diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 2af9336b26..603f1058bd 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -1767,10 +1767,6 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Dim STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Lluosydd cychwynol maint dinas: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Maint cymhedrol dinasoedd o gymharu â threfi arferol ar ddechrau'r gêm -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Diweddaru'r graff dosraniad bob {STRING}{NBSP}diwrnod -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Amser rhwng pob ailgifrifiad o'r graff cyswllt. Bydd pob ailgyfrifiad yn cyfrifio'r cynllun ar gyfer un cydran o'r graff. O ganlyn ni fydd dwis gwerth o X yn golygu y bydd y graff cyfan yn cael ei ddiweddaru bob X diwrnod, ond y bydd rhai cydrannau. Bydd ystod byr yn defnyddio mwy o amser y prosesydd yn ailgyfrio graffiau. Bydd ystor hir yn cynyddu'r amser cyn y daw'r dosraniad i ryn ar lwybrau newydd. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Cymryd {STRING}{NBSP}diwrnod ar gyfer ar gyfer ailgyfrifo graff dosraniad -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Yr amser ar gyfer ailgyfrifo pob cydran o raff cyswllt. Pan y dechreuir ailgyfrifo, fe grëir llinyn gwaith a gaiff redeg am nifer penodol o ddiwrnodau. Bydd gosodiad byr yn ei gwneud yn fwy tebygol na fydd y llinyn wedi gorffen mewn pryd. Yna bydd y gêm yn oedi new y bydd yn barod. Bydd gosodiad hir yn cynyddu'r amser y cymerir i'r dosranaid gael ei ddiweddaru pan fo llwybrau'n newid. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Dull dosrannu ar gyfer teithwyr: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Mae "cymesur" yn golygu y bydd tua'r un faint o deithwyr yn mynd o orsaf A i orsaf B ac yr aiff o B i A. Mae "anghymesur" yn golygu y gall niferoedd mympwyol fynd yn y naill cyfeiriad neu'r llall. Mae "â llaw" yn golygu ni fydd dosrannu diofyn yn digwydd ar gyfer teithwyr. From bc44158f9a3667e5398f6a4c45780a6a9fe948be Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sun, 16 Apr 2023 03:05:04 -0400 Subject: [PATCH 09/48] Change: Allow overbuilding station and waypoint tiles (#10618) --- src/station_cmd.cpp | 12 ------------ src/waypoint_cmd.cpp | 9 +-------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index ce5fb8cb1e..478b08a0fe 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1263,7 +1263,6 @@ static void RestoreTrainReservation(Train *v) static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks) { CommandCost cost(EXPENSES_CONSTRUCTION); - bool success = false; bool length_price_ready = true; byte tracknum = 0; for (TileIndex cur_tile : tile_area) { @@ -1290,12 +1289,9 @@ static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag fl cost.AddCost(_price[PR_BUILD_STATION_RAIL_LENGTH]); length_price_ready = false; } - success = true; } } - if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT); - return cost; } @@ -1879,7 +1875,6 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio static CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlag flags, bool is_drive_through, bool is_truck_stop, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost) { CommandCost cost(EXPENSES_CONSTRUCTION); - bool success = false; /* Check every tile in the area. */ for (TileIndex cur_tile : tile_area) { uint invalid_dirs = 0; @@ -1898,16 +1893,9 @@ static CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlag flags if (!is_preexisting_roadstop) { cost.AddCost(ret); cost.AddCost(unit_cost); - success = true; - } else if (is_preexisting_roadstop && !is_drive_through) { - /* Allow rotating non-drive through stops for free */ - success = true; } - } - if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT); - return cost; } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 9793d63681..40402ef86b 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -195,15 +195,8 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis /* only AddCost for non-existing waypoints */ CommandCost cost(EXPENSES_CONSTRUCTION); - bool success = false; for (TileIndex cur_tile : new_location) { - if (!IsRailWaypointTile(cur_tile)) { - cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]); - success = true; - } - } - if (!success) { - return_cmd_error(STR_ERROR_ALREADY_BUILT); + if (!IsRailWaypointTile(cur_tile)) cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]); } /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */ From 15e6fc4eeb43bc87981cd00837ada9c574853b75 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 9 Apr 2023 22:32:01 +0100 Subject: [PATCH 10/48] Codechange: Use iterator when mapping sprite groups. --- src/newgrf.cpp | 98 ++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index d295e6e8ae..61ee1ddcc2 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5689,9 +5689,7 @@ static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - CanalFeature cf = cfs[i]; - + for (auto &cf : cfs) { if (cf >= CF_END) { grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf); continue; @@ -5725,11 +5723,11 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) ctype = TranslateCargo(GSF_STATIONS, ctype); if (ctype == CT_INVALID) continue; - for (uint i = 0; i < idcount; i++) { - StationSpec *statspec = stations[i] >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[stations[i]]; + for (auto &station : stations) { + StationSpec *statspec = station >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[station]; if (statspec == nullptr) { - grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]); + grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); continue; } @@ -5740,22 +5738,22 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - StationSpec *statspec = stations[i] >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[stations[i]]; + for (auto &station : stations) { + StationSpec *statspec = station >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[station]; if (statspec == nullptr) { - grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]); + grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); continue; } if (statspec->grf_prop.grffile != nullptr) { - grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]); + grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", station); continue; } statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid]; statspec->grf_prop.grffile = _cur.grffile; - statspec->grf_prop.local_id = stations[i]; + statspec->grf_prop.local_id = station; StationClass::Assign(statspec); } } @@ -5781,11 +5779,11 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - HouseSpec *hs = houses[i] >= NUM_HOUSES_PER_GRF ? nullptr : _cur.grffile->housespec[houses[i]]; + for (auto &house : houses) { + HouseSpec *hs = house >= NUM_HOUSES_PER_GRF ? nullptr : _cur.grffile->housespec[house]; if (hs == nullptr) { - grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]); + grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", house); continue; } @@ -5813,11 +5811,11 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - IndustrySpec *indsp = industries[i] >= NUM_INDUSTRYTYPES_PER_GRF ? nullptr : _cur.grffile->industryspec[industries[i]]; + for (auto &industry : industries) { + IndustrySpec *indsp = industry >= NUM_INDUSTRYTYPES_PER_GRF ? nullptr : _cur.grffile->industryspec[industry]; if (indsp == nullptr) { - grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]); + grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industry); continue; } @@ -5845,11 +5843,11 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - IndustryTileSpec *indtsp = indtiles[i] >= NUM_INDUSTRYTILES_PER_GRF ? nullptr : _cur.grffile->indtspec[indtiles[i]]; + for (auto &indtile : indtiles) { + IndustryTileSpec *indtsp = indtile >= NUM_INDUSTRYTILES_PER_GRF ? nullptr : _cur.grffile->indtspec[indtile]; if (indtsp == nullptr) { - grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]); + grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtile); continue; } @@ -5872,9 +5870,7 @@ static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - CargoID cid = cargoes[i]; - + for (auto &cid : cargoes) { if (cid >= NUM_CARGO) { grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid); continue; @@ -5908,11 +5904,11 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) ctype = TranslateCargo(GSF_OBJECTS, ctype); if (ctype == CT_INVALID) continue; - for (uint i = 0; i < idcount; i++) { - ObjectSpec *spec = objects[i] >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[objects[i]]; + for (auto &object : objects) { + ObjectSpec *spec = object >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[object]; if (spec == nullptr) { - grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]); + grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); continue; } @@ -5923,22 +5919,22 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - ObjectSpec *spec = objects[i] >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[objects[i]]; + for (auto &object : objects) { + ObjectSpec *spec = object >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[object]; if (spec == nullptr) { - grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]); + grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); continue; } if (spec->grf_prop.grffile != nullptr) { - grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]); + grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", object); continue; } spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid]; spec->grf_prop.grffile = _cur.grffile; - spec->grf_prop.local_id = objects[i]; + spec->grf_prop.local_id = object; } } @@ -5960,9 +5956,9 @@ static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype >= RTSG_END) continue; extern RailtypeInfo _railtypes[RAILTYPE_END]; - for (uint i = 0; i < idcount; i++) { - if (railtypes[i] != INVALID_RAILTYPE) { - RailtypeInfo *rti = &_railtypes[railtypes[i]]; + for (auto &railtype : railtypes) { + if (railtype != INVALID_RAILTYPE) { + RailtypeInfo *rti = &_railtypes[railtype]; rti->grffile[ctype] = _cur.grffile; rti->group[ctype] = _cur.spritegroups[groupid]; @@ -5994,9 +5990,9 @@ static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType if (ctype >= ROTSG_END) continue; extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - for (uint i = 0; i < idcount; i++) { - if (roadtypes[i] != INVALID_ROADTYPE) { - RoadTypeInfo *rti = &_roadtypes[roadtypes[i]]; + for (auto &roadtype : roadtypes) { + if (roadtype != INVALID_ROADTYPE) { + RoadTypeInfo *rti = &_roadtypes[roadtype]; rti->grffile[ctype] = _cur.grffile; rti->group[ctype] = _cur.spritegroups[groupid]; @@ -6028,11 +6024,11 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - AirportSpec *as = airports[i] >= NUM_AIRPORTS_PER_GRF ? nullptr : _cur.grffile->airportspec[airports[i]]; + for (auto &airport : airports) { + AirportSpec *as = airport >= NUM_AIRPORTS_PER_GRF ? nullptr : _cur.grffile->airportspec[airport]; if (as == nullptr) { - grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]); + grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airport); continue; } @@ -6060,11 +6056,11 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - AirportTileSpec *airtsp = airptiles[i] >= NUM_AIRPORTTILES_PER_GRF ? nullptr : _cur.grffile->airtspec[airptiles[i]]; + for (auto &airptile : airptiles) { + AirportTileSpec *airtsp = airptile >= NUM_AIRPORTTILES_PER_GRF ? nullptr : _cur.grffile->airtspec[airptile]; if (airtsp == nullptr) { - grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]); + grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptile); continue; } @@ -6094,11 +6090,11 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) ctype = TranslateCargo(GSF_ROADSTOPS, ctype); if (ctype == CT_INVALID) continue; - for (uint i = 0; i < idcount; i++) { - RoadStopSpec *roadstopspec = roadstops[i] >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + for (auto &roadstop : roadstops) { + RoadStopSpec *roadstopspec = roadstop >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstop]; if (roadstopspec == nullptr) { - grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstops[i]); + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstop); continue; } @@ -6109,22 +6105,22 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return; - for (uint i = 0; i < idcount; i++) { - RoadStopSpec *roadstopspec = roadstops[i] >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + for (auto &roadstop : roadstops) { + RoadStopSpec *roadstopspec = roadstop >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstop]; if (roadstopspec == nullptr) { - grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstops[i]); + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstop); continue; } if (roadstopspec->grf_prop.grffile != nullptr) { - grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X mapped multiple times, skipping", roadstops[i]); + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X mapped multiple times, skipping", roadstop); continue; } roadstopspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid]; roadstopspec->grf_prop.grffile = _cur.grffile; - roadstopspec->grf_prop.local_id = roadstops[i]; + roadstopspec->grf_prop.local_id = roadstop; RoadStopClass::Assign(roadstopspec); } } From ef6b3074652056b05885bc44f7eb6ad55c5f9189 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 8 Jan 2023 02:12:33 +0000 Subject: [PATCH 11/48] Change: Use std::vector for NewGRF spec tables. Pointer space is allocated only for the number of IDs used, instead of the max number of IDs for each feature. --- src/newgrf.cpp | 289 +++++++++++++++++++------------------------------ src/newgrf.h | 16 +-- 2 files changed, 117 insertions(+), 188 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 61ee1ddcc2..7a2b1c6960 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1922,7 +1922,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte } /* Allocate station specs if necessary */ - if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT(NUM_STATIONS_PER_GRF); + if (_cur.grffile->stations.size() < stid + numinfo) _cur.grffile->stations.resize(stid + numinfo); for (int i = 0; i < numinfo; i++) { StationSpec *statspec = _cur.grffile->stations[stid + i]; @@ -1998,7 +1998,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte case 0x0A: { // Copy sprite layout byte srcid = buf->ReadByte(); - const StationSpec *srcstatspec = srcid >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[srcid]; + const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid]; if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i); @@ -2052,7 +2052,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte case 0x0F: { // Copy custom layout byte srcid = buf->ReadByte(); - const StationSpec *srcstatspec = srcid >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[srcid]; + const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid]; if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i); @@ -2367,9 +2367,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt } /* Allocate house specs if they haven't been allocated already. */ - if (_cur.grffile->housespec == nullptr) { - _cur.grffile->housespec = CallocT(NUM_HOUSES_PER_GRF); - } + if (_cur.grffile->housespec.size() < hid + numinfo) _cur.grffile->housespec.resize(hid + numinfo); for (int i = 0; i < numinfo; i++) { HouseSpec *housespec = _cur.grffile->housespec[hid + i]; @@ -3206,9 +3204,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr } /* Allocate industry tile specs if they haven't been allocated already. */ - if (_cur.grffile->indtspec == nullptr) { - _cur.grffile->indtspec = CallocT(NUM_INDUSTRYTILES_PER_GRF); - } + if (_cur.grffile->indtspec.size() < indtid + numinfo) _cur.grffile->indtspec.resize(indtid + numinfo); for (int i = 0; i < numinfo; i++) { IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i]; @@ -3467,9 +3463,7 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, } /* Allocate industry specs if they haven't been allocated already. */ - if (_cur.grffile->industryspec == nullptr) { - _cur.grffile->industryspec = CallocT(NUM_INDUSTRYTYPES_PER_GRF); - } + if (_cur.grffile->industryspec.size() < indid + numinfo) _cur.grffile->industryspec.resize(indid + numinfo); for (int i = 0; i < numinfo; i++) { IndustrySpec *indsp = _cur.grffile->industryspec[indid + i]; @@ -3876,9 +3870,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B } /* Allocate industry specs if they haven't been allocated already. */ - if (_cur.grffile->airportspec == nullptr) { - _cur.grffile->airportspec = CallocT(NUM_AIRPORTS_PER_GRF); - } + if (_cur.grffile->airportspec.size() < airport + numinfo) _cur.grffile->airportspec.resize(airport + numinfo); for (int i = 0; i < numinfo; i++) { AirportSpec *as = _cur.grffile->airportspec[airport + i]; @@ -4102,9 +4094,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea } /* Allocate object specs if they haven't been allocated already. */ - if (_cur.grffile->objectspec == nullptr) { - _cur.grffile->objectspec = CallocT(NUM_OBJECTS_PER_GRF); - } + if (_cur.grffile->objectspec.size() < id + numinfo) _cur.grffile->objectspec.resize(id + numinfo); for (int i = 0; i < numinfo; i++) { ObjectSpec *spec = _cur.grffile->objectspec[id + i]; @@ -4667,9 +4657,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro } /* Allocate airport tile specs if they haven't been allocated already. */ - if (_cur.grffile->airtspec == nullptr) { - _cur.grffile->airtspec = CallocT(NUM_AIRPORTTILES_PER_GRF); - } + if (_cur.grffile->airtspec.size() < airtid + numinfo) _cur.grffile->airtspec.resize(airtid + numinfo); for (int i = 0; i < numinfo; i++) { AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i]; @@ -4796,7 +4784,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteR return CIR_INVALID_ID; } - if (_cur.grffile->roadstops == nullptr) _cur.grffile->roadstops = CallocT(NUM_ROADSTOPS_PER_GRF); + if (_cur.grffile->roadstops.size() < id + numinfo) _cur.grffile->roadstops.resize(id + numinfo); for (int i = 0; i < numinfo; i++) { RoadStopSpec *rs = _cur.grffile->roadstops[id + i]; @@ -5703,7 +5691,7 @@ static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount) static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->stations == nullptr) { + if (_cur.grffile->stations.empty()) { grfmsg(1, "StationMapSpriteGroup: No stations defined, skipping"); return; } @@ -5724,7 +5712,7 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &station : stations) { - StationSpec *statspec = station >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[station]; + StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station]; if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); @@ -5739,7 +5727,7 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return; for (auto &station : stations) { - StationSpec *statspec = station >= NUM_STATIONS_PER_GRF ? nullptr : _cur.grffile->stations[station]; + StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station]; if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); @@ -5761,7 +5749,7 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->housespec == nullptr) { + if (_cur.grffile->housespec.empty()) { grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping"); return; } @@ -5780,7 +5768,7 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return; for (auto &house : houses) { - HouseSpec *hs = house >= NUM_HOUSES_PER_GRF ? nullptr : _cur.grffile->housespec[house]; + HouseSpec *hs = house >= _cur.grffile->housespec.size() ? nullptr : _cur.grffile->housespec[house]; if (hs == nullptr) { grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", house); @@ -5793,7 +5781,7 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->industryspec == nullptr) { + if (_cur.grffile->industryspec.empty()) { grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping"); return; } @@ -5812,7 +5800,7 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return; for (auto &industry : industries) { - IndustrySpec *indsp = industry >= NUM_INDUSTRYTYPES_PER_GRF ? nullptr : _cur.grffile->industryspec[industry]; + IndustrySpec *indsp = industry >= _cur.grffile->industryspec.size() ? nullptr : _cur.grffile->industryspec[industry]; if (indsp == nullptr) { grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industry); @@ -5825,7 +5813,7 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->indtspec == nullptr) { + if (_cur.grffile->indtspec.empty()) { grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping"); return; } @@ -5844,7 +5832,7 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return; for (auto &indtile : indtiles) { - IndustryTileSpec *indtsp = indtile >= NUM_INDUSTRYTILES_PER_GRF ? nullptr : _cur.grffile->indtspec[indtile]; + IndustryTileSpec *indtsp = indtile >= _cur.grffile->indtspec.size() ? nullptr : _cur.grffile->indtspec[indtile]; if (indtsp == nullptr) { grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtile); @@ -5884,7 +5872,7 @@ static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount) static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->objectspec == nullptr) { + if (_cur.grffile->objectspec.empty()) { grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping"); return; } @@ -5905,7 +5893,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &object : objects) { - ObjectSpec *spec = object >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[object]; + ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object]; if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); @@ -5920,7 +5908,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return; for (auto &object : objects) { - ObjectSpec *spec = object >= NUM_OBJECTS_PER_GRF ? nullptr : _cur.grffile->objectspec[object]; + ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object]; if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); @@ -6006,7 +5994,7 @@ static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->airportspec == nullptr) { + if (_cur.grffile->airportspec.empty()) { grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping"); return; } @@ -6025,7 +6013,7 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return; for (auto &airport : airports) { - AirportSpec *as = airport >= NUM_AIRPORTS_PER_GRF ? nullptr : _cur.grffile->airportspec[airport]; + AirportSpec *as = airport >= _cur.grffile->airportspec.size() ? nullptr : _cur.grffile->airportspec[airport]; if (as == nullptr) { grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airport); @@ -6038,7 +6026,7 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->airtspec == nullptr) { + if (_cur.grffile->airtspec.empty()) { grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping"); return; } @@ -6057,7 +6045,7 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return; for (auto &airptile : airptiles) { - AirportTileSpec *airtsp = airptile >= NUM_AIRPORTTILES_PER_GRF ? nullptr : _cur.grffile->airtspec[airptile]; + AirportTileSpec *airtsp = airptile >= _cur.grffile->airtspec.size() ? nullptr : _cur.grffile->airtspec[airptile]; if (airtsp == nullptr) { grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptile); @@ -6070,7 +6058,7 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->roadstops == nullptr) { + if (_cur.grffile->roadstops.empty()) { grfmsg(1, "RoadStopMapSpriteGroup: No roadstops defined, skipping"); return; } @@ -6091,7 +6079,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &roadstop : roadstops) { - RoadStopSpec *roadstopspec = roadstop >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstop]; + RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop]; if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstop); @@ -6106,7 +6094,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return; for (auto &roadstop : roadstops) { - RoadStopSpec *roadstopspec = roadstop >= NUM_ROADSTOPS_PER_GRF ? nullptr : _cur.grffile->roadstops[roadstop]; + RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop]; if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstop); @@ -6307,7 +6295,7 @@ static void FeatureNewName(ByteReader *buf) switch (GB(id, 8, 8)) { case 0xC4: // Station class name - if (GB(id, 0, 8) >= NUM_STATIONS_PER_GRF || _cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { + if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); } else { StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id; @@ -6316,7 +6304,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC5: // Station name - if (GB(id, 0, 8) >= NUM_STATIONS_PER_GRF || _cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { + if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); } else { _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -6324,7 +6312,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC7: // Airporttile name - if (GB(id, 0, 8) >= NUM_AIRPORTTILES_PER_GRF || _cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) { + if (GB(id, 0, 8) >= _cur.grffile->airtspec.size() || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8)); } else { _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -6332,7 +6320,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC9: // House name - if (GB(id, 0, 8) >= NUM_HOUSES_PER_GRF || _cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) { + if (GB(id, 0, 8) >= _cur.grffile->housespec.size() || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8)); } else { _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -8694,19 +8682,11 @@ static void InitializeGRFSpecial() static void ResetCustomStations() { for (GRFFile * const file : _grf_files) { - StationSpec **&stations = file->stations; - if (stations == nullptr) continue; - for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) { - if (stations[i] == nullptr) continue; - StationSpec *statspec = stations[i]; - - /* Release this station */ + for (auto statspec : file->stations) { delete statspec; } - /* Free and reset the station data */ - free(stations); - stations = nullptr; + file->stations.clear(); } } @@ -8714,14 +8694,10 @@ static void ResetCustomStations() static void ResetCustomHouses() { for (GRFFile * const file : _grf_files) { - HouseSpec **&housespec = file->housespec; - if (housespec == nullptr) continue; - for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) { - free(housespec[i]); + for (auto housespec : file->housespec) { + free(housespec); } - - free(housespec); - housespec = nullptr; + file->housespec.clear(); } } @@ -8729,36 +8705,26 @@ static void ResetCustomHouses() static void ResetCustomAirports() { for (GRFFile * const file : _grf_files) { - AirportSpec **aslist = file->airportspec; - if (aslist != nullptr) { - for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) { - AirportSpec *as = aslist[i]; - - if (as != nullptr) { - /* We need to remove the tiles layouts */ - for (int j = 0; j < as->num_table; j++) { - /* remove the individual layouts */ - free(as->table[j]); - } - free(as->table); - free(as->depot_table); - free(as->rotation); - - free(as); + for (auto as : file->airportspec) { + if (as != nullptr) { + /* We need to remove the tiles layouts */ + for (int j = 0; j < as->num_table; j++) { + /* remove the individual layouts */ + free(as->table[j]); } - } - free(aslist); - file->airportspec = nullptr; - } + free(as->table); + free(as->depot_table); + free(as->rotation); - AirportTileSpec **&airporttilespec = file->airtspec; - if (airporttilespec != nullptr) { - for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) { - free(airporttilespec[i]); + free(as); } - free(airporttilespec); - airporttilespec = nullptr; } + file->airportspec.clear(); + + for (auto ats : file->airtspec) { + free(ats); + } + file->airtspec.clear(); } } @@ -8766,28 +8732,17 @@ static void ResetCustomAirports() static void ResetCustomIndustries() { for (GRFFile * const file : _grf_files) { - IndustrySpec **&industryspec = file->industryspec; - IndustryTileSpec **&indtspec = file->indtspec; - /* We are verifiying both tiles and industries specs loaded from the grf file * First, let's deal with industryspec */ - if (industryspec != nullptr) { - for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) { - IndustrySpec *ind = industryspec[i]; - delete ind; - } - - free(industryspec); - industryspec = nullptr; + for (auto indsp : file->industryspec) { + delete indsp; } + file->industryspec.clear(); - if (indtspec == nullptr) continue; - for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) { - free(indtspec[i]); + for (auto indtsp : file->indtspec) { + free(indtsp); } - - free(indtspec); - indtspec = nullptr; + file->indtspec.clear(); } } @@ -8795,28 +8750,20 @@ static void ResetCustomIndustries() static void ResetCustomObjects() { for (GRFFile * const file : _grf_files) { - ObjectSpec **&objectspec = file->objectspec; - if (objectspec == nullptr) continue; - for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - free(objectspec[i]); + for (auto objectspec : file->objectspec) { + free(objectspec); } - - free(objectspec); - objectspec = nullptr; + file->objectspec.clear(); } } static void ResetCustomRoadStops() { for (auto file : _grf_files) { - RoadStopSpec **&roadstopspec = file->roadstops; - if (roadstopspec == nullptr) continue; - for (uint i = 0; i < NUM_ROADSTOPS_PER_GRF; i++) { - free(roadstopspec[i]); + for (auto roadstopspec : file->roadstops) { + free(roadstopspec); } - - free(roadstopspec); - roadstopspec = nullptr; + file->roadstops.clear(); } } @@ -9389,17 +9336,17 @@ static void FinaliseHouseArray() * minimum introduction date to 0. */ for (GRFFile * const file : _grf_files) { - HouseSpec **&housespec = file->housespec; - if (housespec == nullptr) continue; + if (file->housespec.empty()) continue; - for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) { - HouseSpec *hs = housespec[i]; + size_t num_houses = file->housespec.size(); + for (size_t i = 0; i < num_houses; i++) { + HouseSpec *hs = file->housespec[i]; if (hs == nullptr) continue; - const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr); - const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr); - const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr); + const HouseSpec *next1 = (i + 1 < num_houses ? file->housespec[i + 1] : nullptr); + const HouseSpec *next2 = (i + 2 < num_houses ? file->housespec[i + 2] : nullptr); + const HouseSpec *next3 = (i + 3 < num_houses ? file->housespec[i + 3] : nullptr); if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue; @@ -9407,7 +9354,7 @@ static void FinaliseHouseArray() } } - for (int i = 0; i < NUM_HOUSES; i++) { + for (size_t i = 0; i < NUM_HOUSES; i++) { HouseSpec *hs = HouseSpec::Get(i); const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr); const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr); @@ -9451,50 +9398,41 @@ static void FinaliseHouseArray() static void FinaliseIndustriesArray() { for (GRFFile * const file : _grf_files) { - IndustrySpec **&industryspec = file->industryspec; - IndustryTileSpec **&indtspec = file->indtspec; - if (industryspec != nullptr) { - for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) { - IndustrySpec *indsp = industryspec[i]; + for (auto indsp : file->industryspec) { + if (indsp == nullptr || !indsp->enabled) continue; - if (indsp != nullptr && indsp->enabled) { - StringID strid; - /* process the conversion of text at the end, so to be sure everything will be fine - * and available. Check if it does not return undefind marker, which is a very good sign of a - * substitute industry who has not changed the string been examined, thus using it as such */ - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name); - if (strid != STR_UNDEFINED) indsp->name = strid; + StringID strid; + /* process the conversion of text at the end, so to be sure everything will be fine + * and available. Check if it does not return undefind marker, which is a very good sign of a + * substitute industry who has not changed the string been examined, thus using it as such */ + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name); + if (strid != STR_UNDEFINED) indsp->name = strid; - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text); - if (strid != STR_UNDEFINED) indsp->closure_text = strid; + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text); + if (strid != STR_UNDEFINED) indsp->closure_text = strid; - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text); - if (strid != STR_UNDEFINED) indsp->production_up_text = strid; + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text); + if (strid != STR_UNDEFINED) indsp->production_up_text = strid; - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text); - if (strid != STR_UNDEFINED) indsp->production_down_text = strid; + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text); + if (strid != STR_UNDEFINED) indsp->production_down_text = strid; - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text); - if (strid != STR_UNDEFINED) indsp->new_industry_text = strid; + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text); + if (strid != STR_UNDEFINED) indsp->new_industry_text = strid; - if (indsp->station_name != STR_NULL) { - /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the - * station's name. Don't want to lose the value, therefore, do not process. */ - strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name); - if (strid != STR_UNDEFINED) indsp->station_name = strid; - } - - _industry_mngr.SetEntitySpec(indsp); - } + if (indsp->station_name != STR_NULL) { + /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the + * station's name. Don't want to lose the value, therefore, do not process. */ + strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name); + if (strid != STR_UNDEFINED) indsp->station_name = strid; } + + _industry_mngr.SetEntitySpec(indsp); } - if (indtspec != nullptr) { - for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) { - IndustryTileSpec *indtsp = indtspec[i]; - if (indtsp != nullptr) { - _industile_mngr.SetEntitySpec(indtsp); - } + for (auto indtsp : file->indtspec) { + if (indtsp != nullptr) { + _industile_mngr.SetEntitySpec(indtsp); } } } @@ -9520,12 +9458,9 @@ static void FinaliseIndustriesArray() static void FinaliseObjectsArray() { for (GRFFile * const file : _grf_files) { - ObjectSpec **&objectspec = file->objectspec; - if (objectspec != nullptr) { - for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->IsEnabled()) { - _object_mngr.SetEntitySpec(objectspec[i]); - } + for (auto objectspec : file->objectspec) { + if (objectspec != nullptr && objectspec->grf_prop.grffile != nullptr && objectspec->IsEnabled()) { + _object_mngr.SetEntitySpec(objectspec); } } } @@ -9541,21 +9476,15 @@ static void FinaliseObjectsArray() static void FinaliseAirportsArray() { for (GRFFile * const file : _grf_files) { - AirportSpec **&airportspec = file->airportspec; - if (airportspec != nullptr) { - for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) { - if (airportspec[i] != nullptr && airportspec[i]->enabled) { - _airport_mngr.SetEntitySpec(airportspec[i]); - } + for (auto as : file->airportspec) { + if (as != nullptr && as->enabled) { + _airport_mngr.SetEntitySpec(as); } } - AirportTileSpec **&airporttilespec = file->airtspec; - if (airporttilespec != nullptr) { - for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) { - if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) { - _airporttile_mngr.SetEntitySpec(airporttilespec[i]); - } + for (auto ats : file->airtspec) { + if (ats != nullptr && ats->enabled) { + _airporttile_mngr.SetEntitySpec(ats); } } } diff --git a/src/newgrf.h b/src/newgrf.h index 7561fb145b..3627a7d9c5 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -112,14 +112,14 @@ struct GRFFile : ZeroedMemoryAllocator { uint sound_offset; uint16 num_sounds; - struct StationSpec **stations; - struct HouseSpec **housespec; - struct IndustrySpec **industryspec; - struct IndustryTileSpec **indtspec; - struct ObjectSpec **objectspec; - struct AirportSpec **airportspec; - struct AirportTileSpec **airtspec; - struct RoadStopSpec **roadstops; + std::vector stations; + std::vector housespec; + std::vector industryspec; + std::vector indtspec; + std::vector objectspec; + std::vector airportspec; + std::vector airtspec; + std::vector roadstops; uint32 param[0x80]; uint param_end; ///< one more than the highest set parameter From 7b0797d1cd11cc659d6ab68fb8da32c26ec6cac6 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 15 Apr 2023 21:30:37 +0100 Subject: [PATCH 12/48] Codechange: Use unique ptrs for NewGRF specs. --- src/newgrf.cpp | 183 +++++++++++++++++++------------------------------ src/newgrf.h | 16 ++--- 2 files changed, 77 insertions(+), 122 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 7a2b1c6960..fd8b80cd5c 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1925,7 +1925,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte if (_cur.grffile->stations.size() < stid + numinfo) _cur.grffile->stations.resize(stid + numinfo); for (int i = 0; i < numinfo; i++) { - StationSpec *statspec = _cur.grffile->stations[stid + i]; + StationSpec *statspec = _cur.grffile->stations[stid + i].get(); /* Check that the station we are modifying is defined. */ if (statspec == nullptr && prop != 0x08) { @@ -1935,14 +1935,15 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte switch (prop) { case 0x08: { // Class ID - StationSpec **spec = &_cur.grffile->stations[stid + i]; - /* Property 0x08 is special; it is where the station is allocated */ - if (*spec == nullptr) *spec = new StationSpec(); + if (statspec == nullptr) { + _cur.grffile->stations[stid + i] = std::make_unique(); + statspec = _cur.grffile->stations[stid + i].get(); + } /* Swap classid because we read it in BE meaning WAYP or DFLT */ uint32 classid = buf->ReadDWord(); - (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid)); + statspec->cls_id = StationClass::Allocate(BSWAP32(classid)); break; } @@ -1998,7 +1999,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte case 0x0A: { // Copy sprite layout byte srcid = buf->ReadByte(); - const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid]; + const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid].get(); if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i); @@ -2052,7 +2053,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte case 0x0F: { // Copy custom layout byte srcid = buf->ReadByte(); - const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid]; + const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid].get(); if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i); @@ -2370,7 +2371,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt if (_cur.grffile->housespec.size() < hid + numinfo) _cur.grffile->housespec.resize(hid + numinfo); for (int i = 0; i < numinfo; i++) { - HouseSpec *housespec = _cur.grffile->housespec[hid + i]; + HouseSpec *housespec = _cur.grffile->housespec[hid + i].get(); if (prop != 0x08 && housespec == nullptr) { /* If the house property 08 is not yet set, ignore this property */ @@ -2381,13 +2382,11 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt switch (prop) { case 0x08: { // Substitute building type, and definition of a new house - HouseSpec **house = &_cur.grffile->housespec[hid + i]; byte subs_id = buf->ReadByte(); - if (subs_id == 0xFF) { /* Instead of defining a new house, a substitute house id * of 0xFF disables the old house with the current id. */ - HouseSpec::Get(hid + i)->enabled = false; + if (hid + i < NEW_HOUSE_OFFSET) HouseSpec::Get(hid + i)->enabled = false; continue; } else if (subs_id >= NEW_HOUSE_OFFSET) { /* The substitute id must be one of the original houses. */ @@ -2396,11 +2395,10 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt } /* Allocate space for this house. */ - if (*house == nullptr) *house = CallocT(1); - - housespec = *house; - - MemCpyT(housespec, HouseSpec::Get(subs_id)); + if (housespec == nullptr) { + _cur.grffile->housespec[hid + i] = std::make_unique(*HouseSpec::Get(subs_id)); + housespec = _cur.grffile->housespec[hid + i].get(); + } housespec->enabled = true; housespec->grf_prop.local_id = hid + i; @@ -3207,7 +3205,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr if (_cur.grffile->indtspec.size() < indtid + numinfo) _cur.grffile->indtspec.resize(indtid + numinfo); for (int i = 0; i < numinfo; i++) { - IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i]; + IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i].get(); if (prop != 0x08 && tsp == nullptr) { ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf); @@ -3217,9 +3215,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr switch (prop) { case 0x08: { // Substitute industry tile type - IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i]; byte subs_id = buf->ReadByte(); - if (subs_id >= NEW_INDUSTRYTILEOFFSET) { /* The substitute id must be one of the original industry tile. */ grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i); @@ -3227,11 +3223,10 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr } /* Allocate space for this industry. */ - if (*tilespec == nullptr) { - *tilespec = CallocT(1); - tsp = *tilespec; + if (tsp == nullptr) { + _cur.grffile->indtspec[indtid + i] = std::make_unique(_industry_tile_specs[subs_id]); + tsp = _cur.grffile->indtspec[indtid + i].get(); - memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id])); tsp->enabled = true; /* A copied tile should not have the animation infos copied too. @@ -3466,7 +3461,7 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, if (_cur.grffile->industryspec.size() < indid + numinfo) _cur.grffile->industryspec.resize(indid + numinfo); for (int i = 0; i < numinfo; i++) { - IndustrySpec *indsp = _cur.grffile->industryspec[indid + i]; + IndustrySpec *indsp = _cur.grffile->industryspec[indid + i].get(); if (prop != 0x08 && indsp == nullptr) { ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf); @@ -3476,9 +3471,7 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, switch (prop) { case 0x08: { // Substitute industry type - IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i]; byte subs_id = buf->ReadByte(); - if (subs_id == 0xFF) { /* Instead of defining a new industry, a substitute industry id * of 0xFF disables the old industry with the current id. */ @@ -3493,11 +3486,10 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, /* Allocate space for this industry. * Only need to do it once. If ever it is called again, it should not * do anything */ - if (*indspec == nullptr) { - *indspec = new IndustrySpec; - indsp = *indspec; + if (indsp == nullptr) { + _cur.grffile->industryspec[indid + i] = std::make_unique(_origin_industry_specs[subs_id]); + indsp = _cur.grffile->industryspec[indid + i].get(); - *indsp = _origin_industry_specs[subs_id]; indsp->enabled = true; indsp->grf_prop.local_id = indid + i; indsp->grf_prop.subst_id = subs_id; @@ -3873,7 +3865,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B if (_cur.grffile->airportspec.size() < airport + numinfo) _cur.grffile->airportspec.resize(airport + numinfo); for (int i = 0; i < numinfo; i++) { - AirportSpec *as = _cur.grffile->airportspec[airport + i]; + AirportSpec *as = _cur.grffile->airportspec[airport + i].get(); if (as == nullptr && prop != 0x08 && prop != 0x09) { grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i); @@ -3883,7 +3875,6 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B switch (prop) { case 0x08: { // Modify original airport byte subs_id = buf->ReadByte(); - if (subs_id == 0xFF) { /* Instead of defining a new airport, an airport id * of 0xFF disables the old airport with the current id. */ @@ -3895,15 +3886,13 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B continue; } - AirportSpec **spec = &_cur.grffile->airportspec[airport + i]; /* Allocate space for this airport. * Only need to do it once. If ever it is called again, it should not * do anything */ - if (*spec == nullptr) { - *spec = MallocT(1); - as = *spec; + if (as == nullptr) { + _cur.grffile->airportspec[airport + i] = std::make_unique(*AirportSpec::GetWithoutOverride(subs_id)); + as = _cur.grffile->airportspec[airport + i].get(); - memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as)); as->enabled = true; as->grf_prop.local_id = airport + i; as->grf_prop.subst_id = subs_id; @@ -4097,7 +4086,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea if (_cur.grffile->objectspec.size() < id + numinfo) _cur.grffile->objectspec.resize(id + numinfo); for (int i = 0; i < numinfo; i++) { - ObjectSpec *spec = _cur.grffile->objectspec[id + i]; + ObjectSpec *spec = _cur.grffile->objectspec[id + i].get(); if (prop != 0x08 && spec == nullptr) { /* If the object property 08 is not yet set, ignore this property */ @@ -4108,18 +4097,17 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea switch (prop) { case 0x08: { // Class ID - ObjectSpec **ospec = &_cur.grffile->objectspec[id + i]; - /* Allocate space for this object. */ - if (*ospec == nullptr) { - *ospec = CallocT(1); - (*ospec)->views = 1; // Default for NewGRFs that don't set it. - (*ospec)->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1) + if (spec == nullptr) { + _cur.grffile->objectspec[id + i] = std::make_unique(); + spec = _cur.grffile->objectspec[id + i].get(); + spec->views = 1; // Default for NewGRFs that don't set it. + spec->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1) } /* Swap classid because we read it in BE. */ uint32 classid = buf->ReadDWord(); - (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid)); + spec->cls_id = ObjectClass::Allocate(BSWAP32(classid)); break; } @@ -4660,7 +4648,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro if (_cur.grffile->airtspec.size() < airtid + numinfo) _cur.grffile->airtspec.resize(airtid + numinfo); for (int i = 0; i < numinfo; i++) { - AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i]; + AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i].get(); if (prop != 0x08 && tsp == nullptr) { grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i); @@ -4669,9 +4657,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro switch (prop) { case 0x08: { // Substitute airport tile type - AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i]; byte subs_id = buf->ReadByte(); - if (subs_id >= NEW_AIRPORTTILE_OFFSET) { /* The substitute id must be one of the original airport tiles. */ grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i); @@ -4679,11 +4665,10 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro } /* Allocate space for this airport tile. */ - if (*tilespec == nullptr) { - *tilespec = CallocT(1); - tsp = *tilespec; + if (tsp == nullptr) { + _cur.grffile->airtspec[airtid + i] = std::make_unique(*AirportTileSpec::Get(subs_id)); + tsp = _cur.grffile->airtspec[airtid + i].get(); - memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec)); tsp->enabled = true; tsp->animation.status = ANIM_STATUS_NO_ANIMATION; @@ -4787,7 +4772,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteR if (_cur.grffile->roadstops.size() < id + numinfo) _cur.grffile->roadstops.resize(id + numinfo); for (int i = 0; i < numinfo; i++) { - RoadStopSpec *rs = _cur.grffile->roadstops[id + i]; + RoadStopSpec *rs = _cur.grffile->roadstops[id + i].get(); if (rs == nullptr && prop != 0x08) { grfmsg(1, "RoadStopChangeInfo: Attempt to modify undefined road stop %u, ignoring", id + i); @@ -4798,16 +4783,14 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteR switch (prop) { case 0x08: { // Road Stop Class ID - RoadStopSpec **spec = &_cur.grffile->roadstops[id + i]; - - if (*spec == nullptr) { - *spec = CallocT(1); - new (*spec) RoadStopSpec(); + if (rs == nullptr) { + _cur.grffile->roadstops[id + i] = std::make_unique(); + rs = _cur.grffile->roadstops[id + i].get(); } uint32 classid = buf->ReadDWord(); - (*spec)->cls_id = RoadStopClass::Allocate(BSWAP32(classid)); - (*spec)->spec_id = id + i; + rs->cls_id = RoadStopClass::Allocate(BSWAP32(classid)); + rs->spec_id = id + i; break; } @@ -5712,7 +5695,7 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &station : stations) { - StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station]; + StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station].get(); if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); @@ -5727,7 +5710,7 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return; for (auto &station : stations) { - StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station]; + StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station].get(); if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station); @@ -5768,7 +5751,7 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return; for (auto &house : houses) { - HouseSpec *hs = house >= _cur.grffile->housespec.size() ? nullptr : _cur.grffile->housespec[house]; + HouseSpec *hs = house >= _cur.grffile->housespec.size() ? nullptr : _cur.grffile->housespec[house].get(); if (hs == nullptr) { grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", house); @@ -5800,7 +5783,7 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return; for (auto &industry : industries) { - IndustrySpec *indsp = industry >= _cur.grffile->industryspec.size() ? nullptr : _cur.grffile->industryspec[industry]; + IndustrySpec *indsp = industry >= _cur.grffile->industryspec.size() ? nullptr : _cur.grffile->industryspec[industry].get(); if (indsp == nullptr) { grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industry); @@ -5832,7 +5815,7 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return; for (auto &indtile : indtiles) { - IndustryTileSpec *indtsp = indtile >= _cur.grffile->indtspec.size() ? nullptr : _cur.grffile->indtspec[indtile]; + IndustryTileSpec *indtsp = indtile >= _cur.grffile->indtspec.size() ? nullptr : _cur.grffile->indtspec[indtile].get(); if (indtsp == nullptr) { grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtile); @@ -5893,7 +5876,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &object : objects) { - ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object]; + ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get(); if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); @@ -5908,7 +5891,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return; for (auto &object : objects) { - ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object]; + ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get(); if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object); @@ -6013,7 +5996,7 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return; for (auto &airport : airports) { - AirportSpec *as = airport >= _cur.grffile->airportspec.size() ? nullptr : _cur.grffile->airportspec[airport]; + AirportSpec *as = airport >= _cur.grffile->airportspec.size() ? nullptr : _cur.grffile->airportspec[airport].get(); if (as == nullptr) { grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airport); @@ -6045,7 +6028,7 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return; for (auto &airptile : airptiles) { - AirportTileSpec *airtsp = airptile >= _cur.grffile->airtspec.size() ? nullptr : _cur.grffile->airtspec[airptile]; + AirportTileSpec *airtsp = airptile >= _cur.grffile->airtspec.size() ? nullptr : _cur.grffile->airtspec[airptile].get(); if (airtsp == nullptr) { grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptile); @@ -6079,7 +6062,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (auto &roadstop : roadstops) { - RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop]; + RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop].get(); if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstop); @@ -6094,7 +6077,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return; for (auto &roadstop : roadstops) { - RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop]; + RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop].get(); if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstop); @@ -8682,10 +8665,6 @@ static void InitializeGRFSpecial() static void ResetCustomStations() { for (GRFFile * const file : _grf_files) { - for (auto statspec : file->stations) { - delete statspec; - } - /* Free and reset the station data */ file->stations.clear(); } } @@ -8694,9 +8673,6 @@ static void ResetCustomStations() static void ResetCustomHouses() { for (GRFFile * const file : _grf_files) { - for (auto housespec : file->housespec) { - free(housespec); - } file->housespec.clear(); } } @@ -8705,7 +8681,7 @@ static void ResetCustomHouses() static void ResetCustomAirports() { for (GRFFile * const file : _grf_files) { - for (auto as : file->airportspec) { + for (auto &as : file->airportspec) { if (as != nullptr) { /* We need to remove the tiles layouts */ for (int j = 0; j < as->num_table; j++) { @@ -8715,15 +8691,9 @@ static void ResetCustomAirports() free(as->table); free(as->depot_table); free(as->rotation); - - free(as); } } file->airportspec.clear(); - - for (auto ats : file->airtspec) { - free(ats); - } file->airtspec.clear(); } } @@ -8732,16 +8702,7 @@ static void ResetCustomAirports() static void ResetCustomIndustries() { for (GRFFile * const file : _grf_files) { - /* We are verifiying both tiles and industries specs loaded from the grf file - * First, let's deal with industryspec */ - for (auto indsp : file->industryspec) { - delete indsp; - } file->industryspec.clear(); - - for (auto indtsp : file->indtspec) { - free(indtsp); - } file->indtspec.clear(); } } @@ -8750,9 +8711,6 @@ static void ResetCustomIndustries() static void ResetCustomObjects() { for (GRFFile * const file : _grf_files) { - for (auto objectspec : file->objectspec) { - free(objectspec); - } file->objectspec.clear(); } } @@ -8760,9 +8718,6 @@ static void ResetCustomObjects() static void ResetCustomRoadStops() { for (auto file : _grf_files) { - for (auto roadstopspec : file->roadstops) { - free(roadstopspec); - } file->roadstops.clear(); } } @@ -9340,13 +9295,13 @@ static void FinaliseHouseArray() size_t num_houses = file->housespec.size(); for (size_t i = 0; i < num_houses; i++) { - HouseSpec *hs = file->housespec[i]; + HouseSpec *hs = file->housespec[i].get(); if (hs == nullptr) continue; - const HouseSpec *next1 = (i + 1 < num_houses ? file->housespec[i + 1] : nullptr); - const HouseSpec *next2 = (i + 2 < num_houses ? file->housespec[i + 2] : nullptr); - const HouseSpec *next3 = (i + 3 < num_houses ? file->housespec[i + 3] : nullptr); + const HouseSpec *next1 = (i + 1 < num_houses ? file->housespec[i + 1].get() : nullptr); + const HouseSpec *next2 = (i + 2 < num_houses ? file->housespec[i + 2].get() : nullptr); + const HouseSpec *next3 = (i + 3 < num_houses ? file->housespec[i + 3].get() : nullptr); if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue; @@ -9398,7 +9353,7 @@ static void FinaliseHouseArray() static void FinaliseIndustriesArray() { for (GRFFile * const file : _grf_files) { - for (auto indsp : file->industryspec) { + for (const auto &indsp : file->industryspec) { if (indsp == nullptr || !indsp->enabled) continue; StringID strid; @@ -9427,12 +9382,12 @@ static void FinaliseIndustriesArray() if (strid != STR_UNDEFINED) indsp->station_name = strid; } - _industry_mngr.SetEntitySpec(indsp); + _industry_mngr.SetEntitySpec(indsp.get()); } - for (auto indtsp : file->indtspec) { + for (const auto &indtsp : file->indtspec) { if (indtsp != nullptr) { - _industile_mngr.SetEntitySpec(indtsp); + _industile_mngr.SetEntitySpec(indtsp.get()); } } } @@ -9458,9 +9413,9 @@ static void FinaliseIndustriesArray() static void FinaliseObjectsArray() { for (GRFFile * const file : _grf_files) { - for (auto objectspec : file->objectspec) { + for (auto &objectspec : file->objectspec) { if (objectspec != nullptr && objectspec->grf_prop.grffile != nullptr && objectspec->IsEnabled()) { - _object_mngr.SetEntitySpec(objectspec); + _object_mngr.SetEntitySpec(objectspec.get()); } } } @@ -9476,15 +9431,15 @@ static void FinaliseObjectsArray() static void FinaliseAirportsArray() { for (GRFFile * const file : _grf_files) { - for (auto as : file->airportspec) { + for (auto &as : file->airportspec) { if (as != nullptr && as->enabled) { - _airport_mngr.SetEntitySpec(as); + _airport_mngr.SetEntitySpec(as.get()); } } - for (auto ats : file->airtspec) { + for (auto &ats : file->airtspec) { if (ats != nullptr && ats->enabled) { - _airporttile_mngr.SetEntitySpec(ats); + _airporttile_mngr.SetEntitySpec(ats.get()); } } } diff --git a/src/newgrf.h b/src/newgrf.h index 3627a7d9c5..e9b5255c06 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -112,14 +112,14 @@ struct GRFFile : ZeroedMemoryAllocator { uint sound_offset; uint16 num_sounds; - std::vector stations; - std::vector housespec; - std::vector industryspec; - std::vector indtspec; - std::vector objectspec; - std::vector airportspec; - std::vector airtspec; - std::vector roadstops; + std::vector> stations; + std::vector> housespec; + std::vector> industryspec; + std::vector> indtspec; + std::vector> objectspec; + std::vector> airportspec; + std::vector> airtspec; + std::vector> roadstops; uint32 param[0x80]; uint param_end; ///< one more than the highest set parameter From 9e89eb5726847296b92643ea1c6e3d55101e95e2 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 10 Apr 2023 17:33:18 +0200 Subject: [PATCH 13/48] Codechange: move main function(s) to separate files --- src/os/macosx/CMakeLists.txt | 1 + src/os/macosx/osx_main.cpp | 53 ++++++++++++++++++++ src/os/os2/CMakeLists.txt | 1 + src/os/os2/os2.cpp | 12 ----- src/os/os2/os2_main.cpp | 28 +++++++++++ src/os/unix/CMakeLists.txt | 1 + src/os/unix/unix.cpp | 41 ---------------- src/os/unix/unix_main.cpp | 33 +++++++++++++ src/os/windows/CMakeLists.txt | 1 + src/os/windows/win32.cpp | 75 ----------------------------- src/os/windows/win32_main.cpp | 91 +++++++++++++++++++++++++++++++++++ 11 files changed, 209 insertions(+), 128 deletions(-) create mode 100644 src/os/macosx/osx_main.cpp create mode 100644 src/os/os2/os2_main.cpp create mode 100644 src/os/unix/unix_main.cpp create mode 100644 src/os/windows/win32_main.cpp diff --git a/src/os/macosx/CMakeLists.txt b/src/os/macosx/CMakeLists.txt index 645a057c7d..6442d1a27b 100644 --- a/src/os/macosx/CMakeLists.txt +++ b/src/os/macosx/CMakeLists.txt @@ -4,6 +4,7 @@ add_files( font_osx.h macos.h macos.mm + osx_main.cpp osx_stdafx.h string_osx.cpp string_osx.h diff --git a/src/os/macosx/osx_main.cpp b/src/os/macosx/osx_main.cpp new file mode 100644 index 0000000000..856d48f9b4 --- /dev/null +++ b/src/os/macosx/osx_main.cpp @@ -0,0 +1,53 @@ +/* + * 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 unix_main.cpp Main entry for Mac OSX. */ + +#include "../../stdafx.h" +#include "../../openttd.h" +#include "../../crashlog.h" +#include "../../core/random_func.hpp" +#include "../../string_func.h" + +#include +#include + +#if defined(WITH_SDL) +/* the mac implementation needs this file included in the same file as main() */ +# include +#endif +#include "macos.h" + +#include "../../safeguards.h" + +void CocoaSetupAutoreleasePool(); +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++) StrMakeValidInPlace(argv[i]); + + CocoaSetupAutoreleasePool(); + /* This is passed if we are launched by double-clicking */ + if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) { + argv[1] = nullptr; + argc = 1; + } + + CrashLog::InitialiseCrashLog(); + + SetRandomSeed(time(nullptr)); + + signal(SIGPIPE, SIG_IGN); + + int ret = openttd_main(argc, argv); + + CocoaReleaseAutoreleasePool(); + + return ret; +} diff --git a/src/os/os2/CMakeLists.txt b/src/os/os2/CMakeLists.txt index 52534dbcbb..fbcd4783b0 100644 --- a/src/os/os2/CMakeLists.txt +++ b/src/os/os2/CMakeLists.txt @@ -1,4 +1,5 @@ add_files( os2.cpp + os2_main.cpp CONDITION OPTION_OS2 ) diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index 6e190cfa12..f18e50c4c3 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.cpp @@ -12,8 +12,6 @@ #include "../../gui.h" #include "../../fileio_func.h" #include "../../fios.h" -#include "../../openttd.h" -#include "../../core/random_func.hpp" #include "../../string_func.h" #include "../../textbuf_gui.h" #include "../../thread.h" @@ -169,16 +167,6 @@ void ShowOSErrorBox(const char *buf, bool system) WinTerminate(hab); } -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++) StrMakeValidInPlace(argv[i]); - - return openttd_main(argc, argv); -} - bool GetClipboardContents(char *buffer, const char *last) { /* XXX -- Currently no clipboard support implemented with GCC */ diff --git a/src/os/os2/os2_main.cpp b/src/os/os2/os2_main.cpp new file mode 100644 index 0000000000..a411a07151 --- /dev/null +++ b/src/os/os2/os2_main.cpp @@ -0,0 +1,28 @@ +/* + * 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 os2_main.cpp Main entry for OS/2. */ + +#include "../../stdafx.h" +#include "../../openttd.h" +#include "../../core/random_func.hpp" +#include "../../string_func.h" + +#include +#include + +#include "../../safeguards.h" + +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++) StrMakeValidInPlace(argv[i]); + + return openttd_main(argc, argv); +} diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt index 8e74f96643..a8a421163d 100644 --- a/src/os/unix/CMakeLists.txt +++ b/src/os/unix/CMakeLists.txt @@ -1,5 +1,6 @@ add_files( crashlog_unix.cpp + unix_main.cpp CONDITION UNIX AND NOT APPLE AND NOT OPTION_OS2 ) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 95d6fa1fa5..e3f6496488 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -9,9 +9,6 @@ #include "../../stdafx.h" #include "../../textbuf_gui.h" -#include "../../openttd.h" -#include "../../crashlog.h" -#include "../../core/random_func.hpp" #include "../../debug.h" #include "../../string_func.h" #include "../../fios.h" @@ -55,11 +52,6 @@ #endif #if defined(__APPLE__) -# if defined(WITH_SDL) - /* the mac implementation needs this file included in the same file as main() */ -# include -# endif - # include "../macosx/macos.h" #endif @@ -235,39 +227,6 @@ void ShowOSErrorBox(const char *buf, bool system) } #endif -#ifdef WITH_COCOA -void CocoaSetupAutoreleasePool(); -void CocoaReleaseAutoreleasePool(); -#endif - -int CDECL main(int argc, char *argv[]) -{ - /* Make sure our arguments contain only valid UTF-8 characters. */ - for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); - -#ifdef WITH_COCOA - CocoaSetupAutoreleasePool(); - /* This is passed if we are launched by double-clicking */ - if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) { - argv[1] = nullptr; - argc = 1; - } -#endif - CrashLog::InitialiseCrashLog(); - - SetRandomSeed(time(nullptr)); - - signal(SIGPIPE, SIG_IGN); - - int ret = openttd_main(argc, argv); - -#ifdef WITH_COCOA - CocoaReleaseAutoreleasePool(); -#endif - - return ret; -} - #ifndef WITH_COCOA bool GetClipboardContents(char *buffer, const char *last) { diff --git a/src/os/unix/unix_main.cpp b/src/os/unix/unix_main.cpp new file mode 100644 index 0000000000..41ad22ced5 --- /dev/null +++ b/src/os/unix/unix_main.cpp @@ -0,0 +1,33 @@ +/* + * 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 unix_main.cpp Main entry for Unix. */ + +#include "../../stdafx.h" +#include "../../openttd.h" +#include "../../crashlog.h" +#include "../../core/random_func.hpp" +#include "../../string_func.h" + +#include +#include + +#include "../../safeguards.h" + +int CDECL main(int argc, char *argv[]) +{ + /* Make sure our arguments contain only valid UTF-8 characters. */ + for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); + + CrashLog::InitialiseCrashLog(); + + SetRandomSeed(time(nullptr)); + + signal(SIGPIPE, SIG_IGN); + + return openttd_main(argc, argv); +} diff --git a/src/os/windows/CMakeLists.txt b/src/os/windows/CMakeLists.txt index 8ac2de7acc..2f41ea16e5 100644 --- a/src/os/windows/CMakeLists.txt +++ b/src/os/windows/CMakeLists.txt @@ -6,5 +6,6 @@ add_files( string_uniscribe.h win32.cpp win32.h + win32_main.cpp CONDITION WIN32 ) diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index bb93c01ba0..47cb27a3cc 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -22,10 +22,7 @@ #include "win32.h" #include "../../fios.h" #include "../../core/alloc_func.hpp" -#include "../../openttd.h" -#include "../../core/random_func.hpp" #include "../../string_func.h" -#include "../../crashlog.h" #include #include #include "../../language.h" @@ -229,37 +226,6 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) return retval; } -static int ParseCommandLine(char *line, char **argv, int max_argc) -{ - int n = 0; - - do { - /* skip whitespace */ - while (*line == ' ' || *line == '\t') line++; - - /* end? */ - if (*line == '\0') break; - - /* special handling when quoted */ - if (*line == '"') { - argv[n++] = ++line; - while (*line != '"') { - if (*line == '\0') return n; - line++; - } - } else { - argv[n++] = line; - while (*line != ' ' && *line != '\t') { - if (*line == '\0') return n; - line++; - } - } - *line++ = '\0'; - } while (n != max_argc); - - return n; -} - void CreateConsole() { HANDLE hand; @@ -378,47 +344,6 @@ void ShowInfo(const char *str) } } -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - int argc; - char *argv[64]; // max 64 command line arguments - - /* Set system timer resolution to 1ms. */ - timeBeginPeriod(1); - - CrashLog::InitialiseCrashLog(); - - /* Convert the command line to UTF-8. We need a dedicated buffer - * for this because argv[] points into this buffer and this needs to - * be available between subsequent calls to FS2OTTD(). */ - char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str()); - - /* Set the console codepage to UTF-8. */ - SetConsoleOutputCP(CP_UTF8); - -#if defined(_DEBUG) - CreateConsole(); -#endif - - _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox - - /* setup random seed to something quite random */ - SetRandomSeed(GetTickCount()); - - argc = ParseCommandLine(cmdline, argv, lengthof(argv)); - - /* Make sure our arguments contain only valid UTF-8 characters. */ - for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); - - openttd_main(argc, argv); - - /* Restore system timer resolution. */ - timeEndPeriod(1); - - free(cmdline); - return 0; -} - char *getcwd(char *buf, size_t size) { wchar_t path[MAX_PATH]; diff --git a/src/os/windows/win32_main.cpp b/src/os/windows/win32_main.cpp new file mode 100644 index 0000000000..f8b13a751f --- /dev/null +++ b/src/os/windows/win32_main.cpp @@ -0,0 +1,91 @@ +/* + * 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 win32_main.cpp Implementation main for Windows. */ + +#include "../../stdafx.h" +#include +#include +#include "../../openttd.h" +#include "../../core/random_func.hpp" +#include "../../string_func.h" +#include "../../crashlog.h" +#include "../../debug.h" + +#include "../../safeguards.h" + +static int ParseCommandLine(char *line, char **argv, int max_argc) +{ + int n = 0; + + do { + /* skip whitespace */ + while (*line == ' ' || *line == '\t') line++; + + /* end? */ + if (*line == '\0') break; + + /* special handling when quoted */ + if (*line == '"') { + argv[n++] = ++line; + while (*line != '"') { + if (*line == '\0') return n; + line++; + } + } else { + argv[n++] = line; + while (*line != ' ' && *line != '\t') { + if (*line == '\0') return n; + line++; + } + } + *line++ = '\0'; + } while (n != max_argc); + + return n; +} + +void CreateConsole(); + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + /* Set system timer resolution to 1ms. */ + timeBeginPeriod(1); + + CrashLog::InitialiseCrashLog(); + + /* Convert the command line to UTF-8. We need a dedicated buffer + * for this because argv[] points into this buffer and this needs to + * be available between subsequent calls to FS2OTTD(). */ + char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str()); + + /* Set the console codepage to UTF-8. */ + SetConsoleOutputCP(CP_UTF8); + +#if defined(_DEBUG) + CreateConsole(); +#endif + + _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox + + /* setup random seed to something quite random */ + SetRandomSeed(GetTickCount()); + + char *argv[64]; // max 64 command line arguments + int argc = ParseCommandLine(cmdline, argv, lengthof(argv)); + + /* Make sure our arguments contain only valid UTF-8 characters. */ + for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]); + + int ret = openttd_main(argc, argv); + + /* Restore system timer resolution. */ + timeEndPeriod(1); + + free(cmdline); + return ret; +} From 9b56505feca991736c323ae64e3fc5416522de70 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 10 Apr 2023 18:00:53 +0200 Subject: [PATCH 14/48] Codechange: split building into a library and executable --- CMakeLists.txt | 19 ++++++++++++------- cmake/CheckAtomic.cmake | 2 +- cmake/LinkPackage.cmake | 4 ++-- cmake/SourceList.cmake | 2 +- src/os/macosx/CMakeLists.txt | 5 ++++- src/os/os2/CMakeLists.txt | 5 ++++- src/os/unix/CMakeLists.txt | 5 ++++- src/os/windows/CMakeLists.txt | 5 ++++- 8 files changed, 32 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19ebc760d6..e911625cfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,7 +224,8 @@ include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/squirrel/include) include(MSVCFilters) -add_executable(openttd WIN32 ${GENERATED_SOURCE_FILES}) +add_library(openttd_lib OBJECT ${GENERATED_SOURCE_FILES}) +add_executable(openttd WIN32) set_target_properties(openttd PROPERTIES OUTPUT_NAME "${BINARY_NAME}") # All other files are added via target_sources() @@ -240,17 +241,21 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/media) add_dependencies(openttd find_version) -target_link_libraries(openttd +target_link_libraries(openttd_lib openttd::languages openttd::settings - openttd::media - openttd::basesets openttd::script_api Threads::Threads ) +target_link_libraries(openttd + openttd_lib + openttd::media + openttd::basesets +) + if(HAIKU) - target_link_libraries(openttd "be" "network" "midi") + target_link_libraries(openttd_lib "be" "network" "midi") endif() if(IPO_FOUND) @@ -297,7 +302,7 @@ include(CheckAtomic) if(APPLE) link_package(Iconv TARGET Iconv::Iconv) - target_link_libraries(openttd + target_link_libraries(openttd_lib ${AUDIOTOOLBOX_LIBRARY} ${AUDIOUNIT_LIBRARY} ${COCOA_LIBRARY} @@ -376,7 +381,7 @@ if(WIN32) -DPSAPI_VERSION=1 ) - target_link_libraries(openttd + target_link_libraries(openttd_lib ws2_32 winmm imm32 diff --git a/cmake/CheckAtomic.cmake b/cmake/CheckAtomic.cmake index 52d93f4f5b..990c52c37c 100644 --- a/cmake/CheckAtomic.cmake +++ b/cmake/CheckAtomic.cmake @@ -83,5 +83,5 @@ else() endif() if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB) - target_link_libraries(openttd atomic) + target_link_libraries(openttd_lib atomic) endif() diff --git a/cmake/LinkPackage.cmake b/cmake/LinkPackage.cmake index bea9deb0cf..afbd921cf7 100644 --- a/cmake/LinkPackage.cmake +++ b/cmake/LinkPackage.cmake @@ -8,13 +8,13 @@ function(link_package NAME) # which (later) cmake considers to be an error. Work around this with by stripping the incoming string. if(LP_TARGET AND TARGET ${LP_TARGET}) string(STRIP "${LP_TARGET}" LP_TARGET) - target_link_libraries(openttd ${LP_TARGET}) + target_link_libraries(openttd_lib ${LP_TARGET}) message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${LP_TARGET}") else() string(STRIP "${${NAME}_LIBRARY}" ${NAME}_LIBRARY) string(STRIP "${${NAME}_LIBRARIES}" ${NAME}_LIBRARIES) include_directories(${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR}) - target_link_libraries(openttd ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY}) + target_link_libraries(openttd_lib ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY}) message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR} -- ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY}") endif() elseif(LP_ENCOURAGED) diff --git a/cmake/SourceList.cmake b/cmake/SourceList.cmake index 6e95be2017..b576e20a02 100644 --- a/cmake/SourceList.cmake +++ b/cmake/SourceList.cmake @@ -17,7 +17,7 @@ function(add_files) endif() foreach(FILE IN LISTS PARAM_FILES) - target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) + target_sources(openttd_lib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) endforeach() endfunction() diff --git a/src/os/macosx/CMakeLists.txt b/src/os/macosx/CMakeLists.txt index 6442d1a27b..acb30baf88 100644 --- a/src/os/macosx/CMakeLists.txt +++ b/src/os/macosx/CMakeLists.txt @@ -4,9 +4,12 @@ add_files( font_osx.h macos.h macos.mm - osx_main.cpp osx_stdafx.h string_osx.cpp string_osx.h CONDITION APPLE ) + +if(APPLE) + target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/osx_main.cpp) +endif() diff --git a/src/os/os2/CMakeLists.txt b/src/os/os2/CMakeLists.txt index fbcd4783b0..141dd98043 100644 --- a/src/os/os2/CMakeLists.txt +++ b/src/os/os2/CMakeLists.txt @@ -1,5 +1,8 @@ add_files( os2.cpp - os2_main.cpp CONDITION OPTION_OS2 ) + +if(OPTION_OS2) + target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/os2_main.cpp) +endif() diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt index a8a421163d..a95d8ce2db 100644 --- a/src/os/unix/CMakeLists.txt +++ b/src/os/unix/CMakeLists.txt @@ -1,6 +1,5 @@ add_files( crashlog_unix.cpp - unix_main.cpp CONDITION UNIX AND NOT APPLE AND NOT OPTION_OS2 ) @@ -13,3 +12,7 @@ add_files( font_unix.cpp CONDITION Fontconfig_FOUND ) + +if(UNIX AND NOT APPLE AND NOT OPTION_OS2) + target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/unix_main.cpp) +endif() diff --git a/src/os/windows/CMakeLists.txt b/src/os/windows/CMakeLists.txt index 2f41ea16e5..a1b73a6d8f 100644 --- a/src/os/windows/CMakeLists.txt +++ b/src/os/windows/CMakeLists.txt @@ -6,6 +6,9 @@ add_files( string_uniscribe.h win32.cpp win32.h - win32_main.cpp CONDITION WIN32 ) + +if(WIN32) + target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/win32_main.cpp) +endif() From 88ead3f102938ac15f91805bf48cf67460832ce5 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 10 Apr 2023 22:30:32 +0200 Subject: [PATCH 15/48] Add: catch2 v2.13.10 --- README.md | 2 + cmake/Catch.cmake | 206 + cmake/CatchAddTests.cmake | 135 + src/3rdparty/CMakeLists.txt | 1 + src/3rdparty/README.licensing | 2 +- src/3rdparty/catch2/CMakeLists.txt | 3 + src/3rdparty/catch2/LICENSE.txt | 23 + src/3rdparty/catch2/catch.hpp | 17976 +++++++++++++++++++++++++++ 8 files changed, 18347 insertions(+), 1 deletion(-) create mode 100644 cmake/Catch.cmake create mode 100644 cmake/CatchAddTests.cmake create mode 100644 src/3rdparty/catch2/CMakeLists.txt create mode 100644 src/3rdparty/catch2/LICENSE.txt create mode 100644 src/3rdparty/catch2/catch.hpp diff --git a/README.md b/README.md index 96f137307c..466868c860 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,8 @@ The exact licensing terms can be found in `src/3rdparty/os2/getaddrinfo.c` resp. The fmt implementation in `src/3rdparty/fmt` is licensed under the MIT license. See `src/3rdparty/fmt/LICENSE.rst` for the complete license text. +The catch2 implementation in `src/3rdparty/catch2` is licensed under the Boost Software License, Version 1.0. +See `src/3rdparty/catch2/LICENSE.txt` for the complete license text. ## 4.0 Credits diff --git a/cmake/Catch.cmake b/cmake/Catch.cmake new file mode 100644 index 0000000000..6f21a89c98 --- /dev/null +++ b/cmake/Catch.cmake @@ -0,0 +1,206 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +Catch +----- + +This module defines a function to help use the Catch test framework. + +The :command:`catch_discover_tests` discovers tests by asking the compiled test +executable to enumerate its tests. This does not require CMake to be re-run +when tests change. However, it may not work in a cross-compiling environment, +and setting test properties is less convenient. + +This command is intended to replace use of :command:`add_test` to register +tests, and will create a separate CTest test for each Catch test case. Note +that this is in some cases less efficient, as common set-up and tear-down logic +cannot be shared by multiple test cases executing in the same instance. +However, it provides more fine-grained pass/fail information to CTest, which is +usually considered as more beneficial. By default, the CTest test name is the +same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. + +.. command:: catch_discover_tests + + Automatically add tests with CTest by querying the compiled test executable + for available tests:: + + catch_discover_tests(target + [TEST_SPEC arg1...] + [EXTRA_ARGS arg1...] + [WORKING_DIRECTORY dir] + [TEST_PREFIX prefix] + [TEST_SUFFIX suffix] + [PROPERTIES name1 value1...] + [TEST_LIST var] + [REPORTER reporter] + [OUTPUT_DIR dir] + [OUTPUT_PREFIX prefix} + [OUTPUT_SUFFIX suffix] + ) + + ``catch_discover_tests`` sets up a post-build command on the test executable + that generates the list of tests by parsing the output from running the test + with the ``--list-test-names-only`` argument. This ensures that the full + list of tests is obtained. Since test discovery occurs at build time, it is + not necessary to re-run CMake when the list of tests changes. + However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set + in order to function in a cross-compiling environment. + + Additionally, setting properties on tests is somewhat less convenient, since + the tests are not available at CMake time. Additional test properties may be + assigned to the set of tests as a whole using the ``PROPERTIES`` option. If + more fine-grained test control is needed, custom content may be provided + through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES` + directory property. The set of discovered tests is made accessible to such a + script via the ``_TESTS`` variable. + + The options are: + + ``target`` + Specifies the Catch executable, which must be a known CMake executable + target. CMake will substitute the location of the built executable when + running the test. + + ``TEST_SPEC arg1...`` + Specifies test cases, wildcarded test cases, tags and tag expressions to + pass to the Catch executable with the ``--list-test-names-only`` argument. + + ``EXTRA_ARGS arg1...`` + Any extra arguments to pass on the command line to each test case. + + ``WORKING_DIRECTORY dir`` + Specifies the directory in which to run the discovered test cases. If this + option is not provided, the current binary directory is used. + + ``TEST_PREFIX prefix`` + Specifies a ``prefix`` to be prepended to the name of each discovered test + case. This can be useful when the same test executable is being used in + multiple calls to ``catch_discover_tests()`` but with different + ``TEST_SPEC`` or ``EXTRA_ARGS``. + + ``TEST_SUFFIX suffix`` + Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of + every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may + be specified. + + ``PROPERTIES name1 value1...`` + Specifies additional properties to be set on all tests discovered by this + invocation of ``catch_discover_tests``. + + ``TEST_LIST var`` + Make the list of tests available in the variable ``var``, rather than the + default ``_TESTS``. This can be useful when the same test + executable is being used in multiple calls to ``catch_discover_tests()``. + Note that this variable is only available in CTest. + + ``REPORTER reporter`` + Use the specified reporter when running the test case. The reporter will + be passed to the Catch executable as ``--reporter reporter``. + + ``OUTPUT_DIR dir`` + If specified, the parameter is passed along as + ``--out dir/`` to Catch executable. The actual file name is the + same as the test name. This should be used instead of + ``EXTRA_ARGS --out foo`` to avoid race conditions writing the result output + when using parallel test execution. + + ``OUTPUT_PREFIX prefix`` + May be used in conjunction with ``OUTPUT_DIR``. + If specified, ``prefix`` is added to each output file name, like so + ``--out dir/prefix``. + + ``OUTPUT_SUFFIX suffix`` + May be used in conjunction with ``OUTPUT_DIR``. + If specified, ``suffix`` is added to each output file name, like so + ``--out dir/suffix``. This can be used to add a file extension to + the output e.g. ".xml". + +#]=======================================================================] + +#------------------------------------------------------------------------------ +function(catch_discover_tests TARGET) + cmake_parse_arguments( + "" + "" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX" + "TEST_SPEC;EXTRA_ARGS;PROPERTIES" + ${ARGN} + ) + + if(NOT _WORKING_DIRECTORY) + set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + if(NOT _TEST_LIST) + set(_TEST_LIST ${TARGET}_TESTS) + endif() + + ## Generate a unique name based on the extra arguments + string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}") + string(SUBSTRING ${args_hash} 0 7 args_hash) + + # Define rule to generate test list for aforementioned test executable + set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") + set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") + get_property(crosscompiling_emulator + TARGET ${TARGET} + PROPERTY CROSSCOMPILING_EMULATOR + ) + add_custom_command( + TARGET ${TARGET} POST_BUILD + BYPRODUCTS "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D "TEST_TARGET=${TARGET}" + -D "TEST_EXECUTABLE=$" + -D "TEST_EXECUTOR=${crosscompiling_emulator}" + -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D "TEST_SPEC=${_TEST_SPEC}" + -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D "TEST_PROPERTIES=${_PROPERTIES}" + -D "TEST_PREFIX=${_TEST_PREFIX}" + -D "TEST_SUFFIX=${_TEST_SUFFIX}" + -D "TEST_LIST=${_TEST_LIST}" + -D "TEST_REPORTER=${_REPORTER}" + -D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}" + -D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}" + -D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}" + -D "CTEST_FILE=${ctest_tests_file}" + -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" + VERBATIM + ) + + file(WRITE "${ctest_include_file}" + "if(EXISTS \"${ctest_tests_file}\")\n" + " include(\"${ctest_tests_file}\")\n" + "else()\n" + " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" + "endif()\n" + ) + + if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") + # Add discovered tests to directory TEST_INCLUDE_FILES + set_property(DIRECTORY + APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" + ) + else() + # Add discovered tests as directory TEST_INCLUDE_FILE if possible + get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) + if (NOT ${test_include_file_set}) + set_property(DIRECTORY + PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" + ) + else() + message(FATAL_ERROR + "Cannot set more than one TEST_INCLUDE_FILE" + ) + endif() + endif() + +endfunction() + +############################################################################### + +set(_CATCH_DISCOVER_TESTS_SCRIPT + ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake + CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file" +) diff --git a/cmake/CatchAddTests.cmake b/cmake/CatchAddTests.cmake new file mode 100644 index 0000000000..7faeedbd27 --- /dev/null +++ b/cmake/CatchAddTests.cmake @@ -0,0 +1,135 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +set(prefix "${TEST_PREFIX}") +set(suffix "${TEST_SUFFIX}") +set(spec ${TEST_SPEC}) +set(extra_args ${TEST_EXTRA_ARGS}) +set(properties ${TEST_PROPERTIES}) +set(reporter ${TEST_REPORTER}) +set(output_dir ${TEST_OUTPUT_DIR}) +set(output_prefix ${TEST_OUTPUT_PREFIX}) +set(output_suffix ${TEST_OUTPUT_SUFFIX}) +set(script) +set(suite) +set(tests) + +function(add_command NAME) + set(_args "") + # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments + math(EXPR _last_arg ${ARGC}-1) + foreach(_n RANGE 1 ${_last_arg}) + set(_arg "${ARGV${_n}}") + if(_arg MATCHES "[^-./:a-zA-Z0-9_]") + set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument + else() + set(_args "${_args} ${_arg}") + endif() + endforeach() + set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) +endfunction() + +# Run test executable to get list of available tests +if(NOT EXISTS "${TEST_EXECUTABLE}") + message(FATAL_ERROR + "Specified test executable '${TEST_EXECUTABLE}' does not exist" + ) +endif() +execute_process( + COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only + OUTPUT_VARIABLE output + RESULT_VARIABLE result + WORKING_DIRECTORY "${TEST_WORKING_DIR}" +) +# Catch --list-test-names-only reports the number of tests, so 0 is... surprising +if(${result} EQUAL 0) + message(WARNING + "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" + ) +elseif(${result} LESS 0) + message(FATAL_ERROR + "Error running test executable '${TEST_EXECUTABLE}':\n" + " Result: ${result}\n" + " Output: ${output}\n" + ) +endif() + +string(REPLACE "\n" ";" output "${output}") + +# Run test executable to get list of available reporters +execute_process( + COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters + OUTPUT_VARIABLE reporters_output + RESULT_VARIABLE reporters_result + WORKING_DIRECTORY "${TEST_WORKING_DIR}" +) +if(${reporters_result} EQUAL 0) + message(WARNING + "Test executable '${TEST_EXECUTABLE}' contains no reporters!\n" + ) +elseif(${reporters_result} LESS 0) + message(FATAL_ERROR + "Error running test executable '${TEST_EXECUTABLE}':\n" + " Result: ${reporters_result}\n" + " Output: ${reporters_output}\n" + ) +endif() +string(FIND "${reporters_output}" "${reporter}" reporter_is_valid) +if(reporter AND ${reporter_is_valid} EQUAL -1) + message(FATAL_ERROR + "\"${reporter}\" is not a valid reporter!\n" + ) +endif() + +# Prepare reporter +if(reporter) + set(reporter_arg "--reporter ${reporter}") +endif() + +# Prepare output dir +if(output_dir AND NOT IS_ABSOLUTE ${output_dir}) + set(output_dir "${TEST_WORKING_DIR}/${output_dir}") + if(NOT EXISTS ${output_dir}) + file(MAKE_DIRECTORY ${output_dir}) + endif() +endif() + +# Parse output +foreach(line ${output}) + set(test ${line}) + # Escape characters in test case names that would be parsed by Catch2 + set(test_name ${test}) + foreach(char , [ ]) + string(REPLACE ${char} "\\${char}" test_name ${test_name}) + endforeach(char) + # ...add output dir + if(output_dir) + string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name}) + set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}") + endif() + + # ...and add to script + add_command(add_test + "${prefix}${test}${suffix}" + ${TEST_EXECUTOR} + "${TEST_EXECUTABLE}" + "${test_name}" + ${extra_args} + "${reporter_arg}" + "${output_dir_arg}" + ) + add_command(set_tests_properties + "${prefix}${test}${suffix}" + PROPERTIES + WORKING_DIRECTORY "${TEST_WORKING_DIR}" + ${properties} + ) + list(APPEND tests "${prefix}${test}${suffix}") +endforeach() + +# Create a list of all discovered tests, which users may use to e.g. set +# properties on the tests +add_command(set ${TEST_LIST} ${tests}) + +# Write CTest script +file(WRITE "${CTEST_FILE}" "${script}") diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 50fa6922f4..1c7f915de6 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(catch2) add_subdirectory(fmt) add_subdirectory(md5) add_subdirectory(squirrel) diff --git a/src/3rdparty/README.licensing b/src/3rdparty/README.licensing index 112b02a087..c5da7bdd15 100644 --- a/src/3rdparty/README.licensing +++ b/src/3rdparty/README.licensing @@ -1,3 +1,3 @@ The files in this directory are not licensed under the same terms as the -rest of OpenTTD. Licensing details can be found in OpenTTD's readme.txt +rest of OpenTTD. Licensing details can be found in OpenTTD's README.md and in this directory or subdirectories as well. diff --git a/src/3rdparty/catch2/CMakeLists.txt b/src/3rdparty/catch2/CMakeLists.txt new file mode 100644 index 0000000000..72e0afa732 --- /dev/null +++ b/src/3rdparty/catch2/CMakeLists.txt @@ -0,0 +1,3 @@ +add_files( + catch.hpp +) diff --git a/src/3rdparty/catch2/LICENSE.txt b/src/3rdparty/catch2/LICENSE.txt new file mode 100644 index 0000000000..36b7cd93cd --- /dev/null +++ b/src/3rdparty/catch2/LICENSE.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/3rdparty/catch2/catch.hpp b/src/3rdparty/catch2/catch.hpp new file mode 100644 index 0000000000..9b309bddc6 --- /dev/null +++ b/src/3rdparty/catch2/catch.hpp @@ -0,0 +1,17976 @@ +/* + * Catch v2.13.10 + * Generated: 2022-10-16 11:01:23.452308 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 10 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +# if !defined(__clang__) // Handle Clang masquerading for msvc + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template