1
0
Fork 0

Compare commits

..

11 Commits

Author SHA1 Message Date
Tyler Trahan fa479c4a7c
Cleanup: Describe modifier keys more consistently in tooltips (#11716) 2024-01-20 19:26:39 +00:00
Tyler Trahan 500870627d
Change: Rewrite a few main toolbar tooltips (#11717) 2024-01-20 13:49:34 -05:00
translators 4d79d86812 Update: Translations from eints
catalan: 18 changes by J0anJosep
2024-01-20 18:38:38 +00:00
Peter Nelson d6ccfdbbd9
Fix #11827: Make Layouter::GetCharPosition() aware of ligatures. (#11831)
When ligatures happen the precise individual character position is not known, so instead return the previous position (which is that of the ligature.)
2024-01-20 17:16:42 +00:00
Rubidium 086cbd0d72 Codechange: add constexpr to math functions where applicable 2024-01-20 17:30:36 +01:00
Rubidium dfe70181f1 Codechange: add constexpr to bitmath functions where applicable 2024-01-20 17:30:36 +01:00
Rubidium 4c51534b6a Remove: LeastCommonMultiple / GreatestCommonDivisor
Use std::lcm / std::gcd instead.
2024-01-20 16:45:21 +01:00
Rubidium 1403f24fa9 Codechange: replace LeastCommonMultiple with std::lcm 2024-01-20 16:45:21 +01:00
Patric Stout bd85f61a40 Change: use a stronger hash and actual random information to generate Uids 2024-01-20 14:23:03 +01:00
Patric Stout 37244bc8c5 Codechange: MacOS already has MIN/MAX macros defined
This is caused because we use PreCompile Headers, and one of them
includes a system headers which defines MIN/MAX.
2024-01-20 14:23:03 +01:00
Patric Stout 63a3d56b8a Add: monocypher 4.0.2
Monocypher will take care of all our encryption needs; as most
OSes and vcpkg doesn't have it available, we vendor it.
2024-01-20 14:23:03 +01:00
24 changed files with 4925 additions and 298 deletions

View File

@ -448,6 +448,7 @@ if(WIN32)
usp10 usp10
psapi psapi
winhttp winhttp
bcrypt
) )
endif() endif()

View File

@ -197,6 +197,9 @@ See `src/3rdparty/catch2/LICENSE.txt` for the complete license text.
The icu scriptrun implementation in `src/3rdparty/icu` is licensed under the Unicode license. The icu scriptrun implementation in `src/3rdparty/icu` is licensed under the Unicode license.
See `src/3rdparty/icu/LICENSE` for the complete license text. See `src/3rdparty/icu/LICENSE` for the complete license text.
The monocypher implementation in `src/3rdparty/monocypher` is licensed under the 2-clause BSD and CC-0 license.
See src/3rdparty/monocypher/LICENSE.md` for the complete license text.
## 4.0 Credits ## 4.0 Credits
See [CREDITS.md](./CREDITS.md) See [CREDITS.md](./CREDITS.md)

View File

@ -2,6 +2,7 @@ add_subdirectory(catch2)
add_subdirectory(fmt) add_subdirectory(fmt)
add_subdirectory(icu) add_subdirectory(icu)
add_subdirectory(md5) add_subdirectory(md5)
add_subdirectory(monocypher)
add_subdirectory(squirrel) add_subdirectory(squirrel)
add_subdirectory(nlohmann) add_subdirectory(nlohmann)
add_subdirectory(opengl) add_subdirectory(opengl)

View File

@ -0,0 +1,63 @@
Designers
---------
- **ChaCha20:** Daniel J. Bernstein.
- **Poly1305:** Daniel J. Bernstein.
- **BLAKE2:** Jean-Philippe Aumasson, Christian Winnerlein, Samuel Neves,
and Zooko Wilcox-O'Hearn.
- **Argon2:** Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich.
- **X25519:** Daniel J. Bernstein.
- **EdDSA:** Daniel J. Bernstein, Bo-Yin Yang, Niels Duif, Peter
Schwabe, and Tanja Lange.
Implementors
------------
- **ChaCha20:** Loup Vaillant, implemented from spec.
- **Poly1305:** Loup Vaillant, implemented from spec.
- **BLAKE2b:** Loup Vaillant, implemented from spec.
- **Argon2i:** Loup Vaillant, implemented from spec.
- **X25519:** Daniel J. Bernstein, taken and packaged from SUPERCOP
ref10.
- **EdDSA:** Loup Vaillant, with bits and pieces from SUPERCOP ref10.
Test suite
----------
Designed and implemented by Loup Vaillant, using _libsodium_ (by many
authors), and _ed25519-donna_ (by Andrew Moon —floodyberry).
Manual
------
Loup Vaillant, Fabio Scotoni, and Michael Savage.
- Loup Vaillant did a first draft.
- Fabio Scotoni rewrote the manual into proper man pages (and
substantially changed it in the process).
- Michael Savage did extensive editing and proofreading.
Thanks
------
Fabio Scotoni provided much needed advice about testing, interface,
packaging, and the general direction of the whole project. He also
redesigned the monocypher.org style sheets.
Mike Pechkin and André Maroneze found bugs in earlier versions of
Monocypher.
Andrew Moon clarified carry propagation in modular arithmetic, and
provided advice and code that significantly simplified and improved
Elligator2 mappings.
Mike Hamburg explained comb algorithms, including the signed
all-bits-set comb described in his 2012 paper, Fast and compact
elliptic-curve cryptography. This made EdDSA signatures over twice as
fast.
Samuel Lucas found many typos in both the manual and the website.
Jens Alfke added some #ifdefs that enabled Monocypher to compile into
a C++ namespace, preventing symbol collisions with similarly-named
functions in other crypto libraries.

View File

@ -0,0 +1,295 @@
4.0.2
-----
2023/08/24
- Fixed multiple-lanes Argon2.
- Improved Poly1305 performance.
- Improved Argon2 performance.
- Makefiles no longer override standard environment variables.
4.0.1
-----
2023/03/06
- Fixed Ed25519 secret key size in function prototype.
- Fixed soname (should have been changed in 4.0.0)
- Added convenience sub-targets to makefile.
- Briefly specified wire format of Elligator and incremental AEAD.
4.0.0
-----
2023/02/20
- Fixed unsafe signature API.
- Simpler, more flexible low-level signature API.
- Fully specified, consensus-friendly signatures.
- Added Argon2d and Argon2id, support multiple lanes.
- Added safe and fast streaming AEAD.
- Added HKDF-SHA-512 and documented BLAKE2b KDF.
- More consistent and memorable function names.
- POSIX makefile.
3.1.3
-----
2022/04/25
- Fixed many typos in the documentation.
- Fixed buffer overflow in speed benchmarks.
- Fixed some MSVC warnings.
- Fixed a minor violation of the Elligator2 reverse map specs.
- Added `change-prefix.sh` to help changing the `crypto_` prefix.
- Added the `MONOCYPHER_CPP_NAMESPACE` preprocessor definition to
support namespaces for C++.
- Deprecated `crypto_key_exchange()`
- Use GitHub actions to automate the regular test suite.
3.1.2
-----
2020/12/27
- Addressed issues from Cure53's audit:
- MON-01-001: Clarified which CSPRNG to use on Darwin.
- MON-01-002: Won't fix (nonce handling is a core design decision).
- MON-01-004: Compared with Kleshni's implementation.
- MON-01-005: Split a dedicated "advanced" folder in the manual.
- Quality assurance for 2^255-19 arithmetic (elliptic curves):
- Documented carry propagation.
- Enforced slightly safer invariants.
- Improved the speed of EdDSA signature generation.
- Made the vectors.h header more compact and easier to modify.
- TIS-CI integration.
- Added speed benchmark for ed25519-donna.
- Documented lengths limits of `crypto_ietf_chacha20()`
3.1.1
-----
2020/06/15
- Various documentation fixes.
- Fixed various compiler warnings.
- Fixed some integer overflows (16-bit platforms only).
3.1.0
-----
2020/04/03
- Added Elligator 2 mappings (hash to curve, curve to hash).
- Added OPRF support (with scalar inversion).
- Added Edwards25519 -> Curve25519 conversions.
3.0.0
-----
2020/01/19
- Deprecated the incremental AEAD interface.
- Deprecated the incremental Chacha20, added a direct interface.
- Added IETF Chacha20 (96-bit nonce), as described in RFC 8439.
- Moved deprecated interfaces to a separate `src/deprecated` folder.
- Removed the `ED25519_SHA512` preprocessor flag.
- `crypto_x25519()` and `crypto_key_exchange()` now return `void`.
- Added a custom hash interface to EdDSA. Several instances of EdDSA
can share the same binary.
- Added optional support for HMAC SHA-512.
- Moved SHA-512 operations to `src/optional/monocypher-ed25519.(h|c)`.
- Optional support for Ed25519 no longer requires a preprocessor flag.
Add `src/optional/monocypher-ed25519.(h|c)` to your project instead.
2.0.6
-----
2019/10/21
- Added the `BLAKE2_NO_UNROLLING` preprocessor definition. Activating
it makes the binary about 5KB smaller and speeds up processing times
on many embedded processors.
- Reduced the stack usage of signature verification by about
40%. Signature verification now fits in smaller machines.
- Fixed many implicit casts warnings.
- Fixed the manual here and there.
- Lots of small nitpicks.
2.0.5
-----
2018/08/23
- Faster EdDSA signatures and verification. Like, 4 times as fast.
2.0.4
-----
2018/06/24
- Corrected a critical vulnerability found by Mike Pechkin in EdDSA,
where crypto_check() was accepting invalid signatures. The current
fix removes a buggy optimisation, effectively halving the performance
of EdDSA.
- The test suite no longer tries to allocate zero bytes (some platforms
fail such an allocation).
2.0.3
-----
2018/06/16
- Corrected undefined behaviour in BLAKE2b.
- Improved the test suite (faster, better coverage).
2.0.2
-----
2018/04/23
- Corrected a couple failures to wipe secret buffers.
- Corrected a bug that prevented compilation in Ed25519 mode.
- Adjusted the number of test vectors in the test suite.
- Improved tests for incremental interfaces.
- Replaced the GNU all permissive licence by a public domain dedication
(Creative Commons CC-0). The BSD licence remains as a fallback.
2.0.1
-----
2018/03/07
- Followed a systematic pattern for the loading code of symmetric
crypto. It is now easier to review.
- Tweaked Poly1305 code to make it easier to prove correct.
2.0.0
-----
2018/02/14
- Changed the authenticated encryption format. It now conforms to
RFC 7539, with one exception: it uses XChacha20 initialisation instead
of the IETF version of Chacha20. This new format conforms to
libsodium's `crypto_aead_xchacha20poly1305_ietf_encrypt`.
- Removed `crypto_lock_encrypt()` and `crypto_lock_auth()`.
- Renamed `crypto_lock_aead_auth()` to `crypto_lock_auth_ad()`.
- Renamed `crypto_unlock_aead_auth()` to `crypto_unlock_auth_ad()`.
- Added `crypto_lock_auth_message()` and `crypto_unlock_auth_message()`.
- Renamed `crypto_aead_lock` to `crypto_lock_aead`.
- Renamed `crypto_aead_unlock` to `crypto_unlock_aead`.
The format change facilitates optimisation by aligning data to block
boundaries. The API changes increase consistency.
1.1.0
-----
2018/02/06
- Rewrote the manual into proper man pages.
- Added incremental interfaces for authenticated encryption and
signatures.
- Replaced `crypto_memcmp()` by 3 fixed size buffer comparisons (16, 32,
and 64 bytes), to make sure the generated code remains constant time.
- A couple breaking API changes, easily fixed by renaming the affected
functions.
1.0.1
-----
2017/07/23
- Optimised the loading and unloading code of the symmetric crypto
(BLAKE2b, SHA-512, Chacha20, and Poly1305).
- Fused self-contained tests together for easier analysis with Frama-C
and the TIS interpreter.
1.0
---
2017/07/18
- Renamed `crypto_chacha20_Xinit` to `crypto_chacha20_x_init`, for
consistency reasons (snake case everywhere).
- Fixed signed integer overflow detected by UBSan.
- Doubled the speed of EdDSA by performing the scalar product in
Montgomery space.
0.8
---
2017/07/06
- Added about a hundred lines of code to improve performance of public
key cryptography. Diffie-Hellman is now 20% faster than before.
The effects are less pronounced for EdDSA.
- Added random self-consistency tests.
- Added a speed benchmark against libsodium.
0.7
---
2017/06/07
- Slightly changed the authenticated encryption API. Functions are
now all in "detached" mode. The reason is better support for
authenticated encryption _without_ additional data.
- Rewrote BLAKE2b from spec so it can use the same licence as
everything else.
- Added random tests that compare Monocypher with libsodium and
ed25519-donna.
- Added explicit support for Frama-C analysis (this doesn't affect the
source code).
0.6
---
2017/03/17
- Fixed incorrect Poly1305 output on empty messages. (Found by Mike
Pechkin.)
0.5
---
2017/03/10
- Fixed many undefined behaviours in Curve25519 that occur whenever
we perform a left shift on a signed negative integer. It doesn't
affect the generated code, but you never know. (Found with Frama-C
by André Maroneze.)
Fun fact: TweetNaCl and ref10 have the same bug. Libsodium has
corrected the issue, though.
For those who don't comprehend the magnitude of this madness, the
expression `-1 << 3` is undefined in C. This is explained in
section 6.5.7(§4) of the C11 standard.
0.4
---
2017/03/09
- Fixed critical bug causing Argon2i to fail whenever it uses more
than 512 blocks. It was reading uninitialised memory and the
results were incorrect. (Found by Mike Pechkin.)
- Fixed an undefined behaviour in Curve25519 (`fe_tobytes()`). It was
accessing uninitialised memory before throwing it away. It didn't
affect the compiled code nor the results, but you never know.
(Found with [Frama-C](http://frama-c.com) by André Maroneze.)
0.3
---
2017/02/27
- Got the invariants of Poly1305 right and put them in the comments.
There was no bug, but that was lucky (turned out the IETF test
vectors were designed to trigger the bugs I was afraid of).
- Simplified Poly1305 finalisation (replaced conditional subtraction
by a carry propagation).
- Made a few cosmetic changes here and there.
0.2
---
????/??/??
- Public interface significantly reworked. Removed redundant, hard to
mess up constructions.
- Added AEAD.
- Sped up Curve25519 by a factor of more than 6 (switched to ref10
arithmetic).
- Added various test vectors and completed the consistency tests.
0.1
---
2016/??/??

View File

@ -0,0 +1,6 @@
add_files(
monocypher-ed25519.cpp
monocypher-ed25519.h
monocypher.cpp
monocypher.h
)

View File

@ -0,0 +1,167 @@
Monocypher as a whole is dual-licensed. Choose whichever licence you
want from the two licences listed below.
The first licence is a regular 2-clause BSD licence. The second licence
is the CC-0 from Creative Commons. It is intended to release Monocypher
to the public domain. The BSD licence serves as a fallback option.
See the individual files for specific information about who contributed
to what file during which years. See below for special notes.
Licence 1 (2-clause BSD)
------------------------
Copyright (c) 2017-2023, Loup Vaillant
Copyright (c) 2017-2019, Michael Savage
Copyright (c) 2017-2023, Fabio Scotoni
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Licence 2 (CC-0)
----------------
> CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
> LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
> ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
> INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
> REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
> PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
> THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
> HEREUNDER.
### Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work
of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without
fear of later claims of infringement build upon, modify, incorporate in
other works, reuse and redistribute as freely as possible in any form
whatsoever and for any purposes, including without limitation commercial
purposes. These owners may contribute to the Commons to promote the
ideal of a free culture and the further production of creative, cultural
and scientific works, or to gain reputation or greater distribution for
their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or
she is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under
its terms, with knowledge of his or her Copyright and Related Rights in
the Work and the meaning and intended legal effect of CC0 on those
rights.
1. **Copyright and Related Rights.** A Work made available under CC0 may
be protected by copyright and related or neighboring rights
("Copyright and Related Rights"). Copyright and Related Rights
include, but are not limited to, the following:
- the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
- moral rights retained by the original author(s) and/or
performer(s); publicity and privacy rights pertaining to a person's
image or likeness depicted in a Work;
- rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
- rights protecting the extraction, dissemination, use and reuse of
data in a Work;
- database rights (such as those arising under Directive 96/9/EC of
the European Parliament and of the Council of 11 March 1996 on the
legal protection of databases, and under any national
implementation thereof, including any amended or successor version
of such directive); and
- other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. **Waiver.** To the greatest extent permitted by, but not in
contravention of, applicable law, Affirmer hereby overtly, fully,
permanently, irrevocably and unconditionally waives, abandons, and
surrenders all of Affirmer's Copyright and Related Rights and
associated claims and causes of action, whether now known or unknown
(including existing as well as future claims and causes of action),
in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"Waiver"). Affirmer makes the Waiver for the benefit of each member
of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal
or equitable action to disrupt the quiet enjoyment of the Work by the
public as contemplated by Affirmer's express Statement of Purpose.
3. **Public License Fallback.** Should any part of the Waiver for any
reason be judged legally invalid or ineffective under applicable law,
then the Waiver shall be preserved to the maximum extent permitted
taking into account Affirmer's express Statement of Purpose. In
addition, to the extent the Waiver is so judged Affirmer hereby
grants to each affected person a royalty-free, non transferable, non
sublicensable, non exclusive, irrevocable and unconditional license
to exercise Affirmer's Copyright and Related Rights in the Work (i)
in all territories worldwide, (ii) for the maximum duration provided
by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and
(iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "License"). The
License shall be deemed effective as of the date CC0 was applied by
Affirmer to the Work. Should any part of the License for any reason
be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the
remainder of the License, and in such case Affirmer hereby affirms
that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any
associated claims and causes of action with respect to the Work, in
either case contrary to Affirmer's express Statement of Purpose.
4. **Limitations and Disclaimers.**
- No trademark or patent rights held by Affirmer are waived,
abandoned, surrendered, licensed or otherwise affected by this
document.
- Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy,
or the present or absence of errors, whether or not discoverable,
all to the greatest extent permissible under applicable law.
- Affirmer disclaims responsibility for clearing rights of other
persons that may apply to the Work or any use thereof, including
without limitation any person's Copyright and Related Rights in the
Work. Further, Affirmer disclaims responsibility for obtaining any
necessary consents, permissions or other rights required for any
use of the Work.
- Affirmer understands and acknowledges that Creative Commons is not
a party to this document and has no duty or obligation with respect
to this CC0 or use of the Work.

164
src/3rdparty/monocypher/README.md vendored 100644
View File

@ -0,0 +1,164 @@
Monocypher
----------
Monocypher is an easy to use, easy to deploy, auditable crypto library
written in portable C. It approaches the size of [TweetNaCl][] and the
speed of [libsodium][].
[Official site.](https://monocypher.org/)
[Official releases.](https://monocypher.org/download/)
[libsodium]: https://libsodium.org
[TweetNaCl]: https://tweetnacl.cr.yp.to/
Features
--------
- [Authenticated Encryption][AEAD] with XChaCha20 and Poly1305
(RFC 8439).
- [Hashing and key derivation][HASH] with BLAKE2b (and [SHA-512][]).
- [Password Hashing][PWH] with Argon2.
- [Public Key Cryptography][PKC] with X25519 key exchanges.
- [Public Key Signatures][EDDSA] with EdDSA and [Ed25519][].
- [Steganography and PAKE][STEG] with [Elligator 2][ELLI].
[AEAD]: https://monocypher.org/manual/aead
[HASH]: https://monocypher.org/manual/blake2
[SHA-512]: https://monocypher.org/manual/sha-512
[PWH]: https://monocypher.org/manual/argon2
[PKC]: https://monocypher.org/manual/x25519
[EDDSA]: https://monocypher.org/manual/eddsa
[Ed25519]: https://monocypher.org/manual/ed25519
[STEG]: https://monocypher.org/manual/elligator
[ELLI]: https://elligator.org
Manual
------
The manual can be found at https://monocypher.org/manual/, and in the
`doc/` folder.
Installation
------------
### Option 1: grab the sources
The easiest way to use Monocypher is to include `src/monocypher.h` and
`src/monocypher.c` directly into your project. They compile as C (since
C99) and C++ (since C++98).
If you need the optional SHA-512 or Ed25519, grab
`src/optional/monocypher-ed25519.h` and
`src/optional/monocypher-ed25519.c` as well.
### Option 2: grab the library
Run `make`, then grab the `src/monocypher.h` header and either the
`lib/libmonocypher.a` or `lib/libmonocypher.so` library. The default
compiler is `gcc -std=c99`, and the default flags are `-pedantic -Wall
-Wextra -O3 -march=native`. If they don't work on your platform, you
can change them like this:
$ make CC="clang -std=c11" CFLAGS="-O2"
### Option 3: install it on your system
Run `make`, then `make install` as root. This will install Monocypher in
`/usr/local` by default. This can be changed with `PREFIX` and
`DESTDIR`:
$ make install PREFIX="/opt"
Once installed, you may use `pkg-config` to compile and link your
program. For instance:
$ gcc program.c $(pkg-config monocypher --cflags) -c
$ gcc program.o $(pkg-config monocypher --libs) -o program
If for any reason you wish to avoid installing the man pages or the
`pkg-config` file, you can use the following installation sub targets
instead: `install-lib`, `install-doc`, and `install-pc`.
Test suite
----------
$ make test
It should display a nice printout of all the tests, ending with "All
tests OK!". If you see "failure" or "Error" anywhere, something has gone
wrong.
*Do not* use Monocypher without running those tests at least once.
The same test suite can be run under Clang sanitisers and Valgrind, and
be checked for code coverage:
$ tests/test.sh
$ tests/coverage.sh
### Serious auditing
The code may be analysed more formally with [Frama-c][] and the
[TIS interpreter][TIS]. To analyse the code with Frama-c, run:
$ tests/formal-analysis.sh
$ tests/frama-c.sh
This will have Frama-c parse, and analyse the code, then launch a GUI.
You must have Frama-c installed. See `frama-c.sh` for the recommended
settings. To run the code under the TIS interpreter, run
$ tests/formal-analysis.sh
$ tis-interpreter.sh --cc -Dvolatile= tests/formal-analysis/*.c
Notes:
- `tis-interpreter.sh` is part of TIS. If it is not in your path,
adjust the command accordingly.
- The TIS interpreter sometimes fails to evaluate correct programs when
they use the `volatile` keyword (which is only used as an attempt to
prevent dead store elimination for memory wipes). The `-cc
-Dvolatile=` option works around that bug by ignoring `volatile`
altogether.
[Frama-c]:https://frama-c.com/
[TIS]: https://trust-in-soft.com/tis-interpreter/
Customisation
-------------
Monocypher has optional compatibility with Ed25519. To have that, add
`monocypher-ed25519.h` and `monocypher-ed25519.c` provided in
`src/optional` to your project. If you compile or install Monocypher
with the makefile, they will be automatically included.
Monocypher also has the `BLAKE2_NO_UNROLLING` preprocessor flag, which
is activated by compiling monocypher.c with the `-DBLAKE2_NO_UNROLLING`
option.
The `-DBLAKE2_NO_UNROLLING` option is a performance tweak. By default,
Monocypher unrolls the BLAKE2b inner loop, because doing so is over 25%
faster on modern processors. Some embedded processors however, run the
unrolled loop _slower_ (possibly because of the cost of fetching 5KB of
additional code). If you're using an embedded platform, try this
option. The binary will be about 5KB smaller, and in some cases faster.
The `MONOCYPHER_CPP_NAMESPACE` preprocessor definition allows C++ users
who compile Monocypher as C++ to wrap it in a namespace. When it is not
defined (the default), we assume Monocypher is compiled as C, and an
`extern "C"` declaration is added when we detect that the header is
included in C++ code.
The `change-prefix.sh` script can rename all functions by replacing
`crypto_` by a chosen prefix, so you can avoid name clashes. For
instance, the following command changes all instances of `crypto_` by
`foobar_` (note the absence of the underscore):
./change-prefix.sh foobar

View File

@ -0,0 +1,500 @@
// Monocypher version 4.0.2
//
// This file is dual-licensed. Choose whichever licence you want from
// the two licences listed below.
//
// The first licence is a regular 2-clause BSD licence. The second licence
// is the CC-0 from Creative Commons. It is intended to release Monocypher
// to the public domain. The BSD licence serves as a fallback option.
//
// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
//
// ------------------------------------------------------------------------
//
// Copyright (c) 2017-2019, Loup Vaillant
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ------------------------------------------------------------------------
//
// Written in 2017-2019 by Loup Vaillant
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see
// <https://creativecommons.org/publicdomain/zero/1.0/>
#include "monocypher-ed25519.h"
#ifdef MONOCYPHER_CPP_NAMESPACE
namespace MONOCYPHER_CPP_NAMESPACE {
#endif
/////////////////
/// Utilities ///
/////////////////
#define FOR(i, min, max) for (size_t i = min; i < max; i++)
#define COPY(dst, src, size) FOR(_i_, 0, size) (dst)[_i_] = (src)[_i_]
#define ZERO(buf, size) FOR(_i_, 0, size) (buf)[_i_] = 0
#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx)))
#define WIPE_BUFFER(buffer) crypto_wipe(buffer, sizeof(buffer))
#define MC_MIN(a, b) ((a) <= (b) ? (a) : (b))
typedef uint8_t u8;
typedef uint64_t u64;
// Returns the smallest positive integer y such that
// (x + y) % pow_2 == 0
// Basically, it's how many bytes we need to add to "align" x.
// Only works when pow_2 is a power of 2.
// Note: we use ~x+1 instead of -x to avoid compiler warnings
static size_t align(size_t x, size_t pow_2)
{
return (~x + 1) & (pow_2 - 1);
}
static u64 load64_be(const u8 s[8])
{
return((u64)s[0] << 56)
| ((u64)s[1] << 48)
| ((u64)s[2] << 40)
| ((u64)s[3] << 32)
| ((u64)s[4] << 24)
| ((u64)s[5] << 16)
| ((u64)s[6] << 8)
| (u64)s[7];
}
static void store64_be(u8 out[8], u64 in)
{
out[0] = (in >> 56) & 0xff;
out[1] = (in >> 48) & 0xff;
out[2] = (in >> 40) & 0xff;
out[3] = (in >> 32) & 0xff;
out[4] = (in >> 24) & 0xff;
out[5] = (in >> 16) & 0xff;
out[6] = (in >> 8) & 0xff;
out[7] = in & 0xff;
}
static void load64_be_buf (u64 *dst, const u8 *src, size_t size) {
FOR(i, 0, size) { dst[i] = load64_be(src + i*8); }
}
///////////////
/// SHA 512 ///
///////////////
static u64 rot(u64 x, int c ) { return (x >> c) | (x << (64 - c)); }
static u64 ch (u64 x, u64 y, u64 z) { return (x & y) ^ (~x & z); }
static u64 maj(u64 x, u64 y, u64 z) { return (x & y) ^ ( x & z) ^ (y & z); }
static u64 big_sigma0(u64 x) { return rot(x, 28) ^ rot(x, 34) ^ rot(x, 39); }
static u64 big_sigma1(u64 x) { return rot(x, 14) ^ rot(x, 18) ^ rot(x, 41); }
static u64 lit_sigma0(u64 x) { return rot(x, 1) ^ rot(x, 8) ^ (x >> 7); }
static u64 lit_sigma1(u64 x) { return rot(x, 19) ^ rot(x, 61) ^ (x >> 6); }
static const u64 K[80] = {
0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc,
0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118,
0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694,
0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65,
0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5,
0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70,
0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df,
0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b,
0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30,
0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec,
0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b,
0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178,
0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b,
0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c,
0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817
};
static void sha512_compress(crypto_sha512_ctx *ctx)
{
u64 a = ctx->hash[0]; u64 b = ctx->hash[1];
u64 c = ctx->hash[2]; u64 d = ctx->hash[3];
u64 e = ctx->hash[4]; u64 f = ctx->hash[5];
u64 g = ctx->hash[6]; u64 h = ctx->hash[7];
FOR (j, 0, 16) {
u64 in = K[j] + ctx->input[j];
u64 t1 = big_sigma1(e) + ch (e, f, g) + h + in;
u64 t2 = big_sigma0(a) + maj(a, b, c);
h = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
size_t i16 = 0;
FOR(i, 1, 5) {
i16 += 16;
FOR (j, 0, 16) {
ctx->input[j] += lit_sigma1(ctx->input[(j- 2) & 15]);
ctx->input[j] += lit_sigma0(ctx->input[(j-15) & 15]);
ctx->input[j] += ctx->input[(j- 7) & 15];
u64 in = K[i16 + j] + ctx->input[j];
u64 t1 = big_sigma1(e) + ch (e, f, g) + h + in;
u64 t2 = big_sigma0(a) + maj(a, b, c);
h = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
}
ctx->hash[0] += a; ctx->hash[1] += b;
ctx->hash[2] += c; ctx->hash[3] += d;
ctx->hash[4] += e; ctx->hash[5] += f;
ctx->hash[6] += g; ctx->hash[7] += h;
}
// Write 1 input byte
static void sha512_set_input(crypto_sha512_ctx *ctx, u8 input)
{
size_t word = ctx->input_idx >> 3;
size_t byte = ctx->input_idx & 7;
ctx->input[word] |= (u64)input << (8 * (7 - byte));
}
// Increment a 128-bit "word".
static void sha512_incr(u64 x[2], u64 y)
{
x[1] += y;
if (x[1] < y) {
x[0]++;
}
}
void crypto_sha512_init(crypto_sha512_ctx *ctx)
{
ctx->hash[0] = 0x6a09e667f3bcc908;
ctx->hash[1] = 0xbb67ae8584caa73b;
ctx->hash[2] = 0x3c6ef372fe94f82b;
ctx->hash[3] = 0xa54ff53a5f1d36f1;
ctx->hash[4] = 0x510e527fade682d1;
ctx->hash[5] = 0x9b05688c2b3e6c1f;
ctx->hash[6] = 0x1f83d9abfb41bd6b;
ctx->hash[7] = 0x5be0cd19137e2179;
ctx->input_size[0] = 0;
ctx->input_size[1] = 0;
ctx->input_idx = 0;
ZERO(ctx->input, 16);
}
void crypto_sha512_update(crypto_sha512_ctx *ctx,
const u8 *message, size_t message_size)
{
// Avoid undefined NULL pointer increments with empty messages
if (message_size == 0) {
return;
}
// Align ourselves with word boundaries
if ((ctx->input_idx & 7) != 0) {
size_t nb_bytes = MC_MIN(align(ctx->input_idx, 8), message_size);
FOR (i, 0, nb_bytes) {
sha512_set_input(ctx, message[i]);
ctx->input_idx++;
}
message += nb_bytes;
message_size -= nb_bytes;
}
// Align ourselves with block boundaries
if ((ctx->input_idx & 127) != 0) {
size_t nb_words = MC_MIN(align(ctx->input_idx, 128), message_size) >> 3;
load64_be_buf(ctx->input + (ctx->input_idx >> 3), message, nb_words);
ctx->input_idx += nb_words << 3;
message += nb_words << 3;
message_size -= nb_words << 3;
}
// Compress block if needed
if (ctx->input_idx == 128) {
sha512_incr(ctx->input_size, 1024); // size is in bits
sha512_compress(ctx);
ctx->input_idx = 0;
ZERO(ctx->input, 16);
}
// Process the message block by block
FOR (i, 0, message_size >> 7) { // number of blocks
load64_be_buf(ctx->input, message, 16);
sha512_incr(ctx->input_size, 1024); // size is in bits
sha512_compress(ctx);
ctx->input_idx = 0;
ZERO(ctx->input, 16);
message += 128;
}
message_size &= 127;
if (message_size != 0) {
// Remaining words
size_t nb_words = message_size >> 3;
load64_be_buf(ctx->input, message, nb_words);
ctx->input_idx += nb_words << 3;
message += nb_words << 3;
message_size -= nb_words << 3;
// Remaining bytes
FOR (i, 0, message_size) {
sha512_set_input(ctx, message[i]);
ctx->input_idx++;
}
}
}
void crypto_sha512_final(crypto_sha512_ctx *ctx, u8 hash[64])
{
// Add padding bit
if (ctx->input_idx == 0) {
ZERO(ctx->input, 16);
}
sha512_set_input(ctx, 128);
// Update size
sha512_incr(ctx->input_size, ctx->input_idx * 8);
// Compress penultimate block (if any)
if (ctx->input_idx > 111) {
sha512_compress(ctx);
ZERO(ctx->input, 14);
}
// Compress last block
ctx->input[14] = ctx->input_size[0];
ctx->input[15] = ctx->input_size[1];
sha512_compress(ctx);
// Copy hash to output (big endian)
FOR (i, 0, 8) {
store64_be(hash + i*8, ctx->hash[i]);
}
WIPE_CTX(ctx);
}
void crypto_sha512(u8 hash[64], const u8 *message, size_t message_size)
{
crypto_sha512_ctx ctx;
crypto_sha512_init (&ctx);
crypto_sha512_update(&ctx, message, message_size);
crypto_sha512_final (&ctx, hash);
}
////////////////////
/// HMAC SHA 512 ///
////////////////////
void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
const u8 *key, size_t key_size)
{
// hash key if it is too long
if (key_size > 128) {
crypto_sha512(ctx->key, key, key_size);
key = ctx->key;
key_size = 64;
}
// Compute inner key: padded key XOR 0x36
FOR (i, 0, key_size) { ctx->key[i] = key[i] ^ 0x36; }
FOR (i, key_size, 128) { ctx->key[i] = 0x36; }
// Start computing inner hash
crypto_sha512_init (&ctx->ctx);
crypto_sha512_update(&ctx->ctx, ctx->key, 128);
}
void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
const u8 *message, size_t message_size)
{
crypto_sha512_update(&ctx->ctx, message, message_size);
}
void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, u8 hmac[64])
{
// Finish computing inner hash
crypto_sha512_final(&ctx->ctx, hmac);
// Compute outer key: padded key XOR 0x5c
FOR (i, 0, 128) {
ctx->key[i] ^= 0x36 ^ 0x5c;
}
// Compute outer hash
crypto_sha512_init (&ctx->ctx);
crypto_sha512_update(&ctx->ctx, ctx->key , 128);
crypto_sha512_update(&ctx->ctx, hmac, 64);
crypto_sha512_final (&ctx->ctx, hmac); // outer hash
WIPE_CTX(ctx);
}
void crypto_sha512_hmac(u8 hmac[64], const u8 *key, size_t key_size,
const u8 *message, size_t message_size)
{
crypto_sha512_hmac_ctx ctx;
crypto_sha512_hmac_init (&ctx, key, key_size);
crypto_sha512_hmac_update(&ctx, message, message_size);
crypto_sha512_hmac_final (&ctx, hmac);
}
////////////////////
/// HKDF SHA 512 ///
////////////////////
void crypto_sha512_hkdf_expand(u8 *okm, size_t okm_size,
const u8 *prk, size_t prk_size,
const u8 *info, size_t info_size)
{
int not_first = 0;
u8 ctr = 1;
u8 blk[64];
while (okm_size > 0) {
size_t out_size = MC_MIN(okm_size, sizeof(blk));
crypto_sha512_hmac_ctx ctx;
crypto_sha512_hmac_init(&ctx, prk , prk_size);
if (not_first) {
// For some reason HKDF uses some kind of CBC mode.
// For some reason CTR mode alone wasn't enough.
// Like what, they didn't trust HMAC in 2010? Really??
crypto_sha512_hmac_update(&ctx, blk , sizeof(blk));
}
crypto_sha512_hmac_update(&ctx, info, info_size);
crypto_sha512_hmac_update(&ctx, &ctr, 1);
crypto_sha512_hmac_final(&ctx, blk);
COPY(okm, blk, out_size);
not_first = 1;
okm += out_size;
okm_size -= out_size;
ctr++;
}
}
void crypto_sha512_hkdf(u8 *okm , size_t okm_size,
const u8 *ikm , size_t ikm_size,
const u8 *salt, size_t salt_size,
const u8 *info, size_t info_size)
{
// Extract
u8 prk[64];
crypto_sha512_hmac(prk, salt, salt_size, ikm, ikm_size);
// Expand
crypto_sha512_hkdf_expand(okm, okm_size, prk, sizeof(prk), info, info_size);
}
///////////////
/// Ed25519 ///
///////////////
void crypto_ed25519_key_pair(u8 secret_key[64], u8 public_key[32], u8 seed[32])
{
u8 a[64];
COPY(a, seed, 32); // a[ 0..31] = seed
crypto_wipe(seed, 32);
COPY(secret_key, a, 32); // secret key = seed
crypto_sha512(a, a, 32); // a[ 0..31] = scalar
crypto_eddsa_trim_scalar(a, a); // a[ 0..31] = trimmed scalar
crypto_eddsa_scalarbase(public_key, a); // public key = [trimmed scalar]B
COPY(secret_key + 32, public_key, 32); // secret key includes public half
WIPE_BUFFER(a);
}
static void hash_reduce(u8 h[32],
const u8 *a, size_t a_size,
const u8 *b, size_t b_size,
const u8 *c, size_t c_size,
const u8 *d, size_t d_size)
{
u8 hash[64];
crypto_sha512_ctx ctx;
crypto_sha512_init (&ctx);
crypto_sha512_update(&ctx, a, a_size);
crypto_sha512_update(&ctx, b, b_size);
crypto_sha512_update(&ctx, c, c_size);
crypto_sha512_update(&ctx, d, d_size);
crypto_sha512_final (&ctx, hash);
crypto_eddsa_reduce(h, hash);
}
static void ed25519_dom_sign(u8 signature [64], const u8 secret_key[32],
const u8 *dom, size_t dom_size,
const u8 *message, size_t message_size)
{
u8 a[64]; // secret scalar and prefix
u8 r[32]; // secret deterministic "random" nonce
u8 h[32]; // publically verifiable hash of the message (not wiped)
u8 R[32]; // first half of the signature (allows overlapping inputs)
const u8 *pk = secret_key + 32;
crypto_sha512(a, secret_key, 32);
crypto_eddsa_trim_scalar(a, a);
hash_reduce(r, dom, dom_size, a + 32, 32, message, message_size, 0, 0);
crypto_eddsa_scalarbase(R, r);
hash_reduce(h, dom, dom_size, R, 32, pk, 32, message, message_size);
COPY(signature, R, 32);
crypto_eddsa_mul_add(signature + 32, h, a, r);
WIPE_BUFFER(a);
WIPE_BUFFER(r);
}
void crypto_ed25519_sign(u8 signature [64], const u8 secret_key[64],
const u8 *message, size_t message_size)
{
ed25519_dom_sign(signature, secret_key, 0, 0, message, message_size);
}
int crypto_ed25519_check(const u8 signature[64], const u8 public_key[32],
const u8 *msg, size_t msg_size)
{
u8 h_ram[32];
hash_reduce(h_ram, signature, 32, public_key, 32, msg, msg_size, 0, 0);
return crypto_eddsa_check_equation(signature, public_key, h_ram);
}
static const u8 domain[34] = "SigEd25519 no Ed25519 collisions\1";
void crypto_ed25519_ph_sign(uint8_t signature[64], const uint8_t secret_key[64],
const uint8_t message_hash[64])
{
ed25519_dom_sign(signature, secret_key, domain, sizeof(domain),
message_hash, 64);
}
int crypto_ed25519_ph_check(const uint8_t sig[64], const uint8_t pk[32],
const uint8_t msg_hash[64])
{
u8 h_ram[32];
hash_reduce(h_ram, domain, sizeof(domain), sig, 32, pk, 32, msg_hash, 64);
return crypto_eddsa_check_equation(sig, pk, h_ram);
}
#ifdef MONOCYPHER_CPP_NAMESPACE
}
#endif

View File

@ -0,0 +1,140 @@
// Monocypher version 4.0.2
//
// This file is dual-licensed. Choose whichever licence you want from
// the two licences listed below.
//
// The first licence is a regular 2-clause BSD licence. The second licence
// is the CC-0 from Creative Commons. It is intended to release Monocypher
// to the public domain. The BSD licence serves as a fallback option.
//
// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
//
// ------------------------------------------------------------------------
//
// Copyright (c) 2017-2019, Loup Vaillant
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ------------------------------------------------------------------------
//
// Written in 2017-2019 by Loup Vaillant
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see
// <https://creativecommons.org/publicdomain/zero/1.0/>
#ifndef ED25519_H
#define ED25519_H
#include "monocypher.h"
#ifdef MONOCYPHER_CPP_NAMESPACE
namespace MONOCYPHER_CPP_NAMESPACE {
#elif defined(__cplusplus)
extern "C" {
#endif
////////////////////////
/// Type definitions ///
////////////////////////
// Do not rely on the size or content on any of those types,
// they may change without notice.
typedef struct {
uint64_t hash[8];
uint64_t input[16];
uint64_t input_size[2];
size_t input_idx;
} crypto_sha512_ctx;
typedef struct {
uint8_t key[128];
crypto_sha512_ctx ctx;
} crypto_sha512_hmac_ctx;
// SHA 512
// -------
void crypto_sha512_init (crypto_sha512_ctx *ctx);
void crypto_sha512_update(crypto_sha512_ctx *ctx,
const uint8_t *message, size_t message_size);
void crypto_sha512_final (crypto_sha512_ctx *ctx, uint8_t hash[64]);
void crypto_sha512(uint8_t hash[64],
const uint8_t *message, size_t message_size);
// SHA 512 HMAC
// ------------
void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
const uint8_t *key, size_t key_size);
void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
const uint8_t *message, size_t message_size);
void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, uint8_t hmac[64]);
void crypto_sha512_hmac(uint8_t hmac[64],
const uint8_t *key , size_t key_size,
const uint8_t *message, size_t message_size);
// SHA 512 HKDF
// ------------
void crypto_sha512_hkdf_expand(uint8_t *okm, size_t okm_size,
const uint8_t *prk, size_t prk_size,
const uint8_t *info, size_t info_size);
void crypto_sha512_hkdf(uint8_t *okm , size_t okm_size,
const uint8_t *ikm , size_t ikm_size,
const uint8_t *salt, size_t salt_size,
const uint8_t *info, size_t info_size);
// Ed25519
// -------
// Signatures (EdDSA with curve25519 + SHA-512)
// --------------------------------------------
void crypto_ed25519_key_pair(uint8_t secret_key[64],
uint8_t public_key[32],
uint8_t seed[32]);
void crypto_ed25519_sign(uint8_t signature [64],
const uint8_t secret_key[64],
const uint8_t *message, size_t message_size);
int crypto_ed25519_check(const uint8_t signature [64],
const uint8_t public_key[32],
const uint8_t *message, size_t message_size);
// Pre-hash variants
void crypto_ed25519_ph_sign(uint8_t signature [64],
const uint8_t secret_key [64],
const uint8_t message_hash[64]);
int crypto_ed25519_ph_check(const uint8_t signature [64],
const uint8_t public_key [32],
const uint8_t message_hash[64]);
#ifdef __cplusplus
}
#endif
#endif // ED25519_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,321 @@
// Monocypher version 4.0.2
//
// This file is dual-licensed. Choose whichever licence you want from
// the two licences listed below.
//
// The first licence is a regular 2-clause BSD licence. The second licence
// is the CC-0 from Creative Commons. It is intended to release Monocypher
// to the public domain. The BSD licence serves as a fallback option.
//
// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
//
// ------------------------------------------------------------------------
//
// Copyright (c) 2017-2019, Loup Vaillant
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ------------------------------------------------------------------------
//
// Written in 2017-2019 by Loup Vaillant
//
// To the extent possible under law, the author(s) have dedicated all copyright
// and related neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this software. If not, see
// <https://creativecommons.org/publicdomain/zero/1.0/>
#ifndef MONOCYPHER_H
#define MONOCYPHER_H
#include <stddef.h>
#include <stdint.h>
#ifdef MONOCYPHER_CPP_NAMESPACE
namespace MONOCYPHER_CPP_NAMESPACE {
#elif defined(__cplusplus)
extern "C" {
#endif
// Constant time comparisons
// -------------------------
// Return 0 if a and b are equal, -1 otherwise
int crypto_verify16(const uint8_t a[16], const uint8_t b[16]);
int crypto_verify32(const uint8_t a[32], const uint8_t b[32]);
int crypto_verify64(const uint8_t a[64], const uint8_t b[64]);
// Erase sensitive data
// --------------------
void crypto_wipe(void *secret, size_t size);
// Authenticated encryption
// ------------------------
void crypto_aead_lock(uint8_t *cipher_text,
uint8_t mac [16],
const uint8_t key [32],
const uint8_t nonce[24],
const uint8_t *ad, size_t ad_size,
const uint8_t *plain_text, size_t text_size);
int crypto_aead_unlock(uint8_t *plain_text,
const uint8_t mac [16],
const uint8_t key [32],
const uint8_t nonce[24],
const uint8_t *ad, size_t ad_size,
const uint8_t *cipher_text, size_t text_size);
// Authenticated stream
// --------------------
typedef struct {
uint64_t counter;
uint8_t key[32];
uint8_t nonce[8];
} crypto_aead_ctx;
void crypto_aead_init_x(crypto_aead_ctx *ctx,
const uint8_t key[32], const uint8_t nonce[24]);
void crypto_aead_init_djb(crypto_aead_ctx *ctx,
const uint8_t key[32], const uint8_t nonce[8]);
void crypto_aead_init_ietf(crypto_aead_ctx *ctx,
const uint8_t key[32], const uint8_t nonce[12]);
void crypto_aead_write(crypto_aead_ctx *ctx,
uint8_t *cipher_text,
uint8_t mac[16],
const uint8_t *ad , size_t ad_size,
const uint8_t *plain_text, size_t text_size);
int crypto_aead_read(crypto_aead_ctx *ctx,
uint8_t *plain_text,
const uint8_t mac[16],
const uint8_t *ad , size_t ad_size,
const uint8_t *cipher_text, size_t text_size);
// General purpose hash (BLAKE2b)
// ------------------------------
// Direct interface
void crypto_blake2b(uint8_t *hash, size_t hash_size,
const uint8_t *message, size_t message_size);
void crypto_blake2b_keyed(uint8_t *hash, size_t hash_size,
const uint8_t *key, size_t key_size,
const uint8_t *message, size_t message_size);
// Incremental interface
typedef struct {
// Do not rely on the size or contents of this type,
// for they may change without notice.
uint64_t hash[8];
uint64_t input_offset[2];
uint64_t input[16];
size_t input_idx;
size_t hash_size;
} crypto_blake2b_ctx;
void crypto_blake2b_init(crypto_blake2b_ctx *ctx, size_t hash_size);
void crypto_blake2b_keyed_init(crypto_blake2b_ctx *ctx, size_t hash_size,
const uint8_t *key, size_t key_size);
void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
const uint8_t *message, size_t message_size);
void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *hash);
// Password key derivation (Argon2)
// --------------------------------
#define CRYPTO_ARGON2_D 0
#define CRYPTO_ARGON2_I 1
#define CRYPTO_ARGON2_ID 2
typedef struct {
uint32_t algorithm; // Argon2d, Argon2i, Argon2id
uint32_t nb_blocks; // memory hardness, >= 8 * nb_lanes
uint32_t nb_passes; // CPU hardness, >= 1 (>= 3 recommended for Argon2i)
uint32_t nb_lanes; // parallelism level (single threaded anyway)
} crypto_argon2_config;
typedef struct {
const uint8_t *pass;
const uint8_t *salt;
uint32_t pass_size;
uint32_t salt_size; // 16 bytes recommended
} crypto_argon2_inputs;
typedef struct {
const uint8_t *key; // may be NULL if no key
const uint8_t *ad; // may be NULL if no additional data
uint32_t key_size; // 0 if no key (32 bytes recommended otherwise)
uint32_t ad_size; // 0 if no additional data
} crypto_argon2_extras;
extern const crypto_argon2_extras crypto_argon2_no_extras;
void crypto_argon2(uint8_t *hash, uint32_t hash_size, void *work_area,
crypto_argon2_config config,
crypto_argon2_inputs inputs,
crypto_argon2_extras extras);
// Key exchange (X-25519)
// ----------------------
// Shared secrets are not quite random.
// Hash them to derive an actual shared key.
void crypto_x25519_public_key(uint8_t public_key[32],
const uint8_t secret_key[32]);
void crypto_x25519(uint8_t raw_shared_secret[32],
const uint8_t your_secret_key [32],
const uint8_t their_public_key [32]);
// Conversion to EdDSA
void crypto_x25519_to_eddsa(uint8_t eddsa[32], const uint8_t x25519[32]);
// scalar "division"
// Used for OPRF. Be aware that exponential blinding is less secure
// than Diffie-Hellman key exchange.
void crypto_x25519_inverse(uint8_t blind_salt [32],
const uint8_t private_key[32],
const uint8_t curve_point[32]);
// "Dirty" versions of x25519_public_key().
// Use with crypto_elligator_rev().
// Leaks 3 bits of the private key.
void crypto_x25519_dirty_small(uint8_t pk[32], const uint8_t sk[32]);
void crypto_x25519_dirty_fast (uint8_t pk[32], const uint8_t sk[32]);
// Signatures
// ----------
// EdDSA with curve25519 + BLAKE2b
void crypto_eddsa_key_pair(uint8_t secret_key[64],
uint8_t public_key[32],
uint8_t seed[32]);
void crypto_eddsa_sign(uint8_t signature [64],
const uint8_t secret_key[64],
const uint8_t *message, size_t message_size);
int crypto_eddsa_check(const uint8_t signature [64],
const uint8_t public_key[32],
const uint8_t *message, size_t message_size);
// Conversion to X25519
void crypto_eddsa_to_x25519(uint8_t x25519[32], const uint8_t eddsa[32]);
// EdDSA building blocks
void crypto_eddsa_trim_scalar(uint8_t out[32], const uint8_t in[32]);
void crypto_eddsa_reduce(uint8_t reduced[32], const uint8_t expanded[64]);
void crypto_eddsa_mul_add(uint8_t r[32],
const uint8_t a[32],
const uint8_t b[32],
const uint8_t c[32]);
void crypto_eddsa_scalarbase(uint8_t point[32], const uint8_t scalar[32]);
int crypto_eddsa_check_equation(const uint8_t signature[64],
const uint8_t public_key[32],
const uint8_t h_ram[32]);
// Chacha20
// --------
// Specialised hash.
// Used to hash X25519 shared secrets.
void crypto_chacha20_h(uint8_t out[32],
const uint8_t key[32],
const uint8_t in [16]);
// Unauthenticated stream cipher.
// Don't forget to add authentication.
uint64_t crypto_chacha20_djb(uint8_t *cipher_text,
const uint8_t *plain_text,
size_t text_size,
const uint8_t key[32],
const uint8_t nonce[8],
uint64_t ctr);
uint32_t crypto_chacha20_ietf(uint8_t *cipher_text,
const uint8_t *plain_text,
size_t text_size,
const uint8_t key[32],
const uint8_t nonce[12],
uint32_t ctr);
uint64_t crypto_chacha20_x(uint8_t *cipher_text,
const uint8_t *plain_text,
size_t text_size,
const uint8_t key[32],
const uint8_t nonce[24],
uint64_t ctr);
// Poly 1305
// ---------
// This is a *one time* authenticator.
// Disclosing the mac reveals the key.
// See crypto_lock() on how to use it properly.
// Direct interface
void crypto_poly1305(uint8_t mac[16],
const uint8_t *message, size_t message_size,
const uint8_t key[32]);
// Incremental interface
typedef struct {
// Do not rely on the size or contents of this type,
// for they may change without notice.
uint8_t c[16]; // chunk of the message
size_t c_idx; // How many bytes are there in the chunk.
uint32_t r [4]; // constant multiplier (from the secret key)
uint32_t pad[4]; // random number added at the end (from the secret key)
uint32_t h [5]; // accumulated hash
} crypto_poly1305_ctx;
void crypto_poly1305_init (crypto_poly1305_ctx *ctx, const uint8_t key[32]);
void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
const uint8_t *message, size_t message_size);
void crypto_poly1305_final (crypto_poly1305_ctx *ctx, uint8_t mac[16]);
// Elligator 2
// -----------
// Elligator mappings proper
void crypto_elligator_map(uint8_t curve [32], const uint8_t hidden[32]);
int crypto_elligator_rev(uint8_t hidden[32], const uint8_t curve [32],
uint8_t tweak);
// Easy to use key pair generation
void crypto_elligator_key_pair(uint8_t hidden[32], uint8_t secret_key[32],
uint8_t seed[32]);
#ifdef __cplusplus
}
#endif
#endif // MONOCYPHER_H

View File

@ -55,7 +55,7 @@ debug_inline constexpr static uint GB(const T x, const uint8_t s, const uint8_t
* @return The new value of \a x * @return The new value of \a x
*/ */
template <typename T, typename U> template <typename T, typename U>
inline T SB(T &x, const uint8_t s, const uint8_t n, const U d) constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
{ {
x &= (T)(~((((T)1U << n) - 1) << s)); x &= (T)(~((((T)1U << n) - 1) << s));
x |= (T)(d << s); x |= (T)(d << s);
@ -80,7 +80,7 @@ inline T SB(T &x, const uint8_t s, const uint8_t n, const U d)
* @return The new value of \a x * @return The new value of \a x
*/ */
template <typename T, typename U> template <typename T, typename U>
inline T AB(T &x, const uint8_t s, const uint8_t n, const U i) constexpr T AB(T &x, const uint8_t s, const uint8_t n, const U i)
{ {
const T mask = ((((T)1U << n) - 1) << s); const T mask = ((((T)1U << n) - 1) << s);
x = (T)((x & ~mask) | ((x + (i << s)) & mask)); x = (T)((x & ~mask) | ((x + (i << s)) & mask));
@ -100,7 +100,7 @@ inline T AB(T &x, const uint8_t s, const uint8_t n, const U i)
* @return True if the bit is set, false else. * @return True if the bit is set, false else.
*/ */
template <typename T> template <typename T>
debug_inline static bool HasBit(const T x, const uint8_t y) debug_inline constexpr bool HasBit(const T x, const uint8_t y)
{ {
return (x & ((T)1U << y)) != 0; return (x & ((T)1U << y)) != 0;
} }
@ -118,7 +118,7 @@ debug_inline static bool HasBit(const T x, const uint8_t y)
* @return The new value of the old value with the bit set * @return The new value of the old value with the bit set
*/ */
template <typename T> template <typename T>
inline T SetBit(T &x, const uint8_t y) constexpr T SetBit(T &x, const uint8_t y)
{ {
return x = (T)(x | ((T)1U << y)); return x = (T)(x | ((T)1U << y));
} }
@ -148,7 +148,7 @@ inline T SetBit(T &x, const uint8_t y)
* @return The new value of the old value with the bit cleared * @return The new value of the old value with the bit cleared
*/ */
template <typename T> template <typename T>
inline T ClrBit(T &x, const uint8_t y) constexpr T ClrBit(T &x, const uint8_t y)
{ {
return x = (T)(x & ~((T)1U << y)); return x = (T)(x & ~((T)1U << y));
} }
@ -178,7 +178,7 @@ inline T ClrBit(T &x, const uint8_t y)
* @return The new value of the old value with the bit toggled * @return The new value of the old value with the bit toggled
*/ */
template <typename T> template <typename T>
inline T ToggleBit(T &x, const uint8_t y) constexpr T ToggleBit(T &x, const uint8_t y)
{ {
return x = (T)(x ^ ((T)1U << y)); return x = (T)(x ^ ((T)1U << y));
} }
@ -228,7 +228,7 @@ constexpr uint8_t FindLastBit(T x)
* @return The new value with the first bit cleared * @return The new value with the first bit cleared
*/ */
template <typename T> template <typename T>
inline T KillFirstBit(T value) constexpr T KillFirstBit(T value)
{ {
return value &= (T)(value - 1); return value &= (T)(value - 1);
} }
@ -256,7 +256,7 @@ constexpr uint CountBits(T value)
* @return does \a value have exactly 1 bit set? * @return does \a value have exactly 1 bit set?
*/ */
template <typename T> template <typename T>
inline bool HasExactlyOneBit(T value) constexpr bool HasExactlyOneBit(T value)
{ {
return value != 0 && (value & (value - 1)) == 0; return value != 0 && (value & (value - 1)) == 0;
} }
@ -268,7 +268,7 @@ inline bool HasExactlyOneBit(T value)
* @return does \a value have at most 1 bit set? * @return does \a value have at most 1 bit set?
*/ */
template <typename T> template <typename T>
inline bool HasAtMostOneBit(T value) constexpr bool HasAtMostOneBit(T value)
{ {
return (value & (value - 1)) == 0; return (value & (value - 1)) == 0;
} }

View File

@ -12,41 +12,6 @@
#include "../safeguards.h" #include "../safeguards.h"
/**
* Compute least common multiple (lcm) of arguments \a a and \a b, the smallest
* integer value that is a multiple of both \a a and \a b.
* @param a First number.
* @param b second number.
* @return Least common multiple of values \a a and \a b.
*
* @note This function only works for non-negative values of \a a and \a b.
*/
int LeastCommonMultiple(int a, int b)
{
if (a == 0 || b == 0) return 0; // By definition.
if (a == 1 || a == b) return b;
if (b == 1) return a;
return a * b / GreatestCommonDivisor(a, b);
}
/**
* Compute greatest common divisor (gcd) of \a a and \a b.
* @param a First number.
* @param b second number.
* @return Greatest common divisor of \a a and \a b.
*/
int GreatestCommonDivisor(int a, int b)
{
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
/** /**
* Deterministic approximate division. * Deterministic approximate division.
* Cancels out division errors stemming from the integer nature of the division over multiple runs. * Cancels out division errors stemming from the integer nature of the division over multiple runs.

View File

@ -20,7 +20,7 @@
* @return The unsigned value * @return The unsigned value
*/ */
template <typename T> template <typename T>
inline T abs(const T a) constexpr T abs(const T a)
{ {
return (a < (T)0) ? -a : a; return (a < (T)0) ? -a : a;
} }
@ -34,7 +34,7 @@ inline T abs(const T a)
* @return The smallest multiple of n equal or greater than x * @return The smallest multiple of n equal or greater than x
*/ */
template <typename T> template <typename T>
inline T Align(const T x, uint n) constexpr T Align(const T x, uint n)
{ {
assert((n & (n - 1)) == 0 && n != 0); assert((n & (n - 1)) == 0 && n != 0);
n--; n--;
@ -52,7 +52,7 @@ inline T Align(const T x, uint n)
* @see Align() * @see Align()
*/ */
template <typename T> template <typename T>
inline T *AlignPtr(T *x, uint n) constexpr T *AlignPtr(T *x, uint n)
{ {
static_assert(sizeof(size_t) == sizeof(void *)); static_assert(sizeof(size_t) == sizeof(void *));
return reinterpret_cast<T *>(Align((size_t)x, n)); return reinterpret_cast<T *>(Align((size_t)x, n));
@ -76,7 +76,7 @@ inline T *AlignPtr(T *x, uint n)
* @see Clamp(int, int, int) * @see Clamp(int, int, int)
*/ */
template <typename T> template <typename T>
inline T Clamp(const T a, const T min, const T max) constexpr T Clamp(const T a, const T min, const T max)
{ {
assert(min <= max); assert(min <= max);
if (a <= min) return min; if (a <= min) return min;
@ -99,7 +99,7 @@ inline T Clamp(const T a, const T min, const T max)
* @returns A value between min and max which is closest to a. * @returns A value between min and max which is closest to a.
*/ */
template <typename T> template <typename T>
inline T SoftClamp(const T a, const T min, const T max) constexpr T SoftClamp(const T a, const T min, const T max)
{ {
if (min > max) { if (min > max) {
using U = std::make_unsigned_t<T>; using U = std::make_unsigned_t<T>;
@ -126,7 +126,7 @@ inline T SoftClamp(const T a, const T min, const T max)
* @returns A value between min and max which is closest to a. * @returns A value between min and max which is closest to a.
* @see ClampU(uint, uint, uint) * @see ClampU(uint, uint, uint)
*/ */
inline int Clamp(const int a, const int min, const int max) constexpr int Clamp(const int a, const int min, const int max)
{ {
return Clamp<int>(a, min, max); return Clamp<int>(a, min, max);
} }
@ -147,7 +147,7 @@ inline int Clamp(const int a, const int min, const int max)
* @returns A value between min and max which is closest to a. * @returns A value between min and max which is closest to a.
* @see Clamp(int, int, int) * @see Clamp(int, int, int)
*/ */
inline uint ClampU(const uint a, const uint min, const uint max) constexpr uint ClampU(const uint a, const uint min, const uint max)
{ {
return Clamp<uint>(a, min, max); return Clamp<uint>(a, min, max);
} }
@ -231,7 +231,7 @@ constexpr To ClampTo(From value)
* @return The absolute difference between the given scalars * @return The absolute difference between the given scalars
*/ */
template <typename T> template <typename T>
inline T Delta(const T a, const T b) constexpr T Delta(const T a, const T b)
{ {
return (a < b) ? b - a : a - b; return (a < b) ? b - a : a - b;
} }
@ -249,7 +249,7 @@ inline T Delta(const T a, const T b)
* @return True if the value is in the interval, false else. * @return True if the value is in the interval, false else.
*/ */
template <typename T> template <typename T>
inline bool IsInsideBS(const T x, const size_t base, const size_t size) constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
{ {
return (size_t)(x - base) < size; return (size_t)(x - base) < size;
} }
@ -265,7 +265,7 @@ inline bool IsInsideBS(const T x, const size_t base, const size_t size)
* @see IsInsideBS() * @see IsInsideBS()
*/ */
template <typename T, std::enable_if_t<std::disjunction_v<std::is_convertible<T, size_t>, std::is_base_of<StrongTypedefBase, T>>, int> = 0> template <typename T, std::enable_if_t<std::disjunction_v<std::is_convertible<T, size_t>, std::is_base_of<StrongTypedefBase, T>>, int> = 0>
static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
{ {
if constexpr (std::is_base_of_v<StrongTypedefBase, T>) { if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
return (size_t)(x.base() - min) < (max - min); return (size_t)(x.base() - min) < (max - min);
@ -280,7 +280,7 @@ static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_
* @param b variable to swap with a * @param b variable to swap with a
*/ */
template <typename T> template <typename T>
inline void Swap(T &a, T &b) constexpr void Swap(T &a, T &b)
{ {
T t = a; T t = a;
a = b; a = b;
@ -292,7 +292,7 @@ inline void Swap(T &a, T &b)
* @param i value to convert, range 0..255 * @param i value to convert, range 0..255
* @return value in range 0..100 * @return value in range 0..100
*/ */
inline uint ToPercent8(uint i) constexpr uint ToPercent8(uint i)
{ {
assert(i < 256); assert(i < 256);
return i * 101 >> 8; return i * 101 >> 8;
@ -303,14 +303,12 @@ inline uint ToPercent8(uint i)
* @param i value to convert, range 0..65535 * @param i value to convert, range 0..65535
* @return value in range 0..100 * @return value in range 0..100
*/ */
inline uint ToPercent16(uint i) constexpr uint ToPercent16(uint i)
{ {
assert(i < 65536); assert(i < 65536);
return i * 101 >> 16; return i * 101 >> 16;
} }
int LeastCommonMultiple(int a, int b);
int GreatestCommonDivisor(int a, int b);
int DivideApprox(int a, int b); int DivideApprox(int a, int b);
/** /**
@ -319,7 +317,7 @@ int DivideApprox(int a, int b);
* @param b Denominator * @param b Denominator
* @return Quotient, rounded up * @return Quotient, rounded up
*/ */
inline uint CeilDiv(uint a, uint b) constexpr uint CeilDiv(uint a, uint b)
{ {
return (a + b - 1) / b; return (a + b - 1) / b;
} }
@ -330,7 +328,7 @@ inline uint CeilDiv(uint a, uint b)
* @param b Denominator * @param b Denominator
* @return a rounded up to the nearest multiple of b. * @return a rounded up to the nearest multiple of b.
*/ */
inline uint Ceil(uint a, uint b) constexpr uint Ceil(uint a, uint b)
{ {
return CeilDiv(a, b) * b; return CeilDiv(a, b) * b;
} }
@ -341,7 +339,7 @@ inline uint Ceil(uint a, uint b)
* @param b Denominator * @param b Denominator
* @return Quotient, rounded to nearest * @return Quotient, rounded to nearest
*/ */
inline int RoundDivSU(int a, uint b) constexpr int RoundDivSU(int a, uint b)
{ {
if (a > 0) { if (a > 0) {
/* 0.5 is rounded to 1 */ /* 0.5 is rounded to 1 */
@ -358,7 +356,7 @@ inline int RoundDivSU(int a, uint b)
* @param b Denominator * @param b Denominator
* @return Quotient, rounded away from zero * @return Quotient, rounded away from zero
*/ */
inline int DivAwayFromZero(int a, uint b) constexpr int DivAwayFromZero(int a, uint b)
{ {
const int _b = static_cast<int>(b); const int _b = static_cast<int>(b);
if (a > 0) { if (a > 0) {

View File

@ -10,6 +10,7 @@
#include "../stdafx.h" #include "../stdafx.h"
#include "random_func.hpp" #include "random_func.hpp"
#include "bitmath_func.hpp" #include "bitmath_func.hpp"
#include "../debug.h"
#ifdef RANDOM_DEBUG #ifdef RANDOM_DEBUG
#include "../network/network.h" #include "../network/network.h"
@ -20,6 +21,15 @@
#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h"
#endif /* RANDOM_DEBUG */ #endif /* RANDOM_DEBUG */
#if defined(_WIN32)
# include <windows.h>
# include <bcrypt.h>
#elif defined(__EMSCRIPTEN__)
# include <emscripten.h>
#elif !defined(__APPLE__) && !defined(__NetBSD__) && !defined(__FreeBSD__)
# include <sys/random.h>
#endif
#include "../safeguards.h" #include "../safeguards.h"
Randomizer _random, _interactive_random; Randomizer _random, _interactive_random;
@ -83,3 +93,53 @@ uint32_t DoRandomRange(uint32_t limit, int line, const char *file)
return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32; return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32;
} }
#endif /* RANDOM_DEBUG */ #endif /* RANDOM_DEBUG */
/**
* Fill the given buffer with random bytes.
*
* This function will attempt to use a cryptographically-strong random
* generator, but will fall back to a weaker random generator if none is
* available.
*
* In the end, the buffer will always be filled with some form of random
* bytes when this function returns.
*
* @param buf The buffer to fill with random bytes.
*/
void RandomBytesWithFallback(std::span<uint8_t> buf)
{
#if defined(_WIN32)
auto res = BCryptGenRandom(nullptr, static_cast<PUCHAR>(buf.data()), static_cast<ULONG>(buf.size()), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (res >= 0) return;
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
arc4random_buf(buf.data(), buf.size());
return;
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
auto res = getrandom(buf.data(), buf.size(), 0);
if (res > 0 && static_cast<size_t>(res) == buf.size()) return;
#elif defined(__EMSCRIPTEN__)
auto res = EM_ASM_INT({
var buf = $0;
var bytes = $1;
var crypto = window.crypto;
if (crypto === undefined || crypto.getRandomValues === undefined) {
return -1;
}
crypto.getRandomValues(Module.HEAPU8.subarray(buf, buf + bytes));
return 1;
}, buf.data(), buf.size());
if (res > 0) return;
#else
# warning "No cryptographically-strong random generator available; using a fallback instead"
#endif
static bool warned_once = false;
Debug(misc, warned_once ? 1 : 0, "Cryptographically-strong random generator unavailable; using fallback");
warned_once = true;
for (uint i = 0; i < buf.size(); i++) {
buf[i] = static_cast<uint8_t>(InteractiveRandom());
}
}

View File

@ -159,4 +159,6 @@ inline bool Chance16R(const uint a, const uint b, uint32_t &r)
} }
#endif /* RANDOM_DEBUG */ #endif /* RANDOM_DEBUG */
void RandomBytesWithFallback(std::span<uint8_t> buf);
#endif /* RANDOM_FUNC_HPP */ #endif /* RANDOM_FUNC_HPP */

View File

@ -244,10 +244,12 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
if (!IsConsumedFormattingCode(c)) index += line->GetInternalCharLength(c); if (!IsConsumedFormattingCode(c)) index += line->GetInternalCharLength(c);
} }
/* Initial position, returned if character not found. */
static const std::vector<Point> zero = { {0, 0} };
auto position = zero.begin();
/* We couldn't find the code point index. */ /* We couldn't find the code point index. */
if (str != ch) { if (str != ch) return *position;
return { 0, 0 };
}
/* Valid character. */ /* Valid character. */
@ -257,15 +259,24 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
const auto &positions = run.GetPositions(); const auto &positions = run.GetPositions();
const auto &charmap = run.GetGlyphToCharMap(); const auto &charmap = run.GetGlyphToCharMap();
for (int i = 0; i < run.GetGlyphCount(); i++) { /* Run starts after our character, use the last found position. */
/* Matching glyph? Return position. */ if ((size_t)charmap.front() > index) return *position;
if ((size_t)charmap[i] == index) {
return positions[i]; position = positions.begin();
} for (auto it = charmap.begin(); it != charmap.end(); /* nothing */) {
/* Plain honest-to-$deity match. */
if ((size_t)*it == index) return *position;
++it;
if (it == charmap.end()) break;
/* We just passed our character, it's probably a ligature, use the last found position. */
if ((size_t)*it > index) return *position;
++position;
} }
} }
NOT_REACHED(); /* At the end of the run but still didn't find our character so probably a trailing ligature, use the last found position. */
return *position;
} }
/** /**

View File

@ -772,7 +772,7 @@ STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLA
STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rutes de transport STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rutes de transport
STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Bosc STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Bosc
STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Estació de ferrocarril STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Estació de ferrocarril
STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Moll de càrrega de camions STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Estació per a camions
STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Parada d'autobús STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Parada d'autobús
STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Aeroport/Heliport STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Aeroport/Heliport
STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Moll STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Moll
@ -904,7 +904,7 @@ STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}El benef
STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} no pot arribar al proper destí perquè és fora del seu abast STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} no pot arribar al proper destí perquè és fora del seu abast
STR_NEWS_ORDER_REFIT_FAILED :{WHITE}El {VEHICLE} s'ha parat perquè l'ordre de remodelació ha fallat STR_NEWS_ORDER_REFIT_FAILED :{WHITE}El {VEHICLE} s'ha parat perquè l'ordre de remodelació ha fallat
STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}L'autorenovació ha fallat en el {VEHICLE}{}{STRING} STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}L'autorenovació de {VEHICLE} ha fallat.{}{STRING}
STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLACK}No{G u va} {STRING} disponible! STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLACK}No{G u va} {STRING} disponible!
STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE}
@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dòlar de Hong
STR_GAME_OPTIONS_CURRENCY_INR :Rúpia índia STR_GAME_OPTIONS_CURRENCY_INR :Rúpia índia
STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonèsia STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonèsia
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit
STR_GAME_OPTIONS_CURRENCY_LVL :Lats letó
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Desa automàticament STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Desa automàticament
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'interval de desada automàtica de la partida STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'interval de desada automàtica de la partida
@ -1044,6 +1045,10 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marqueu
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escala els bisells STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escala els bisells
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'escalin els bisells segons la mida de la interfície. STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'escalin els bisells segons la mida de la interfície.
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Fes servir la font tradicional
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Marqueu aquesta casella si preferiu fer servir la font tradicional de mida fixa i pixelada.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Aplica anti-àlies a les fonts
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Marqueu aquesta casella per a fer servir tècniques d'anti-àlies a les fonts redimensionables.
STR_GAME_OPTIONS_GUI_SCALE_1X :x1 STR_GAME_OPTIONS_GUI_SCALE_1X :x1
STR_GAME_OPTIONS_GUI_SCALE_2X :x2 STR_GAME_OPTIONS_GUI_SCALE_2X :x2
@ -1779,6 +1784,8 @@ STR_CONFIG_SETTING_SERVINT_DISABLED :Desactivat
STR_CONFIG_SETTING_NOSERVICE :Desactiva les revisions quan les avaries s'estableixen a cap: {STRING} STR_CONFIG_SETTING_NOSERVICE :Desactiva les revisions quan les avaries s'estableixen a cap: {STRING}
STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quan està activat, els vehicles no són revisats si no es poden espatllar STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quan està activat, els vehicles no són revisats si no es poden espatllar
STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY :Penalització de la velocitat de càrrega per a trens més llargs que l'estació: {STRING}
STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY_HELPTEXT :Quan s'activa, els trens que són massa llargs per a l'estació es carreguen més a poc a poc que un tren que sí que hi cap. Aquesta opció no afecta als encaminadors; és a dir, no afecta als algoritmes que fan servir els trens per a decidir el camí per a arribar a l'estació.
STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activa límits de velocitat per als vagons: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activa límits de velocitat per als vagons: {STRING}
STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Quan està activat, també utilitza els límits de velocitat dels vagons per decidir la velocitat màxima del tren STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Quan està activat, també utilitza els límits de velocitat dels vagons per decidir la velocitat màxima del tren
@ -2055,14 +2062,17 @@ STR_CONFIG_SETTING_ACCOUNTING :Comptabilitat
STR_CONFIG_SETTING_VEHICLES :Vehicles STR_CONFIG_SETTING_VEHICLES :Vehicles
STR_CONFIG_SETTING_VEHICLES_PHYSICS :Lleis físiques STR_CONFIG_SETTING_VEHICLES_PHYSICS :Lleis físiques
STR_CONFIG_SETTING_VEHICLES_ROUTING :Recorreguts STR_CONFIG_SETTING_VEHICLES_ROUTING :Recorreguts
STR_CONFIG_SETTING_VEHICLES_ORDERS :Ordres
STR_CONFIG_SETTING_LIMITATIONS :Limitacions STR_CONFIG_SETTING_LIMITATIONS :Limitacions
STR_CONFIG_SETTING_ACCIDENTS :Desastres / Accidents STR_CONFIG_SETTING_ACCIDENTS :Desastres / Accidents
STR_CONFIG_SETTING_GENWORLD :Generació del món STR_CONFIG_SETTING_GENWORLD :Generació del món
STR_CONFIG_SETTING_ENVIRONMENT :Interacció amb l'entorn STR_CONFIG_SETTING_ENVIRONMENT :Interacció amb l'entorn
STR_CONFIG_SETTING_ENVIRONMENT_TIME :Temps
STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :Autoritats STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :Autoritats
STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :Poblacions STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :Poblacions
STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :Indústries STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :Indústries
STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :Distribució de la càrrega STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :Distribució de la càrrega
STR_CONFIG_SETTING_ENVIRONMENT_TREES :Arbres
STR_CONFIG_SETTING_AI :Competidors STR_CONFIG_SETTING_AI :Competidors
STR_CONFIG_SETTING_AI_NPC :Jugadors IA STR_CONFIG_SETTING_AI_NPC :Jugadors IA
STR_CONFIG_SETTING_NETWORK :Xarxa STR_CONFIG_SETTING_NETWORK :Xarxa
@ -2720,9 +2730,9 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Construcció de
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construeix vies de tren. Ctrl canvia entre contrueix/treu la construcció de vies. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construeix vies de tren. Ctrl canvia entre contrueix/treu la construcció de vies. Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construeix vies de tren utilitzant el mode Autorail. Ctrl canvia entre construeix/treu la construcció de vies de tren. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construeix vies de tren utilitzant el mode Autorail. Ctrl canvia entre construeix/treu la construcció de vies de tren. Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construeix unes cotxeres (per construir i revisar trens). Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construeix unes cotxeres (per construir i revisar trens). Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converteix una via en un punt de control. Ctrl permet ajuntar punts de control. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Construeix un punt de control en una via de ferrocarril. Ctrl permet ajuntar punts de control. Amb Maj. es commuta entre construir o mostrar el cost estimat.
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construeix una estació de tren. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construeix una estació de tren. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construeix senyals de tren. Ctrl commuta entre semàfors mecànics i elèctrics{}Arrossegant es construeixen senyals al llarg d'un tros recte de rail. Ctrl construeix senyals fins a la propera intersecció o senyal{}Ctrl+Clic commuta l'obertura de la finestra de detecció de senyals. Shift commuta construir/mostrar el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construeix senyals de tren en vies de ferrocarril. Ctrl commuta entre semàfors mecànics i elèctrics.{}Arrossegant es construeixen senyals al llarg d'un tros recte de rail. Ctrl construeix senyals fins a la propera intersecció o senyal.{}Ctrl+Clic commuta l'obertura de la finestra de detecció de senyals. Shift commuta construir/mostrar el cost estimat.
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construeix un pont de tren. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construeix un pont de tren. Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construeix un túnel per a trens. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construeix un túnel per a trens. Shift commuta construeix/mostra el cost estimat
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Commuta construeix/treu per vies de tren, senyals, punts de control i estacions. Mantingueu Ctrl per treure també les vies dels punts de control i de les estacions STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Commuta construeix/treu per vies de tren, senyals, punts de control i estacions. Mantingueu Ctrl per treure també les vies dels punts de control i de les estacions
@ -2810,7 +2820,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construe
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construeix cotxeres de tramvies (per comprar i revisar tramvies). Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construeix cotxeres de tramvies (per comprar i revisar tramvies). Shift commuta construeix/mostra el cost estimat
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construeix estacions d'autobús. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construeix estacions d'autobús. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Construeix una estació de tramvies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Construeix una estació de tramvies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construeix un moll de càrrega. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construeix una estació per a camions. Ctrl permet ajuntar estacions. Amb Maj. es commuta entre construir o mostrar el cost estimat.
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Construeix una estació de tramvies de mercaderies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Construeix una estació de tramvies de mercaderies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activa/Desactiva les carreteres d'un sentit STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activa/Desactiva les carreteres d'un sentit
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construeix un pont per carretera. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construeix un pont per carretera. Shift commuta construeix/mostra el cost estimat
@ -2835,7 +2845,7 @@ STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Seleccio
STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orientació Parada d'autobús STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orientació Parada d'autobús
STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de la parada d'autobús STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de la parada d'autobús
STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orientació Estació de Mercaderies STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orientació Estació de Mercaderies
STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació del moll de càrrega de camions STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Seleccioneu l'orientació de l'estació per a camions.
STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de passatgers STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de passatgers
STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de l'estació de tramvies de passatgers STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de l'estació de tramvies de passatgers
STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de mercaderies STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de mercaderies
@ -3013,7 +3023,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propieta
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoritat local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoritat local: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Cap STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Cap
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construït: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construït/renovat: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classe d'estació: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classe d'estació: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipus d'estació: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipus d'estació: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Classe de l'aeroport: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Classe de l'aeroport: {LTBLUE}{STRING}
@ -3079,7 +3089,7 @@ STR_LAI_TREE_NAME_CACTUS_PLANTS :Plantes de Cact
STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estació de Ferrocarril STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estació de Ferrocarril
STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar d'Avions STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar d'Avions
STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroport STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroport
STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Moll de càrrega de camions STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estació de camions
STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada d'autobús STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada d'autobús
STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Moll per vaixells STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Moll per vaixells
STR_LAI_STATION_DESCRIPTION_BUOY :Boia STR_LAI_STATION_DESCRIPTION_BUOY :Boia

View File

@ -282,7 +282,7 @@ STR_TOOLTIP_RESIZE :{BLACK}Click an
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size
STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list up/down STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list up/down
STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list left/right STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list left/right
STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
# Show engines button # Show engines button
###length VEHICLE_TYPES ###length VEHICLE_TYPES
@ -370,32 +370,32 @@ STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pause ga
STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Fast forward the game STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Fast forward the game
STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Options and settings STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Options and settings
STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Save, load or abandon game, exit program STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Save, load or abandon game, exit program
STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Display map, extra viewport, cargo flow or list of signs STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Open map, extra viewport, cargo flow or list of signs
STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Display town directory STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Open town directory or found town
STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Display subsidies STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Open subsidy list
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Display list of company's stations STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Open list of company's stations
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Open company finances information
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Open general company information
STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Display story book STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Open story book
STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Display goal list STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Open goal list
STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Display company graphs and cargo payment rates STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Open company graphs and cargo payment rates
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Open company league table
STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Examine industries or fund construction of a new industry STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Open industry directory, industry chain, or fund construction of a new industry
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Display list of company's trains. Ctrl+Click toggles opening the group/vehicle list STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Open list of company's trains. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Display list of company's road vehicles. Ctrl+Click toggles opening the group/vehicle list STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Open list of company's road vehicles. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Display list of company's ships. Ctrl+Click toggles opening the group/vehicle list STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Open list of company's ships. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Display list of company's aircraft. Ctrl+Click toggles opening the group/vehicle list STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Open list of company's aircraft. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting
STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom the view in STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom in
STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom out
STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway infrastructure
STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build roads STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build road infrastructure
STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build tramways STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build tramway infrastructure
STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build ship docks STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build waterway infrastructure
STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Build airports STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Build airports
STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc. STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open landscaping menu, tree menu, or place a sign
STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Show sound/music window STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Open sound/music window
STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Show last message/news report, messages history or delete all messages STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Open last message/news report, messages history or delete all messages
STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Land area information, screenshot, about OpenTTD and developer tools STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Open land information, screenshot menu, OpenTTD credits, or developer tools
STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Switch toolbars STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Switch toolbars
# Extra tooltips for the scenario editor toolbar # Extra tooltips for the scenario editor toolbar
@ -405,15 +405,15 @@ STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Scenari
STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Move the starting date backward 1 year STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Move the starting date backward 1 year
STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Move the starting date forward 1 year STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Move the starting date forward 1 year
STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Click to enter the starting year STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Click to enter the starting year
STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Display map, town directory STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Open map, extra viewport, sign list, or town or industry directory
STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscape generation STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Open landscaping menu or generate a new world
STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town generation STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Build or generate towns
STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Build or generate industries
STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Build road infrastructure
STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramway construction STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Build tramway infrastructure
STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign
STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
# Scenario editor file menu # Scenario editor file menu
###length 7 ###length 7
@ -1037,7 +1037,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Check th
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {RAW_STRING} STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {RAW_STRING}
STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Hold Ctrl for continuous adjustment STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Ctrl+Drag for continuous adjustment
STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size
STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically
@ -1334,7 +1334,7 @@ STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains f
STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations.
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Allow to join stations not directly adjacent: {STRING2} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Allow to join stations not directly adjacent: {STRING2}
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts. Needs Ctrl+Click while placing the new parts STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts, by Ctrl+Clicking while placing the new parts
STR_CONFIG_SETTING_INFLATION :Inflation: {STRING2} STR_CONFIG_SETTING_INFLATION :Inflation: {STRING2}
STR_CONFIG_SETTING_INFLATION_HELPTEXT :Enable inflation in the economy, where costs are slightly faster rising than payments STR_CONFIG_SETTING_INFLATION_HELPTEXT :Enable inflation in the economy, where costs are slightly faster rising than payments
@ -1874,7 +1874,7 @@ STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Automatically b
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Set the year when electric signals will be used for tracks. Before this year, non-electric signals will be used (which have the exact same function, but different looks) STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Set the year when electric signals will be used for tracks. Before this year, non-electric signals will be used (which have the exact same function, but different looks)
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Cycle through signal types: {STRING2} STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Cycle through signal types: {STRING2}
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Select which signal types to cycle through when Ctrl+clicking on a built signal with the signal tool STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Select which signal types to cycle through when Ctrl+Clicking on a built signal with the signal tool
###length 2 ###length 2
STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Path signals only STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Path signals only
STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :All visible STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :All visible
@ -2147,14 +2147,14 @@ STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Select '
STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Select 'sub-tropical' landscape style STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Select 'sub-tropical' landscape style
STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Select 'toyland' landscape style STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Select 'toyland' landscape style
STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Display game options STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Open game options
STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display highscore table STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Open highscore table
STR_INTRO_TOOLTIP_HELP :{BLACK}Get access to documentation and online resources STR_INTRO_TOOLTIP_HELP :{BLACK}Get access to documentation and online resources
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Open settings
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Open NewGRF settings
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download
STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Display AI settings STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Open AI settings
STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Display Game script settings STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Open Game script settings
STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD' STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD'
STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset. STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset.
@ -2212,8 +2212,8 @@ STR_LIVERY_TRAIN_GROUP_TOOLTIP :{BLACK}Show col
STR_LIVERY_ROAD_VEHICLE_GROUP_TOOLTIP :{BLACK}Show colours of road vehicle groups STR_LIVERY_ROAD_VEHICLE_GROUP_TOOLTIP :{BLACK}Show colours of road vehicle groups
STR_LIVERY_SHIP_GROUP_TOOLTIP :{BLACK}Show colours of ship groups STR_LIVERY_SHIP_GROUP_TOOLTIP :{BLACK}Show colours of ship groups
STR_LIVERY_AIRCRAFT_GROUP_TOOLTIP :{BLACK}Show colours of aircraft groups STR_LIVERY_AIRCRAFT_GROUP_TOOLTIP :{BLACK}Show colours of aircraft groups
STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Choose the primary colour for the selected scheme. Ctrl+Click will set this colour for every scheme STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Choose the primary colour for the selected scheme. Ctrl+Click to set this colour for every scheme
STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Choose the secondary colour for the selected scheme. Ctrl+Click will set this colour for every scheme STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Choose the secondary colour for the selected scheme. Ctrl+Click to set this colour for every scheme
STR_LIVERY_PANEL_TOOLTIP :{BLACK}Select a colour scheme to change, or multiple schemes with Ctrl+Click. Click on the box to toggle use of the scheme STR_LIVERY_PANEL_TOOLTIP :{BLACK}Select a colour scheme to change, or multiple schemes with Ctrl+Click. Click on the box to toggle use of the scheme
STR_LIVERY_TRAIN_GROUP_EMPTY :No train groups are set up STR_LIVERY_TRAIN_GROUP_EMPTY :No train groups are set up
STR_LIVERY_ROAD_VEHICLE_GROUP_EMPTY :No road vehicle groups are set up STR_LIVERY_ROAD_VEHICLE_GROUP_EMPTY :No road vehicle groups are set up
@ -2726,16 +2726,16 @@ STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Electrified Rai
STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Monorail Construction STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Monorail Construction
STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglev Construction STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglev Construction
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl+Click to remove railway track. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl+Click to remove railway track. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Build waypoint on railway. Ctrl enables joining waypoints. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Build waypoint on railway. Ctrl+Click to select another waypoint to join. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Build signal on railway. Ctrl toggles semaphore/light signals{}Dragging builds signals along a straight stretch of rail. Ctrl builds signals up to the next junction or signal{}Ctrl+Click toggles opening the signal selection window. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Build signal on railway. Ctrl+Click to build the alternate signal style{}Click+Drag to fill the selected section of rail with signals at the chosen spacing. Ctrl+Click+Drag to fill signals up to the next junction, station, or signal. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel. Also press Shift to show cost estimate only
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track, signals, waypoints and stations. Hold Ctrl to also remove the rail of waypoints and stations STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track, signals, waypoints and stations. Ctrl+Click to also remove the rail of waypoints and stations
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Convert/Upgrade the type of rail. Shift toggles building/showing cost estimate STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Convert/Upgrade the type of rail. Also press Shift to show cost estimate only
STR_RAIL_NAME_RAILROAD :Railway STR_RAIL_NAME_RAILROAD :Railway
STR_RAIL_NAME_ELRAIL :Electrified railway STR_RAIL_NAME_ELRAIL :Electrified railway
@ -2785,7 +2785,7 @@ STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Exit Sig
STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combo Signal (electric){}The combo signal simply acts as both an entry and exit signal. This allows you to build large "trees" of pre-signals STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combo Signal (electric){}The combo signal simply acts as both an entry and exit signal. This allows you to build large "trees" of pre-signals
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. Standard path signals can be passed from the back side STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. Standard path signals can be passed from the back side
STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}One-way Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. One-way path signals can't be passed from the back side STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}One-way Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. One-way path signals can't be passed from the back side
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signal Convert{}When selected, clicking an existing signal will convert it to the selected signal type and variant. Ctrl+Click will toggle the existing variant. Shift+Click shows estimated conversion cost STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signal Convert{}Click an existing signal to convert it to the selected signal type and variant. Ctrl+Click to toggle the existing variant. Shift+Click shows estimated conversion cost
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Dragging signal distance STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Dragging signal distance
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Decrease dragging signal distance STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Decrease dragging signal distance
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase dragging signal distance STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase dragging signal distance
@ -2811,25 +2811,25 @@ STR_BRIDGE_TUBULAR_SILICON :Tubular, Silico
# Road construction toolbar # Road construction toolbar
STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Road Construction STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Road Construction
STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramway Construction STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramway Construction
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl+Click to remove road section. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl+Click to remove tramway section. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl+Click to remove road section. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl+Click to remove tramway section. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Build bus station. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Build bus station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Build passenger tram station. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Build passenger tram station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Build lorry station. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Build lorry station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Build freight tram station. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Build freight tram station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activate/Deactivate one way roads STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activate/Deactivate one way roads
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Build tramway bridge. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Build tramway bridge. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tramway tunnel. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tramway tunnel. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for tramway construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for tramway construction
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Also press Shift to show cost estimate only
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of tram. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of tram. Also press Shift to show cost estimate only
STR_ROAD_NAME_ROAD :Road STR_ROAD_NAME_ROAD :Road
STR_ROAD_NAME_TRAM :Tramway STR_ROAD_NAME_TRAM :Tramway
@ -2853,14 +2853,14 @@ STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Select f
# Waterways toolbar (last two for SE only) # Waterways toolbar (last two for SE only)
STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Waterways Construction STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Waterways Construction
STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Waterways STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Waterways
STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Build canals. Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Build canals. Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Build locks. Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Build locks. Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build ship depot (for buying and servicing ships). Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build ship depot (for buying and servicing ships). Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Build ship dock. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Build ship dock. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Place a buoy which can be used as a waypoint. Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Place a buoy which can be used as a waypoint. Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Build aqueduct. Shift toggles building/showing cost estimate STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Build aqueduct. Also press Shift to show cost estimate only
STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Define water area.{}Make a canal, unless Ctrl is held down at sea level, when it will flood the surroundings instead STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Build canal. Ctrl+Click at sea level to flood with sea water instead
STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Place rivers. Ctrl selects the area diagonally STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Place rivers. Ctrl+Click to select diagonally
# Ship depot construction window # Ship depot construction window
STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}Ship Depot Orientation STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}Ship Depot Orientation
@ -2871,7 +2871,7 @@ STR_STATION_BUILD_DOCK_CAPTION :{WHITE}Dock
# Airport toolbar # Airport toolbar
STR_TOOLBAR_AIRCRAFT_CAPTION :{WHITE}Airports STR_TOOLBAR_AIRCRAFT_CAPTION :{WHITE}Airports
STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Build airport. Ctrl enables joining stations. Shift toggles building/showing cost estimate STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Build airport. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only
# Airport construction window # Airport construction window
STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Airport Selection STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Airport Selection
@ -2898,14 +2898,14 @@ STR_STATION_BUILD_NOISE :{BLACK}Noise ge
# Landscaping toolbar # Landscaping toolbar
STR_LANDSCAPING_TOOLBAR :{WHITE}Landscaping STR_LANDSCAPING_TOOLBAR :{WHITE}Landscaping
STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Dragging lowers the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Click+Drag to lower the first selected corner and level the selected area to the new corner height. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Dragging raises the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Click+Drag to raise the first selected corner and level the selected area to the new corner height. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
# Object construction window # Object construction window
STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build
STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object
STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles
@ -2917,7 +2917,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters
STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_CAPTION :{WHITE}Trees
STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type
STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type
STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only
STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees
STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape
STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal
@ -2930,7 +2930,7 @@ STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plant la
# Land generation window (SE) # Land generation window (SE)
STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Land Generation STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Land Generation
STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Place rocky areas on landscape STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Place rocky areas on landscape
STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Hold Ctrl to remove it STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Ctrl+Click to remove desert area
STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Increase area of land to lower/raise STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Increase area of land to lower/raise
STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrease area of land to lower/raise STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrease area of land to lower/raise
STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND :{BLACK}Generate random land STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND :{BLACK}Generate random land
@ -2944,7 +2944,7 @@ STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Are you
# Town generation window (SE) # Town generation window (SE)
STR_FOUND_TOWN_CAPTION :{WHITE}Town Generation STR_FOUND_TOWN_CAPTION :{WHITE}Town Generation
STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}New Town STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}New Town
STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Found new town. Shift+Click shows only estimated cost STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Found new town. Also press Shift to show cost estimate only
STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random Town STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random Town
STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location
STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns
@ -3010,7 +3010,7 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Select t
# Land area window # Land area window
STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Land Area Information STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Land Area Information
STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centre the main view on tile location. Ctrl+Click opens a new viewport on tile location STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centre the main view on tile location. Ctrl+Click to open a new viewport on tile location
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Cost to clear: {LTBLUE}N/A STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Cost to clear: {LTBLUE}N/A
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Cost to clear: {RED}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Cost to clear: {RED}{CURRENCY_LONG}
STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Revenue when cleared: {LTBLUE}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Revenue when cleared: {LTBLUE}{CURRENCY_LONG}
@ -3257,11 +3257,11 @@ STR_MAPGEN_VARIETY :{BLACK}Variety
STR_MAPGEN_GENERATE :{WHITE}Generate STR_MAPGEN_GENERATE :{WHITE}Generate
STR_MAPGEN_GENERATE_TOOLTIP :{BLACK}Create the world and play OpenTTD! STR_MAPGEN_GENERATE_TOOLTIP :{BLACK}Create the world and play OpenTTD!
STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings
STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Display NewGRF settings STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Open NewGRF settings
STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings
STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Display AI settings STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Open AI settings
STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings
STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Display game script settings STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Open game script settings
###length 21 ###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original)
@ -3537,7 +3537,7 @@ STR_SIGN_LIST_MATCH_CASE_TOOLTIP :{BLACK}Toggle m
# Sign window # Sign window
STR_EDIT_SIGN_CAPTION :{WHITE}Edit sign text STR_EDIT_SIGN_CAPTION :{WHITE}Edit sign text
STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Centre the main view on sign location. Ctrl+Click opens a new viewport on sign location STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Centre the main view on sign location. Ctrl+Click to open a new viewport on sign location
STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP :{BLACK}Go to next sign STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP :{BLACK}Go to next sign
STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Go to previous sign STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Go to previous sign
@ -3548,7 +3548,7 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns
STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_NONE :{ORANGE}- None -
STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA})
STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA})
STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click opens a new viewport on town location STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click to open a new viewport on town location
STR_TOWN_POPULATION :{BLACK}World population: {COMMA} STR_TOWN_POPULATION :{BLACK}World population: {COMMA}
# Town view window # Town view window
@ -3566,7 +3566,7 @@ STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}Town gro
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK}{NBSP}day{P "" s} (funded) STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK}{NBSP}day{P "" s} (funded)
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Town is {RED}not{BLACK} growing STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Town is {RED}not{BLACK} growing
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click opens a new viewport on town location STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click to open a new viewport on town location
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Local Authority STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Local Authority
STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Show information on local authority STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Show information on local authority
STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Change town name STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Change town name
@ -3621,7 +3621,7 @@ STR_GOALS_TEXT :{ORANGE}{RAW_ST
STR_GOALS_NONE :{ORANGE}- None - STR_GOALS_NONE :{ORANGE}- None -
STR_GOALS_PROGRESS :{ORANGE}{RAW_STRING} STR_GOALS_PROGRESS :{ORANGE}{RAW_STRING}
STR_GOALS_PROGRESS_COMPLETE :{GREEN}{RAW_STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{RAW_STRING}
STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on goal to centre main view on industry/town/tile. Ctrl+Click opens a new viewport on industry/town/tile location STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on goal to centre main view on industry/town/tile. Ctrl+Click to open a new viewport on industry/town/tile location
# Goal question window # Goal question window
STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}Question STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}Question
@ -3657,7 +3657,7 @@ STR_SUBSIDIES_OFFERED_FROM_TO :{ORANGE}{STRING
STR_SUBSIDIES_NONE :{ORANGE}- None - STR_SUBSIDIES_NONE :{ORANGE}- None -
STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}Services already subsidised: STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}Services already subsidised:
STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT}) STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT})
STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click opens a new viewport on industry/town location STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click to open a new viewport on industry/town location
# Story book window # Story book window
STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Story Book STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Story Book
@ -3673,8 +3673,8 @@ STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}Go to ne
STR_STORY_BOOK_INVALID_GOAL_REF :{RED}Invalid goal reference STR_STORY_BOOK_INVALID_GOAL_REF :{RED}Invalid goal reference
# Station list window # Station list window
STR_STATION_LIST_TOOLTIP :{BLACK}Station names - click on name to centre main view on station. Ctrl+Click opens a new viewport on station location STR_STATION_LIST_TOOLTIP :{BLACK}Station names - click on name to centre main view on station. Ctrl+Click to open a new viewport on station location
STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold Ctrl to select more than one item STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}Ctrl+Click to select multiple items
STR_STATION_LIST_CAPTION :{WHITE}{COMPANY} - {COMMA} Station{P "" s} STR_STATION_LIST_CAPTION :{WHITE}{COMPANY} - {COMMA} Station{P "" s}
STR_STATION_LIST_STATION :{YELLOW}{STATION} {STATION_FEATURES} STR_STATION_LIST_STATION :{YELLOW}{STATION} {STATION_FEATURES}
STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT} STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT}
@ -3733,7 +3733,7 @@ STR_CARGO_RATING_VERY_GOOD :Very Good
STR_CARGO_RATING_EXCELLENT :Excellent STR_CARGO_RATING_EXCELLENT :Excellent
STR_CARGO_RATING_OUTSTANDING :Outstanding STR_CARGO_RATING_OUTSTANDING :Outstanding
STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on station location. Ctrl+Click opens a new viewport on station location STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on station location. Ctrl+Click to open a new viewport on station location
STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Change name of station STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Change name of station
STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Show all trains which have this station on their schedule STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Show all trains which have this station on their schedule
@ -3748,9 +3748,9 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Prevent
# Waypoint/buoy view window # Waypoint/buoy view window
STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT}
STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on waypoint location. Ctrl+Click opens a new viewport on waypoint location STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on waypoint location. Ctrl+Click to open a new viewport on waypoint location
STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Change waypoint name STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Change waypoint name
STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on buoy location. Ctrl+Click opens a new viewport on buoy location STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on buoy location. Ctrl+Click to open a new viewport on buoy location
STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Change buoy name STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Change buoy name
STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name
@ -3793,9 +3793,9 @@ STR_FINANCES_MAX_LOAN :{WHITE}Maximum
STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG}
STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG}
STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG}
STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click to borrow as much as possible
STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG} STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG}
STR_FINANCES_REPAY_TOOLTIP :{BLACK}Repay part of loan. Ctrl+Click repays as much loan as possible STR_FINANCES_REPAY_TOOLTIP :{BLACK}Repay part of loan. Ctrl+Click to repay as much loan as possible
STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastructure STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastructure
# Company view # Company view
@ -3824,7 +3824,7 @@ STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Build co
STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}View HQ STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}View HQ
STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}View company headquarters STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}View company headquarters
STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Relocate HQ STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Relocate HQ
STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value. Shift+Click shows estimated cost without relocating HQ STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value. Also press Shift to show cost estimate only
STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Details STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Details
STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}View detailed infrastructure counts STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}View detailed infrastructure counts
STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Give money STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Give money
@ -3870,7 +3870,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUST
STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4} STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}
STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4}
STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} and {NUM} more... STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} and {NUM} more...
STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click opens a new viewport on industry location STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click to open a new viewport on industry location
STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Accepted cargo: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Accepted cargo: {SILVER}{STRING}
STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produced cargo: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produced cargo: {SILVER}{STRING}
STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All cargo types STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All cargo types
@ -3880,7 +3880,7 @@ STR_INDUSTRY_DIRECTORY_FILTER_NONE :None
STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY}
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Production last month: STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Production last month:
STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{RAW_STRING}{BLACK} ({COMMA}% transported) STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{RAW_STRING}{BLACK} ({COMMA}% transported)
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centre the main view on industry location. Ctrl+Click opens a new viewport on industry location STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centre the main view on industry location. Ctrl+Click to open a new viewport on industry location
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Production level: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Production level: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}The industry has announced imminent closure! STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}The industry has announced imminent closure!
@ -4019,10 +4019,10 @@ STR_CARGO_TYPE_FILTER_FREIGHT :Freight
STR_CARGO_TYPE_FILTER_NONE :None STR_CARGO_TYPE_FILTER_NONE :None
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click to show/hide this vehicle type
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click to show/hide of the vehicle type
STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Ship selection list. Click on ship for information. Ctrl+Click for toggling hiding of the ship type STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Ship selection list. Click on ship for information. Ctrl+Click to show/hide of the ship type
STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft selection list. Click on aircraft for information. Ctrl+Click for toggling hiding of the aircraft type STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft selection list. Click on aircraft for information. Ctrl+Click to show/hide of the aircraft type
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehicle STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehicle
@ -4037,16 +4037,16 @@ STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and
STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Aircraft STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Aircraft
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Also press Shift to show cost estimate only
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Also press Shift to show cost estimate only
STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Also press Shift to show cost estimate only
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename
@ -4096,7 +4096,7 @@ STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} ve
STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT})
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Trains - drag vehicle with left-click to add/remove from train, right-click for information. Hold Ctrl to make both functions apply to the following chain STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Trains - drag vehicle with left-click to add/remove from train, right-click for information. Ctrl+Click to apply either function to the following chain
STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vehicles - right-click on vehicle for information STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vehicles - right-click on vehicle for information
STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Ships - right-click on ship for information STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Ships - right-click on ship for information
STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft - right-click on aircraft for information STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft - right-click on aircraft for information
@ -4138,16 +4138,16 @@ STR_DEPOT_CLONE_SHIP :{BLACK}Clone Sh
STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Clone Aircraft STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Clone Aircraft
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}This will buy a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Buy a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only
STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}This will buy a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Buy a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only
STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}This will buy a copy of a ship. Click this button and then on a ship inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Buy a copy of a ship. Click this button and then on a ship inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only
STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}This will buy a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Buy a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Ctrl+Click to share the orders. Also press Shift to show cost estimate only
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centre main view on train depot location. Ctrl+Click opens a new viewport on train depot location STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centre main view on train depot location. Ctrl+Click to open a new viewport on train depot location
STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centre main view on road vehicle depot location. Ctrl+Click opens a new viewport on road depot location STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centre main view on road vehicle depot location. Ctrl+Click to open a new viewport on road depot location
STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Centre main view on ship depot location. Ctrl+Click opens a new viewport on ship depot location STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Centre main view on ship depot location. Ctrl+Click to open a new viewport on ship depot location
STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centre main view on hangar location. Ctrl+Click opens a new viewport on hangar location STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centre main view on hangar location. Ctrl+Click to open a new viewport on hangar location
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Get a list of all trains with the current depot in their orders STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Get a list of all trains with the current depot in their orders
@ -4248,27 +4248,27 @@ STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+
STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE}
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Centre main view on train's location. Double click will follow train in main view. Ctrl+Click opens a new viewport on train's location STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Centre main view on train's location. Double click to follow train in main view. Ctrl+Click to open a new viewport on train's location
STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Centre main view on vehicle's location. Double click will follow vehicle in main view. Ctrl+Click opens a new viewport on vehicle's location STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Centre main view on vehicle's location. Double click to follow vehicle in main view. Ctrl+Click to open a new viewport on vehicle's location
STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Centre main view on ship's location. Double click will follow ship in main view. Ctrl+Click opens a new viewport on ship's location STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Centre main view on ship's location. Double click to follow ship in main view. Ctrl+Click to open a new viewport on ship's location
STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centre main view on aircraft's location. Double click will follow aircraft in main view. Ctrl+Click opens a new viewport on aircraft's location STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centre main view on aircraft's location. Double click to follow aircraft in main view. Ctrl+Click to open a new viewport on aircraft's location
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send train to depot. Ctrl+Click will only service STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send train to depot. Ctrl+Click to only service
STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send vehicle to depot. Ctrl+Click will only service STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send vehicle to depot. Ctrl+Click to only service
STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send ship to depot. Ctrl+Click will only service STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send ship to depot. Ctrl+Click to only service
STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send aircraft to hangar. Ctrl+Click will only service STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send aircraft to hangar. Ctrl+Click to only service
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}This will buy a copy of the train including all cars. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Buy a copy of the train including all cars. Ctrl+Click to share orders. Also press Shift to show cost estimate only
STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}This will buy a copy of the road vehicle. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Buy a copy of the road vehicle. Ctrl+Click to share orders. Also press Shift to show cost estimate only
STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}This will buy a copy of the ship. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Buy a copy of the ship. Ctrl+Click to share orders. Also press Shift to show cost estimate only
STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}This will buy a copy of the aircraft. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Buy a copy of the aircraft. Ctrl+Click to share orders. Also press Shift to show cost estimate only
STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Force train to proceed without waiting for signal to clear it STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Force train to proceed without waiting for signal to clear it
STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Reverse direction of train STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Reverse direction of train
STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Force vehicle to turn around STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Force vehicle to turn around
STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centre main view on order destination. Ctrl+Click opens a new viewport on the order destination's location STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centre main view on order destination. Ctrl+Click to open a new viewport on the order destination's location
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Refit train to carry a different cargo type STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Refit train to carry a different cargo type
@ -4358,8 +4358,8 @@ STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK} Last service: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK} Last service: {LTBLUE}{DATE_LONG}
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG}
STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by 10. Ctrl+Click increases servicing interval by 5 STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by 10. Ctrl+Click to increase servicing interval by 5
STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by 10. Ctrl+Click decreases servicing interval by 5 STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by 10. Ctrl+Click to decrease servicing interval by 5
STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Change servicing interval type STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Change servicing interval type
STR_VEHICLE_DETAILS_DEFAULT :Default STR_VEHICLE_DETAILS_DEFAULT :Default
@ -4402,7 +4402,7 @@ STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capa
STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG}
STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {RED}{CURRENCY_LONG}
STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG}
STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Dragging with the mouse allows to select multiple vehicles. Clicking on an empty space will select the whole vehicle. Ctrl+Click will select a vehicle and the following chain STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Click+Drag to select multiple vehicles. Click on an empty space to select the whole vehicle. Ctrl+Click to select a vehicle and the following chain
###length VEHICLE_TYPES ###length VEHICLE_TYPES
STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry
@ -4427,7 +4427,7 @@ STR_ORDERS_CAPTION :{WHITE}{VEHICLE
STR_ORDERS_TIMETABLE_VIEW :{BLACK}Timetable STR_ORDERS_TIMETABLE_VIEW :{BLACK}Timetable
STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Switch to the timetable view STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Switch to the timetable view
STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click scrolls to the order's destination STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click to scroll to the order's destination
STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_INDEX :{COMMA}:{NBSP}
STR_ORDER_TEXT :{STRING4} {STRING2} {STRING} STR_ORDER_TEXT :{STRING4} {STRING2} {STRING}
@ -4497,20 +4497,20 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}The valu
STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against
STR_ORDERS_SKIP_BUTTON :{BLACK}Skip STR_ORDERS_SKIP_BUTTON :{BLACK}Skip
STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click to skip to the selected order
STR_ORDERS_DELETE_BUTTON :{BLACK}Delete STR_ORDERS_DELETE_BUTTON :{BLACK}Delete
STR_ORDERS_DELETE_TOOLTIP :{BLACK}Delete the highlighted order STR_ORDERS_DELETE_TOOLTIP :{BLACK}Delete the highlighted order
STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Delete all orders STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Delete all orders
STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Stop sharing STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Stop sharing
STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Stop sharing the order list. Ctrl+Click additionally deletes all orders for this vehicle STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Stop sharing the order list. Ctrl+Click to additionally delete all orders for this vehicle
STR_ORDERS_GO_TO_BUTTON :{BLACK}Go To STR_ORDERS_GO_TO_BUTTON :{BLACK}Go To
STR_ORDER_GO_TO_NEAREST_DEPOT :Go to nearest depot STR_ORDER_GO_TO_NEAREST_DEPOT :Go to nearest depot
STR_ORDER_GO_TO_NEAREST_HANGAR :Go to nearest hangar STR_ORDER_GO_TO_NEAREST_HANGAR :Go to nearest hangar
STR_ORDER_CONDITIONAL :Conditional order jump STR_ORDER_CONDITIONAL :Conditional order jump
STR_ORDER_SHARE :Share orders STR_ORDER_SHARE :Share orders
STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Insert a new order before the highlighted order, or add to end of list. Ctrl makes station orders 'full load any cargo', waypoint orders 'non-stop' and depot orders 'service'. 'Share orders' or Ctrl lets this vehicle share orders with the selected vehicle. Clicking a vehicle copies the orders from that vehicle. A depot order disables automatic servicing of the vehicle STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Insert a new order before the highlighted order, or add to end of list. Ctrl+Click on a station for 'full load any cargo', on a waypoint for 'non-stop', or on a depot for 'service'. Click on another vehicle to copy its orders or Ctrl+Click to share orders. A depot order disables automatic servicing of the vehicle
STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Show all vehicles that share this schedule STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Show all vehicles that share this schedule
@ -4616,24 +4616,24 @@ STR_TIMETABLE_STATUS_START_AT_DATE :{BLACK}This tim
STR_TIMETABLE_STATUS_START_IN_SECONDS :{BLACK}This timetable will start in {COMMA} seconds STR_TIMETABLE_STATUS_START_IN_SECONDS :{BLACK}This timetable will start in {COMMA} seconds
STR_TIMETABLE_START :{BLACK}Start Timetable STR_TIMETABLE_START :{BLACK}Start Timetable
STR_TIMETABLE_START_TOOLTIP :{BLACK}Select when this timetable starts. Ctrl+Click evenly distributes the start of all vehicles sharing this order based on their relative order, if the order is completely timetabled STR_TIMETABLE_START_TOOLTIP :{BLACK}Select when this timetable starts. Ctrl+Click to evenly distribute the start of all vehicles sharing this order based on their relative order, if the order is completely timetabled
STR_TIMETABLE_START_SECONDS_QUERY :Seconds until timetable starts STR_TIMETABLE_START_SECONDS_QUERY :Seconds until timetable starts
STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time
STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click sets the time for all orders STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click to set the time for all orders
STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time
STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click clears the time for all orders STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click to clear the time for all orders
STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit
STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click sets the speed for all orders STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click to set the speed for all orders
STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit
STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click clears the speed for all orders STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click to clear the speed for all orders
STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter
STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click will reset the entire group so the latest vehicle will be on time and all others will be early STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click to reset the entire group so the latest vehicle will be on time and all others will be early
STR_TIMETABLE_AUTOFILL :{BLACK}Autofill STR_TIMETABLE_AUTOFILL :{BLACK}Autofill
STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times

View File

@ -31,7 +31,7 @@
#include "town_kdtree.h" #include "town_kdtree.h"
#include "viewport_kdtree.h" #include "viewport_kdtree.h"
#include "newgrf_profiling.h" #include "newgrf_profiling.h"
#include "3rdparty/md5/md5.h" #include "3rdparty/monocypher/monocypher.h"
#include "safeguards.h" #include "safeguards.h"
@ -61,25 +61,24 @@ void InitializeOldNames();
/** /**
* Generate an unique ID. * Generate an unique ID.
* *
* It isn't as much of an unique ID as we would like, but our random generator * It isn't as much of an unique ID but more a hashed digest of a random
* can only produce 32bit random numbers. * string and a time. It is very likely to be unique, but it does not follow
* That is why we combine InteractiveRandom with the current (steady) clock. * any UUID standard.
* The first to add a bit of randomness, the second to ensure you can't get
* the same unique ID when you run it twice from the same state at different
* times.
*
* This makes it unlikely that two users generate the same ID for different
* subjects. But as this is not an UUID, so it can't be ruled out either.
*/ */
std::string GenerateUid(std::string_view subject) std::string GenerateUid(std::string_view subject)
{ {
auto current_time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); std::array<uint8_t, 32> random_bytes;
std::string coding_string = fmt::format("{}{}{}", InteractiveRandom(), current_time, subject); RandomBytesWithFallback(random_bytes);
Md5 checksum; auto current_time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
MD5Hash digest; std::string coding_string = fmt::format("{}{}", current_time, subject);
checksum.Append(coding_string.c_str(), coding_string.length());
checksum.Finish(digest); std::array<uint8_t, 16> digest;
crypto_blake2b_ctx ctx;
crypto_blake2b_init(&ctx, digest.size());
crypto_blake2b_update(&ctx, random_bytes.data(), random_bytes.size());
crypto_blake2b_update(&ctx, reinterpret_cast<const uint8_t *>(coding_string.data()), coding_string.size());
crypto_blake2b_final(&ctx, digest.data());
return FormatArrayAsHex(digest); return FormatArrayAsHex(digest);
} }

View File

@ -1642,20 +1642,20 @@ public:
this->smallest_y = std::max(min_inf_height, min_acs_height + WidgetDimensions::scaled.vsep_wide + min_avs_height); this->smallest_y = std::max(min_inf_height, min_acs_height + WidgetDimensions::scaled.vsep_wide + min_avs_height);
/* Filling. */ /* Filling. */
this->fill_x = LeastCommonMultiple(this->avs->fill_x, this->acs->fill_x); this->fill_x = std::lcm(this->avs->fill_x, this->acs->fill_x);
if (this->inf->fill_x > 0 && (this->fill_x == 0 || this->fill_x > this->inf->fill_x)) this->fill_x = this->inf->fill_x; if (this->inf->fill_x > 0 && (this->fill_x == 0 || this->fill_x > this->inf->fill_x)) this->fill_x = this->inf->fill_x;
this->fill_y = this->avs->fill_y; this->fill_y = this->avs->fill_y;
if (this->acs->fill_y > 0 && (this->fill_y == 0 || this->fill_y > this->acs->fill_y)) this->fill_y = this->acs->fill_y; if (this->acs->fill_y > 0 && (this->fill_y == 0 || this->fill_y > this->acs->fill_y)) this->fill_y = this->acs->fill_y;
this->fill_y = LeastCommonMultiple(this->fill_y, this->inf->fill_y); this->fill_y = std::lcm(this->fill_y, this->inf->fill_y);
/* Resizing. */ /* Resizing. */
this->resize_x = LeastCommonMultiple(this->avs->resize_x, this->acs->resize_x); this->resize_x = std::lcm(this->avs->resize_x, this->acs->resize_x);
if (this->inf->resize_x > 0 && (this->resize_x == 0 || this->resize_x > this->inf->resize_x)) this->resize_x = this->inf->resize_x; if (this->inf->resize_x > 0 && (this->resize_x == 0 || this->resize_x > this->inf->resize_x)) this->resize_x = this->inf->resize_x;
this->resize_y = this->avs->resize_y; this->resize_y = this->avs->resize_y;
if (this->acs->resize_y > 0 && (this->resize_y == 0 || this->resize_y > this->acs->resize_y)) this->resize_y = this->acs->resize_y; if (this->acs->resize_y > 0 && (this->resize_y == 0 || this->resize_y > this->acs->resize_y)) this->resize_y = this->acs->resize_y;
this->resize_y = LeastCommonMultiple(this->resize_y, this->inf->resize_y); this->resize_y = std::lcm(this->resize_y, this->inf->resize_y);
/* Make sure the height suits the 3 column (resp. not-editable) format; the 2 column format can easily fill space between the lists */ /* Make sure the height suits the 3 column (resp. not-editable) format; the 2 column format can easily fill space between the lists */
this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y); this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y);

View File

@ -13,41 +13,6 @@
#include "../core/math_func.hpp" #include "../core/math_func.hpp"
TEST_CASE("LeastCommonMultipleTest - Zero")
{
CHECK(0 == LeastCommonMultiple(0, 0));
CHECK(0 == LeastCommonMultiple(0, 600));
CHECK(0 == LeastCommonMultiple(600, 0));
}
TEST_CASE("LeastCommonMultipleTest - FindLCM")
{
CHECK(25 == LeastCommonMultiple(5, 25));
CHECK(25 == LeastCommonMultiple(25, 5));
CHECK(130 == LeastCommonMultiple(5, 26));
CHECK(130 == LeastCommonMultiple(26, 5));
}
TEST_CASE("GreatestCommonDivisorTest - Negative")
{
CHECK(4 == GreatestCommonDivisor(4, -52));
// CHECK(3 == GreatestCommonDivisor(-27, 6)); // error - returns -3
}
TEST_CASE("GreatestCommonDivisorTest - Zero")
{
CHECK(27 == GreatestCommonDivisor(0, 27));
CHECK(27 == GreatestCommonDivisor(27, 0));
}
TEST_CASE("GreatestCommonDivisorTest - FindGCD")
{
CHECK(5 == GreatestCommonDivisor(5, 25));
CHECK(5 == GreatestCommonDivisor(25, 5));
CHECK(1 == GreatestCommonDivisor(7, 27));
CHECK(1 == GreatestCommonDivisor(27, 7));
}
TEST_CASE("DivideApproxTest - Negative") TEST_CASE("DivideApproxTest - Negative")
{ {
CHECK(-2 == DivideApprox(-5, 2)); CHECK(-2 == DivideApprox(-5, 2));

View File

@ -1239,10 +1239,10 @@ void NWidgetStacked::SetupSmallestSize(Window *w)
this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal());
this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical());
this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); this->fill_x = std::lcm(this->fill_x, child_wid->fill_x);
this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->fill_y = std::lcm(this->fill_y, child_wid->fill_y);
this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); this->resize_x = std::lcm(this->resize_x, child_wid->resize_x);
this->resize_y = LeastCommonMultiple(this->resize_y, child_wid->resize_y); this->resize_y = std::lcm(this->resize_y, child_wid->resize_y);
} }
} }
@ -1409,12 +1409,12 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w)
if (child_wid->fill_x > 0) { if (child_wid->fill_x > 0) {
if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x; if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x;
} }
this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->fill_y = std::lcm(this->fill_y, child_wid->fill_y);
if (child_wid->resize_x > 0) { if (child_wid->resize_x > 0) {
if (this->resize_x == 0 || this->resize_x > child_wid->resize_x) this->resize_x = child_wid->resize_x; if (this->resize_x == 0 || this->resize_x > child_wid->resize_x) this->resize_x = child_wid->resize_x;
} }
this->resize_y = LeastCommonMultiple(this->resize_y, child_wid->resize_y); this->resize_y = std::lcm(this->resize_y, child_wid->resize_y);
} }
if (this->fill_x == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_x = 1; if (this->fill_x == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_x = 1;
/* 4. Increase by required PIP space. */ /* 4. Increase by required PIP space. */
@ -1598,12 +1598,12 @@ void NWidgetVertical::SetupSmallestSize(Window *w)
if (child_wid->fill_y > 0) { if (child_wid->fill_y > 0) {
if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y; if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y;
} }
this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); this->fill_x = std::lcm(this->fill_x, child_wid->fill_x);
if (child_wid->resize_y > 0) { if (child_wid->resize_y > 0) {
if (this->resize_y == 0 || this->resize_y > child_wid->resize_y) this->resize_y = child_wid->resize_y; if (this->resize_y == 0 || this->resize_y > child_wid->resize_y) this->resize_y = child_wid->resize_y;
} }
this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); this->resize_x = std::lcm(this->resize_x, child_wid->resize_x);
} }
if (this->fill_y == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_y = 1; if (this->fill_y == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_y = 1;
/* 4. Increase by required PIP space. */ /* 4. Increase by required PIP space. */