We won't be able to make it fully self-descriptive (looking at you
MAP-chunks), but anything else can. With this framework, we can
add headers for each chunk explaining how each chunk looks like
in detail.
They also will all be tables, making it a lot easier to read in
external tooling, and opening the way to consider a database
(like SQLite) to use as savegame format.
Lastly, with the headers in the savegame, you can freely add
fields without needing a savegame version bump; older versions
of OpenTTD will simply ignore the new field. This also means
we can remove all the SLE_CONDNULL, as they are irrelevant.
The next few commits will start using this framework.
We often ask people for their openttd.cfg, which now includes their
passwords, usernames, etc. It is easy for people to overlook this,
unwillingly sharing information they shouldn't.
By splitting this information over either private.cfg or secrets.cfg,
we make it more obvious they shouldn't be sharing those files, and
hint to what is inside them.
Instead of creating the object on heap and use a pointer, create
the object on stack and use a guaranteed-not-null pointer.
The size of IniFile doesn't warrent the forcing to heap.
Additionally, use a subclass instead of a function to do some
initial bookkeeping on an IniFile meant to read a configuration.
Unless invoked with -w, --warning ("print a warning for any untranslated strings") or -t, --todo ("replace any untranslated strings with '<TODO>'").
Eints normally fixes the warnings after a Pull Request, so it is not really useful information for the developer to see as a warning.
With std::variant all memory can be figured out at compile time, so the compiler needs to keep track of fewer elements. It also saves out a unique_ptr and its memory management, over a slight impact for resolving a setting.
One UpdateServiceInterval has two parameters to update the service interval for a vehicle type, the other for all vehicle types at once. Rename the latter to help with function resolution for the introduction of variants.
Rename the zero-parameter NetworkValidateClientName to NetworkValidateOurClientName to make it clearer it is performed on our client name, and to make it a non-overloaded function to aid with the variant being added a few commits later
ThreadSanitizer rightfully notices that the game-thread could
update the palette while the draw-thread is copying it for local
use. The odds of this are very small, but nevertheless, it does
carry a very good point.
It wouldn't hurt the application in any way, but it might cause
visual glitches on the screen.
The enum values still have the exact same numerical values, but the 10.12
SDK introduced more explicit names (e.g. like NSEventTypeApplicationDefined
instead of NSApplicationDefined) for several enum constants.
Use them when available.
When the game-loop is very slow, it was easily possible to start
the loop with _shift_pressed being false, but end with
_shift_pressed being true. This doesn't hurt the game as such,
but for the user this can be very weird: I pressed "Buy Vehicle",
pressed shift a bit later, and I still get a cost indication.
Creating a thread was not thread-safe. The irony.
The video-driver has a function GameLoopPause() which first checks
if the thread is the game-thread or not. For this it needs access
to this->game_thread. This variable is set in StartNewThread().
However, due to timing, it is well possible GameLoopPause() is
called from the thread well before this->game_thread is assigned.
And so we have a race-condition!
Simply solve this by preventing a thread to start till we are
done with our bookkeeping.
This makes it easier to spot chunks that have a save_proc that
is a nullptr, but also prevents confusion, where it looks like
the CH_ type of a chunk has influence on how it is being read.
It is not, it is only used for saving.