Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab76e8738c | |||
|
|
338def1b06 | ||
|
|
f6a88e40a4 | ||
|
|
08cf106fc6 | ||
|
|
243c6bead3 | ||
|
|
931aa39018 | ||
|
|
9750826590 | ||
|
|
72b5c6a591 | ||
|
|
2047c27445 | ||
|
|
56cac21086 | ||
|
|
11aa3694fa | ||
|
|
3de8853e29 | ||
|
|
00e0021e3a | ||
|
|
295508fc53 | ||
|
|
f79ec7955a | ||
|
|
bd2a92331b | ||
|
|
f6b38e8e06 | ||
|
|
e4fc8ef595 | ||
|
|
6f36f3d714 | ||
|
|
92a171c3e0 | ||
|
|
d68e5159e1 | ||
|
|
3d2a8fb60c | ||
|
|
d683ec0183 | ||
|
|
d5e28a904d | ||
|
|
9954187680 | ||
|
|
77f02faf15 | ||
|
|
340c2802da | ||
|
|
e866ca8adc | ||
|
|
c0308acb03 | ||
|
|
8d312b305b | ||
|
|
e21c12afeb | ||
|
|
e16b982b6a | ||
|
|
3e83dcedfd | ||
|
|
8746be8bf2 | ||
|
|
907cb4fc53 | ||
|
|
8fb7d74dfe | ||
|
|
69acc132ca | ||
|
|
71087bb6d3 | ||
|
|
ca53e134be | ||
|
|
433484cda3 | ||
|
|
b8b01818ca | ||
|
|
575336ef43 | ||
|
|
8e12bd35ae | ||
|
|
4751179dc5 | ||
|
|
9aa6669266 | ||
|
|
84bbe235e4 | ||
|
|
f71ada4f30 | ||
|
|
f845b4bbc3 | ||
|
|
40a75e0b8d | ||
|
|
97c1738541 | ||
|
|
eebfb83aa2 | ||
|
|
8928f4979a | ||
|
|
caa7c44052 | ||
|
|
d09b5aaeba | ||
|
|
c01bf06ee1 | ||
|
|
018944dc20 | ||
|
|
668186ca5b | ||
|
|
ff35288ddf | ||
|
|
02c00f3e3e | ||
|
|
704e871a0e | ||
|
|
603154899a | ||
|
|
0f25eaa271 | ||
|
|
515303b8be | ||
|
|
2732b3d6c6 | ||
|
|
ea74ca0a76 | ||
|
|
f599108c16 | ||
|
|
4321cca5fb | ||
|
|
df2ee7b06c | ||
|
|
e904122441 | ||
|
|
7457f8d0ff | ||
|
|
5751da7809 | ||
|
|
e141734e54 | ||
|
|
2189607c34 | ||
|
|
e42aec5a89 | ||
|
|
0eaeeaabb6 | ||
|
|
704d3b8a9b | ||
|
|
00a09af1fd | ||
|
|
d4a6ee9554 | ||
|
|
3a3d8f3b53 | ||
|
|
737e3feaf0 | ||
|
|
7580eac2d5 | ||
|
|
2485de9462 | ||
|
|
107c208d87 | ||
|
|
ec3c8d3462 | ||
|
|
4af089b9be | ||
|
|
b7dfa3eb90 | ||
|
|
1cf8799810 | ||
|
|
d26629c15b | ||
|
|
5706801ea7 | ||
|
|
dd532cbc77 | ||
|
|
fb9d4afa5c | ||
|
|
88cf99017a | ||
|
|
322ca6ef54 | ||
|
|
3fc7b3b9a0 | ||
|
|
f08da1d373 | ||
|
|
ab94c8b511 | ||
|
|
6c5a8f55df | ||
|
|
a886bd9666 | ||
|
|
a3cfd23cf9 | ||
|
|
bd7120bae4 | ||
|
|
af1bd43b30 | ||
|
|
0058ebe472 | ||
|
|
818a57c9af | ||
|
|
d7c5e9e8ab | ||
|
|
7f49b6f25a | ||
|
|
5f4f9334ce | ||
|
|
4c0dca1411 | ||
|
|
fe12d38024 | ||
|
|
15d02f51ed | ||
|
|
b6c75dec3a | ||
|
|
26d1d5d6e7 | ||
|
|
6eff879e49 | ||
|
|
3c488e1eb8 | ||
|
|
ec4104ec6c | ||
|
|
3e625b5b1a | ||
|
|
b394c20519 | ||
|
|
a7625b8ae0 | ||
|
|
9db285a32b | ||
|
|
2d2191fbb3 | ||
|
|
23d733be95 | ||
|
|
24efdf6ac5 | ||
|
|
14d95ef1c9 | ||
|
|
100c043599 | ||
|
|
0cff40dd19 | ||
|
|
1addeddc07 | ||
|
|
8a37f6479a | ||
|
|
a06814c173 | ||
|
|
984202b101 | ||
|
|
d7b99cbe26 | ||
|
|
c768f4fc7a | ||
|
|
ee22fa34d7 | ||
|
|
eaf62f3969 | ||
|
|
b9ca3ead8b | ||
|
|
dc6305e8c1 | ||
|
|
95a8fab339 | ||
|
|
8b60fc3d35 | ||
|
|
2f0fe22d63 | ||
|
|
649c1cf14c | ||
|
|
ecf534522c | ||
|
|
27eadc13ec | ||
|
|
df461b0329 | ||
|
|
005892bfdb | ||
|
|
cca9dcdd57 | ||
|
|
9c95fbdb07 | ||
|
|
86cb184eb4 | ||
|
|
e4b3f3f495 | ||
|
|
bab5a8a787 | ||
|
|
381dee2e01 | ||
|
|
738624ded4 | ||
|
|
55a328c586 | ||
|
|
de8a840db5 | ||
|
|
82430a1086 | ||
|
|
e0e0d5f8fb | ||
|
|
ebd258b404 | ||
|
|
32b0fb9f6e | ||
|
|
04ce1c08ae | ||
|
|
ab315d0dc9 | ||
|
|
6e0f58f700 | ||
|
|
3a71f36393 | ||
|
|
ae27ce12a7 | ||
|
|
ce3d0097f6 | ||
|
|
08ff1ab93e | ||
|
|
ab353f8ad5 | ||
|
|
8b9f59d320 | ||
|
|
8dda387f82 | ||
|
|
5806c2aba4 | ||
|
|
0c432bdc4d | ||
|
|
ab52f7eecf | ||
|
|
b8b80cb42e | ||
|
|
aef8a345b2 | ||
|
|
63b9284a7e | ||
|
|
a9de766fa6 | ||
|
|
30e1a61c04 | ||
|
|
216905ce1f | ||
|
|
25aeb1c5a5 | ||
|
|
8fb26612c0 | ||
|
|
ef40c5e240 | ||
|
|
634b67bf13 | ||
|
|
1a2b54498b | ||
|
|
2d48829999 | ||
|
|
00b442d6f9 | ||
|
|
bc3bd642b9 | ||
|
|
845b894fd8 | ||
|
|
0fd576bfbc | ||
|
|
626ee4ab41 | ||
|
|
8172e25273 | ||
|
|
b2ca6e1ac8 | ||
|
|
cff48c0f63 | ||
|
|
41b3314d76 | ||
|
|
278c3a7db1 | ||
|
|
c5afc9173c | ||
|
|
f180262aee | ||
|
|
d7c485d4b9 | ||
|
|
8f22066b9a | ||
|
|
aff09306de | ||
|
|
253ba0d354 | ||
|
|
b53d79b1d2 | ||
|
|
a602845d0a | ||
|
|
3fd5c33ae6 | ||
|
|
7824ae5b59 | ||
|
|
b307541099 | ||
|
|
890040ceea | ||
|
|
667adf7df9 | ||
|
|
f0a891c4f7 | ||
|
|
c0b5510a94 | ||
|
|
c4f9479507 | ||
|
|
fad77261ea | ||
|
|
d4f0f0e2c5 | ||
|
|
529d813496 | ||
|
|
e93d081a4a | ||
|
|
59420d57ec | ||
|
|
a61311fcb0 | ||
|
|
bf865dc536 | ||
|
|
f612bc6ee2 | ||
|
|
2fb1593550 | ||
|
|
e775ef2b70 | ||
|
|
149592e4dd | ||
|
|
e939f59cbb | ||
|
|
7b1e3cfeb5 | ||
|
|
86be6d7e0b | ||
|
|
912d7bd80e | ||
|
|
ae3390fe48 | ||
|
|
0463d4c198 | ||
|
|
56cf89d189 | ||
|
|
8afef45d4e | ||
|
|
ddb3914074 | ||
|
|
677ec70b0e | ||
|
|
c25d9f5c81 | ||
|
|
222832f1d4 | ||
|
|
7135330819 | ||
|
|
b22fb43cea | ||
|
|
2b79e7cdf5 | ||
|
|
bb86023d50 | ||
|
|
4c117dd2d8 | ||
|
|
8015d96a50 | ||
|
|
5d2e6e4efa | ||
|
|
ca146c8ddd | ||
|
|
409c073eca | ||
|
|
7bab2c1cc3 | ||
|
|
c637d376d0 | ||
|
|
ad9080338c | ||
|
|
bff69e192b | ||
|
|
25d1238907 | ||
|
|
2d7ad9f717 | ||
|
|
f1bf39f38b | ||
|
|
a4d4301a0c |
@@ -14,3 +14,7 @@ notifications:
|
||||
pull-request:
|
||||
issue:
|
||||
tag-created:
|
||||
workflow-run:
|
||||
only:
|
||||
- .github/workflows/release.yml
|
||||
- .github/workflows/ci-nightly.yml
|
||||
|
||||
403
.github/workflows/ci-build.yml
vendored
403
.github/workflows/ci-build.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: CI
|
||||
name: CI - Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -17,79 +17,22 @@ jobs:
|
||||
emscripten:
|
||||
name: Emscripten
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
container:
|
||||
# If you change this version, change the number in the cache step too.
|
||||
image: emscripten/emsdk:3.1.42
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /emsdk/upstream/emscripten/cache
|
||||
key: 3.1.42-${{ runner.os }}
|
||||
|
||||
- name: Patch Emscripten to support LZMA
|
||||
run: |
|
||||
cd /emsdk/upstream/emscripten
|
||||
patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch
|
||||
|
||||
- name: Build (host tools)
|
||||
run: |
|
||||
mkdir build-host
|
||||
cd build-host
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. -DOPTION_TOOLS_ONLY=ON
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc) --target tools
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
emcmake cmake .. -DHOST_BINARY_DIR=../build-host
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc) --target openttd
|
||||
echo "::endgroup::"
|
||||
uses: ./.github/workflows/ci-emscripten.yml
|
||||
secrets: inherit
|
||||
|
||||
linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Clang - Debug
|
||||
- name: Clang
|
||||
compiler: clang-15
|
||||
cxxcompiler: clang++-15
|
||||
libraries: libsdl2-dev
|
||||
- name: Clang - Release
|
||||
compiler: clang-15
|
||||
cxxcompiler: clang++-15
|
||||
libraries: libsdl2-dev
|
||||
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF
|
||||
- name: GCC - SDL2
|
||||
compiler: gcc
|
||||
cxxcompiler: g++
|
||||
libraries: libsdl2-dev
|
||||
- name: GCC - SDL1.2
|
||||
compiler: gcc
|
||||
cxxcompiler: g++
|
||||
libraries: libsdl1.2-dev
|
||||
- name: GCC - Dedicated
|
||||
compiler: gcc
|
||||
cxxcompiler: g++
|
||||
@@ -99,332 +42,57 @@ jobs:
|
||||
|
||||
name: Linux (${{ matrix.name }})
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
CXX: ${{ matrix.cxxcompiler }}
|
||||
uses: ./.github/workflows/ci-linux.yml
|
||||
secrets: inherit
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "::group::Update apt"
|
||||
sudo apt-get update
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Install dependencies"
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
liballegro4-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libfontconfig-dev \
|
||||
libharfbuzz-dev \
|
||||
libicu-dev \
|
||||
liblzma-dev \
|
||||
liblzo2-dev \
|
||||
${{ matrix.libraries }} \
|
||||
zlib1g-dev \
|
||||
# EOF
|
||||
|
||||
echo "::group::Install vcpkg dependencies"
|
||||
|
||||
# Disable vcpkg integration, as we mostly use system libraries.
|
||||
mv vcpkg.json vcpkg-disabled.json
|
||||
|
||||
# We only use breakpad from vcpkg, as its CMake files
|
||||
# are a bit special. So the Ubuntu's variant doesn't work.
|
||||
./vcpkg/vcpkg install breakpad
|
||||
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Get OpenGFX
|
||||
run: |
|
||||
mkdir -p ~/.local/share/openttd/baseset
|
||||
cd ~/.local/share/openttd/baseset
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/vcpkg/scripts/buildsystems/vcpkg.cmake ${{ matrix.extra-cmake-parameters }}
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc)
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
(
|
||||
cd build
|
||||
ctest -j $(nproc) --timeout 120
|
||||
)
|
||||
|
||||
# Re-enable vcpkg.
|
||||
mv vcpkg-disabled.json vcpkg.json
|
||||
|
||||
# Check no tracked files have been modified.
|
||||
git diff --exit-code
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
cxxcompiler: ${{ matrix.cxxcompiler }}
|
||||
libraries: ${{ matrix.libraries }}
|
||||
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
|
||||
|
||||
macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
- name: arm64 - Debug
|
||||
arch: arm64
|
||||
full_arch: arm64
|
||||
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=Debug
|
||||
- name: arm64 - Release
|
||||
arch: arm64
|
||||
full_arch: arm64
|
||||
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF
|
||||
|
||||
name: Mac OS (${{ matrix.arch }})
|
||||
name: Mac OS (${{ matrix.name }})
|
||||
|
||||
runs-on: macos-14
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
uses: ./.github/workflows/ci-macos.yml
|
||||
secrets: inherit
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||
|
||||
- name: Install OpenGFX
|
||||
run: |
|
||||
mkdir -p ~/Documents/OpenTTD/baseset
|
||||
cd ~/Documents/OpenTTD/baseset
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.full_arch }} \
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-osx \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(sysctl -n hw.logicalcpu) cores"
|
||||
cmake --build . -j $(sysctl -n hw.logicalcpu)
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
full_arch: ${{ matrix.full_arch }}
|
||||
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
arch: [x86, x64]
|
||||
|
||||
name: Windows (${{ matrix.os }} / ${{ matrix.arch }})
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
.\vcpkg\bootstrap-vcpkg.bat -disableMetrics
|
||||
|
||||
- name: Install OpenGFX
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install MSVC problem matcher
|
||||
uses: ammaraskar/msvc-problem-matcher@master
|
||||
|
||||
- name: Configure developer command prompt for ${{ matrix.arch }}
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
env:
|
||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${GITHUB_WORKSPACE}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
cmake --build .
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
ctest --timeout 120
|
||||
|
||||
|
||||
msys2:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- msystem: MINGW64
|
||||
arch: x86_64
|
||||
- msystem: MINGW32
|
||||
arch: i686
|
||||
- os: windows-latest
|
||||
arch: x86
|
||||
- os: windows-latest
|
||||
arch: x64
|
||||
|
||||
name: MinGW (${{ matrix.arch }})
|
||||
name: Windows (${{ matrix.arch }})
|
||||
|
||||
runs-on: windows-latest
|
||||
uses: ./.github/workflows/ci-windows.yml
|
||||
secrets: inherit
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
release: false
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-${{ matrix.arch }}-cmake
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-lzo2
|
||||
mingw-w64-${{ matrix.arch }}-libpng
|
||||
mingw-w64-${{ matrix.arch }}-lld
|
||||
mingw-w64-${{ matrix.arch }}-ninja
|
||||
|
||||
- name: Install OpenGFX
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
cmake --build .
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
cd build
|
||||
ctest --timeout 120
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
check_annotations:
|
||||
name: Check Annotations
|
||||
@@ -433,7 +101,6 @@ jobs:
|
||||
- linux
|
||||
- macos
|
||||
- windows
|
||||
- msys2
|
||||
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
|
||||
|
||||
62
.github/workflows/ci-emscripten.yml
vendored
Normal file
62
.github/workflows/ci-emscripten.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: CI (Emscripten)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
emscripten:
|
||||
name: CI
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
container:
|
||||
# If you change this version, change the number in the cache step too.
|
||||
image: emscripten/emsdk:3.1.42
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /emsdk/upstream/emscripten/cache
|
||||
key: 3.1.42-${{ runner.os }}
|
||||
|
||||
- name: Patch Emscripten to support LZMA
|
||||
run: |
|
||||
cd /emsdk/upstream/emscripten
|
||||
patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch
|
||||
|
||||
- name: Build (host tools)
|
||||
run: |
|
||||
mkdir build-host
|
||||
cd build-host
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. -DOPTION_TOOLS_ONLY=ON
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc) --target tools
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
emcmake cmake .. -DHOST_BINARY_DIR=../build-host
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc) --target openttd
|
||||
echo "::endgroup::"
|
||||
123
.github/workflows/ci-linux.yml
vendored
Normal file
123
.github/workflows/ci-linux.yml
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
name: CI (Linux)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
compiler:
|
||||
required: true
|
||||
type: string
|
||||
cxxcompiler:
|
||||
required: true
|
||||
type: string
|
||||
libraries:
|
||||
required: true
|
||||
type: string
|
||||
extra-cmake-parameters:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: CI
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CC: ${{ inputs.compiler }}
|
||||
CXX: ${{ inputs.cxxcompiler }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "::group::Update apt"
|
||||
sudo apt-get update
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Install dependencies"
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
liballegro4-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libfontconfig-dev \
|
||||
libharfbuzz-dev \
|
||||
libicu-dev \
|
||||
liblzma-dev \
|
||||
liblzo2-dev \
|
||||
${{ inputs.libraries }} \
|
||||
zlib1g-dev \
|
||||
# EOF
|
||||
|
||||
echo "::group::Install vcpkg dependencies"
|
||||
|
||||
# Disable vcpkg integration, as we mostly use system libraries.
|
||||
mv vcpkg.json vcpkg-disabled.json
|
||||
|
||||
# We only use breakpad from vcpkg, as its CMake files
|
||||
# are a bit special. So the Ubuntu's variant doesn't work.
|
||||
${{ runner.temp }}/vcpkg/vcpkg install breakpad
|
||||
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Get OpenGFX
|
||||
run: |
|
||||
mkdir -p ~/.local/share/openttd/baseset
|
||||
cd ~/.local/share/openttd/baseset
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake ${{ inputs.extra-cmake-parameters }}
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc)
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
(
|
||||
cd build
|
||||
ctest -j $(nproc) --timeout 120
|
||||
)
|
||||
|
||||
# Re-enable vcpkg.
|
||||
mv vcpkg-disabled.json vcpkg.json
|
||||
|
||||
# Check no tracked files have been modified.
|
||||
git diff --exit-code
|
||||
90
.github/workflows/ci-macos.yml
vendored
Normal file
90
.github/workflows/ci-macos.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: CI (MacOS)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
arch:
|
||||
required: true
|
||||
type: string
|
||||
full_arch:
|
||||
required: true
|
||||
type: string
|
||||
extra-cmake-parameters:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
macos:
|
||||
name: CI
|
||||
|
||||
runs-on: macos-14
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
|
||||
steps:
|
||||
- name: Setup Xcode version
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||
|
||||
- name: Install OpenGFX
|
||||
run: |
|
||||
mkdir -p ~/Documents/OpenTTD/baseset
|
||||
cd ~/Documents/OpenTTD/baseset
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-DCMAKE_OSX_ARCHITECTURES=${{ inputs.full_arch }} \
|
||||
-DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-osx \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||
${{ inputs.extra-cmake-parameters }} \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(sysctl -n hw.logicalcpu) cores"
|
||||
cmake --build . -j $(sysctl -n hw.logicalcpu)
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120
|
||||
83
.github/workflows/ci-mingw.yml
vendored
Normal file
83
.github/workflows/ci-mingw.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
name: CI (MinGW)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
arch:
|
||||
required: true
|
||||
type: string
|
||||
msystem:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
mingw:
|
||||
name: CI
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ inputs.msystem }}
|
||||
release: false
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-${{ inputs.arch }}-cmake
|
||||
mingw-w64-${{ inputs.arch }}-gcc
|
||||
mingw-w64-${{ inputs.arch }}-lzo2
|
||||
mingw-w64-${{ inputs.arch }}-libpng
|
||||
mingw-w64-${{ inputs.arch }}-lld
|
||||
mingw-w64-${{ inputs.arch }}-ninja
|
||||
|
||||
- name: Install OpenGFX
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install GCC problem matcher
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
cmake --build .
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
cd build
|
||||
ctest --timeout 120
|
||||
82
.github/workflows/ci-nightly.yml
vendored
Normal file
82
.github/workflows/ci-nightly.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: CI - Nightly
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: GCC - SDL1.2
|
||||
compiler: gcc
|
||||
cxxcompiler: g++
|
||||
libraries: libsdl1.2-dev
|
||||
|
||||
name: Linux (${{ matrix.name }})
|
||||
|
||||
uses: ./.github/workflows/ci-linux.yml
|
||||
secrets: inherit
|
||||
|
||||
with:
|
||||
compiler: ${{ matrix.compiler }}
|
||||
cxxcompiler: ${{ matrix.cxxcompiler }}
|
||||
libraries: ${{ matrix.libraries }}
|
||||
extra-cmake-parameters:
|
||||
|
||||
macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
full_arch: x86_64
|
||||
|
||||
name: Mac OS (${{ matrix.arch }})
|
||||
|
||||
uses: ./.github/workflows/ci-macos.yml
|
||||
secrets: inherit
|
||||
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
full_arch: ${{ matrix.full_arch }}
|
||||
|
||||
mingw:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- msystem: MINGW64
|
||||
arch: x86_64
|
||||
- msystem: MINGW32
|
||||
arch: i686
|
||||
|
||||
name: MinGW (${{ matrix.arch }})
|
||||
|
||||
uses: ./.github/workflows/ci-mingw.yml
|
||||
secrets: inherit
|
||||
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
check_annotations:
|
||||
name: Check Annotations
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- mingw
|
||||
|
||||
if: always()
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check annotations
|
||||
uses: OpenTTD/actions/annotation-check@v5
|
||||
87
.github/workflows/ci-windows.yml
vendored
Normal file
87
.github/workflows/ci-windows.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
name: CI (Windows)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
arch:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
name: CI
|
||||
|
||||
runs-on: ${{ inputs.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}\vcpkg
|
||||
${{ runner.temp }}\vcpkg\bootstrap-vcpkg.bat -disableMetrics
|
||||
|
||||
- name: Install OpenGFX
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||
|
||||
echo "::group::Download OpenGFX"
|
||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Unpack OpenGFX"
|
||||
unzip opengfx-all.zip
|
||||
echo "::endgroup::"
|
||||
|
||||
rm -f opengfx-all.zip
|
||||
|
||||
- name: Install MSVC problem matcher
|
||||
uses: ammaraskar/msvc-problem-matcher@master
|
||||
|
||||
- name: Configure developer command prompt for ${{ inputs.arch }}
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ inputs.arch }}
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
env:
|
||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-windows-static \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
||||
# EOF
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build"
|
||||
cmake --build .
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
ctest --timeout 120
|
||||
42
.github/workflows/codeql.yml
vendored
42
.github/workflows/codeql.yml
vendored
@@ -26,6 +26,19 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup vcpkg caching
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||
|
||||
- name: Install vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "::group::Update apt"
|
||||
@@ -44,13 +57,28 @@ jobs:
|
||||
libsdl2-dev \
|
||||
zlib1g-dev \
|
||||
# EOF
|
||||
|
||||
echo "::group::Install vcpkg dependencies"
|
||||
|
||||
# Disable vcpkg integration, as we mostly use system libraries.
|
||||
mv vcpkg.json vcpkg-disabled.json
|
||||
|
||||
# We only use breakpad from vcpkg, as its CMake files
|
||||
# are a bit special. So the Ubuntu's variant doesn't work.
|
||||
${{ runner.temp }}/vcpkg/vcpkg install breakpad
|
||||
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Set number of make jobs
|
||||
- name: Prepare build
|
||||
run: |
|
||||
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "::group::CMake"
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
@@ -58,8 +86,14 @@ jobs:
|
||||
languages: cpp
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
- name: Build
|
||||
run: |
|
||||
cd build
|
||||
|
||||
echo "::group::Build"
|
||||
echo "Running on $(nproc) cores"
|
||||
cmake --build . -j $(nproc)
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
2
.ottdrev
2
.ottdrev
@@ -1 +1 @@
|
||||
14.1 20240503 0 b3c704a6306027de4aad575c8e394a2d8a1878f9 1 1 2024
|
||||
13.0 20231203 0 2ebc601d97aa431e5d8aebfe4a7bbfdabf29dc75 1 1 2023
|
||||
|
||||
@@ -5,7 +5,7 @@ if(NOT BINARY_NAME)
|
||||
endif()
|
||||
|
||||
project(${BINARY_NAME}
|
||||
VERSION 14.0
|
||||
VERSION 15.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
@@ -248,15 +248,15 @@ include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/squirrel/include)
|
||||
|
||||
include(MSVCFilters)
|
||||
|
||||
add_library(openttd_lib OBJECT ${GENERATED_SOURCE_FILES})
|
||||
if(ANDROID)
|
||||
add_library(openttd SHARED ${GENERATED_SOURCE_FILES})
|
||||
set(BINARY_NAME application)
|
||||
target_link_libraries(openttd_lib log z)
|
||||
add_library(openttd SHARED)
|
||||
target_link_libraries(openttd log z)
|
||||
else()
|
||||
add_library(openttd_lib OBJECT ${GENERATED_SOURCE_FILES})
|
||||
add_executable(openttd WIN32)
|
||||
add_executable(openttd_test)
|
||||
endif()
|
||||
add_executable(openttd_test)
|
||||
|
||||
set_target_properties(openttd PROPERTIES OUTPUT_NAME "${BINARY_NAME}")
|
||||
# All other files are added via target_sources()
|
||||
@@ -357,15 +357,13 @@ if(NOT OPTION_DEDICATED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(3rdparty/llvm/CheckAtomic)
|
||||
include(CheckAtomic)
|
||||
|
||||
if(ANDROID)
|
||||
target_link_libraries(openttd_lib
|
||||
target_link_libraries(openttd
|
||||
${EXPAT_LIBRARY}
|
||||
)
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
target_compile_options(openttd_lib PRIVATE -flto=thin)
|
||||
target_link_libraries(openttd_lib -flto=thin)
|
||||
target_compile_options(openttd PRIVATE -flto=thin)
|
||||
target_link_libraries(openttd -flto=thin)
|
||||
endif()
|
||||
|
||||
@@ -157,7 +157,7 @@ enum SomeEnumeration {
|
||||
* Use curly braces and put the contained statements on their own lines (e.g., don't put them directly after the **if**).
|
||||
* Opening curly bracket **{** stays on the first line, closing curly bracket **}** gets a line to itself (except for the **}** preceding an **else**, which should be on the same line as the **else**).
|
||||
* When only a single statement is contained, the brackets can be omitted. In this case, put the single statement on the same line as the preceding keyword (**if**, **while**, etc.). Note that this is only allowed for if statements without an **else** clause.
|
||||
* All fall throughs must be documented, using a **FALLTHROUGH** define/macro.
|
||||
* Non-trivial fall throughs must be documented, using a `[[fallthrough]]` attribute.
|
||||
* The NOT_REACHED() macro can be used in default constructs that should never be reached.
|
||||
* Unconditional loops are written with **`for (;;) {`**
|
||||
|
||||
@@ -180,7 +180,7 @@ switch (a) {
|
||||
|
||||
case 1:
|
||||
DoSomething();
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case 2:
|
||||
DoMore();
|
||||
@@ -191,7 +191,7 @@ switch (a) {
|
||||
int r = 2;
|
||||
|
||||
DoEvenMore(a);
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
case 4: {
|
||||
@@ -248,7 +248,7 @@ Templates are a very powerful C++ tool, but they can easily confuse beginners. T
|
||||
* Templates are to be documented in a very clear and verbose manner. Never assume anything in the documentation.
|
||||
* the template keyword and the template layout get a separate line. typenames are either "T" or preceded by a "T", integers get a single capital letter or a descriptive name preceded by "T".
|
||||
```c++
|
||||
template <typename T, typename Tsomething, int N, byte Tnumber_of_something>
|
||||
template <typename T, typename Tsomething, int N, uint8_t Tnumber_of_something>
|
||||
int Func();
|
||||
```
|
||||
|
||||
|
||||
12
COMPILING.md
12
COMPILING.md
@@ -29,7 +29,7 @@ open most older savegames or use the content downloading system.
|
||||
|
||||
## Windows
|
||||
|
||||
You need Microsoft Visual Studio 2022 or more recent.
|
||||
You need Microsoft Visual Studio 2017 or more recent.
|
||||
|
||||
You can download the free Visual Studio Community Edition from Microsoft at
|
||||
https://visualstudio.microsoft.com/vs/community/.
|
||||
@@ -65,7 +65,7 @@ To install both the x64 (64bit) and x86 (32bit) variants (though only one is nec
|
||||
|
||||
You can open the folder (as a CMake project). CMake will be detected, and you can compile from there.
|
||||
If libraries are installed but not found, you need to set VCPKG_TARGET_TRIPLET in CMake parameters.
|
||||
For Visual Studio 2022 you also need to set CMAKE_TOOLCHAIN_FILE.
|
||||
For Visual Studio 2017 you also need to set CMAKE_TOOLCHAIN_FILE.
|
||||
(Typical values are shown in the MSVC project file command line example)
|
||||
|
||||
Alternatively, you can create a MSVC project file via CMake. For this
|
||||
@@ -75,7 +75,7 @@ that comes with vcpkg. After that, you can run something similar to this:
|
||||
```powershell
|
||||
mkdir build
|
||||
cd build
|
||||
cmake.exe .. -G"Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE="<location of vcpkg>\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET="x64-windows-static"
|
||||
cmake.exe .. -G"Visual Studio 16 2019" -DCMAKE_TOOLCHAIN_FILE="<location of vcpkg>\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET="x64-windows-static"
|
||||
```
|
||||
|
||||
Change `<location of vcpkg>` to where you have installed vcpkg. After this
|
||||
@@ -83,7 +83,7 @@ in the build folder are MSVC project files. MSVC can rebuild the project
|
||||
files himself via the `ZERO_CHECK` project.
|
||||
|
||||
## All other platforms
|
||||
Minimum required version of CMake is 3.16.
|
||||
Minimum required version of CMake is 3.9.
|
||||
By default this produces a Debug build with assertations enabled.
|
||||
This is a far slower build than release builds.
|
||||
|
||||
@@ -115,9 +115,9 @@ builds.
|
||||
|
||||
## Supported compilers
|
||||
|
||||
Every compiler that is supported by CMake and supports C++20, should be
|
||||
Every compiler that is supported by CMake and supports C++17, should be
|
||||
able to compile OpenTTD. As the exact list of compilers changes constantly,
|
||||
we refer to the compiler manual to see if it supports C++20, and to CMake
|
||||
we refer to the compiler manual to see if it supports C++17, and to CMake
|
||||
to see if it supports your compiler.
|
||||
|
||||
## Compilation of base sets
|
||||
|
||||
@@ -212,9 +212,6 @@ See `src/3rdparty/monocypher/LICENSE.md` for the complete license text.
|
||||
The OpenTTD Social Integration API in `src/3rdparty/openttd_social_integration_api` is licensed under the MIT license.
|
||||
See `src/3rdparty/openttd_social_integration_api/LICENSE` for the complete license text.
|
||||
|
||||
The atomic datatype support detection in `cmake/3rdparty/llvm/CheckAtomic.cmake` is licensed under the Apache 2.0 license.
|
||||
See `cmake/3rdparty/llvm/LICENSE.txt` for the complete license text.
|
||||
|
||||
## 4.0 Credits
|
||||
|
||||
See [CREDITS.md](./CREDITS.md)
|
||||
|
||||
@@ -15,6 +15,7 @@ set(AI_COMPAT_SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_15.nut
|
||||
)
|
||||
|
||||
foreach(AI_COMPAT_SOURCE_FILE IN LISTS AI_COMPAT_SOURCE_FILES)
|
||||
|
||||
@@ -4,3 +4,5 @@
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
AILog.Info("14 API compatibility in effect.");
|
||||
|
||||
6
bin/ai/compat_15.nut
Normal file
6
bin/ai/compat_15.nut
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -12,6 +12,7 @@ set(GS_COMPAT_SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_15.nut
|
||||
)
|
||||
|
||||
foreach(GS_COMPAT_SOURCE_FILE IN LISTS GS_COMPAT_SOURCE_FILES)
|
||||
|
||||
@@ -4,3 +4,5 @@
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
GSLog.Info("14 API compatibility in effect.");
|
||||
|
||||
6
bin/game/compat_15.nut
Normal file
6
bin/game/compat_15.nut
Normal file
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
136
changelog.txt
136
changelog.txt
@@ -1,134 +1,3 @@
|
||||
14.1 (2024-05-03)
|
||||
------------------------------------------------------------------------
|
||||
Add: Check that towns can build roads before generating map (#12503)
|
||||
Fix #12228: Ships could get lost due to pathfinder not considering reversing in some cases (#12474)
|
||||
Fix #12433: Width of unit number display was too narrow (#12534)
|
||||
Fix #12502: Desync related to vehicle replacement (#12512)
|
||||
Fix #12506: Desync after new oil rig is constructed (#12511)
|
||||
Fix #12584: Crash on some tar files during tar scan (#12586)
|
||||
Fix: [SDL2] Keypad numbers did not function (#12596)
|
||||
Fix: Houses and industry tiles could accept incorrect cargo (#12547)
|
||||
Fix: Map generation stage strings were incorrect (#12549)
|
||||
Fix: [Script] Allow only 255 league tables, as 255 itself is the invalid id sentinel (#12545)
|
||||
Fix: Mark vehicle status bars dirty when a vehicle leaves unbunching depot (#12516)
|
||||
Fix: Do not show train waiting for unbunching as waiting for free path (#12515)
|
||||
Fix: Smooth outliers in unbunching round trip calculations (#12513)
|
||||
|
||||
|
||||
14.0 (2024-04-13)
|
||||
------------------------------------------------------------------------
|
||||
Update: New title game for 14.0
|
||||
Fix #12477: Crash when launching OpenTTD from within a Dropbox folder (#12478)
|
||||
Fix #12233: Mini order list overlaps vehicle group name (#12423)
|
||||
Fix #12114: Viewport coords of crashed aircraft not updated when falling (#12424)
|
||||
Fix #12395: Ensure president name widget is tall enough (#12419)
|
||||
Fix #12415: Incorrect payment for aircraft secondary cargo (#12416)
|
||||
Fix #12387: [NewGRF] Wrong tile offset passed to rail station CB 149 (slope check)
|
||||
Fix #12388: Autoreplacing train heads slowly made the unit number grow (#12389)
|
||||
Fix #12368: Incorrect offset for click position within industry chain window (#12370)
|
||||
Fix: Aircraft can float above the ground when crashed (#12425)
|
||||
Fix: Segfault when using -q without providing a . character (#12418)
|
||||
Fix: Wrong scrolling dropdown list position with RTL (#12412)
|
||||
Fix: [Win32] Force font mapper to only use TrueType fonts (#12406)
|
||||
Fix: "-q" displays NewGRF IDs in the wrong byte-order (#12397)
|
||||
Fix: Do not send chat to clients that have not authorized yet (#12377)
|
||||
Fix: [NewGRF] Label for fruit incorrectly changed to `FRUI` from `FRUT` (#12367)
|
||||
Fix: [Script] ScriptSubsidy::GetExpireDate should return an economy-date (#12372)
|
||||
Revert #11603: [Script] AI/GSTimeMode was not the best solution for economy/calendar support (#12362)
|
||||
|
||||
|
||||
14.0-RC3 (2024-03-23)
|
||||
------------------------------------------------------------------------
|
||||
Fix #12347: Crash attempting to find catchment tiles of a station with no catchment area (#12348)
|
||||
Fix #12319: Some SSE blitters were broken due to ODR violations (#12322)
|
||||
Fix #12302: Allow empty train engines to use an invalid cargo type (#12325)
|
||||
Fix #12305: Crash with large positive sprite x offset in engine preview window (#12313)
|
||||
Fix #12166: Crash when opening tram road stop build window (#12168)
|
||||
Fix #12092: Incorrect x-axis in cargo payment graph window (#12359)
|
||||
Fix: Crash when attempting to join a company while not joined (#12353)
|
||||
Change: Show unbunching action in timetable window (#12351)
|
||||
Change: [Windows] Switch to Microsoft Azure code signing certificate (#12292)
|
||||
|
||||
|
||||
14.0-RC2 (2024-03-16)
|
||||
------------------------------------------------------------------------
|
||||
Update: Bump bundled OpenTTD TTF fonts to version v0.6 (#12276)
|
||||
Update: Developer credits (#12173, #12235)
|
||||
Change: Use (at least) standard toolbar button size for signal selection buttons (#12265)
|
||||
Change: [Script] Match FormatString behaviour more closely (#12205)
|
||||
Fix #12236: Ship pathfinder causes crash when ship is already at destination (#12238)
|
||||
Fix #12225: [Script] Missing AI::ResetConfig support for running AI config (#12226)
|
||||
Fix #12203: When unbunching at a depot, don't overlook implicit orders (#12220)
|
||||
Fix #12196: Always show selected content, even when filtering and disable "select upgrade" button when filtering (#12201)
|
||||
Fix #12195: Reset cursor when no Object is selected (#12207)
|
||||
Fix #12176: Ships are circling in one place (#12181)
|
||||
Fix #12154: Incorrect calendar day lengths with minutes per year setting (#12158)
|
||||
Fix #12148: Do not draw decimals when number of digits is 0 (#12150)
|
||||
Fix #12147: Reset all saved settings to their default before loading a game (#12210)
|
||||
Fix #12145: Incorrect date handling in date cheat in wallclock time-keeping mode (#12146)
|
||||
Fix #12134: Use correct error messages if clearing drive-through road stops fails (#12139)
|
||||
Fix #12133: [Script] Don't crash when emergency saving (#12138)
|
||||
Fix #12127: Truncation ellipses rendered shadows even for black font without shadows (#12132)
|
||||
Fix #12119: Remove red warning text when maximum loan is zero (#12141)
|
||||
Fix #12118: When adding an unbunching order, properly check for unsafe conditions (#12136)
|
||||
Fix #12076: Do not allow 'join' command on dedicated servers (#12208)
|
||||
Fix #12010: Use economy timer for vehicle stats minimum age, not calendar (#12142)
|
||||
Fix: Improved ship movement when no path to destination is found (#12285, #12286)
|
||||
Fix: Initialize _switch_mode_time so crash-logs before first game have a realistic time (#12184)
|
||||
Fix: [Script] Only show debug script window at the end of savegame loading (#12135)
|
||||
Fix: [Script] Broken ScriptText circular reference detection (#12187)
|
||||
Fix: Ordering of command per tick limit and pause mode filtering (#12126)
|
||||
Fix: Only reset unbunching departure data in the correct depot (#12155)
|
||||
Fix: Off by one in TimerGameEconomy::ConvertDateToYMD in wallclock mode (#12143)
|
||||
Fix: Missing savegame conversion for current_order (#12188)
|
||||
Fix: Helptext for timekeeping unit setting erroneously refers to vehicle movement (#12172)
|
||||
Fix: Don't show "insert order" errors in the console (#12245)
|
||||
Fix: Don't defer OnResize() after ReInit() (#12174)
|
||||
Remove: [Script] random_deviation from setting description table (#12221)
|
||||
Revert #11993: New number format system does not and cannot work for CJK languages (#12157)
|
||||
Revert #11606: Don't auto-build past tunnelbridge ends (#12244)
|
||||
|
||||
|
||||
14.0-RC1 (2024-02-18)
|
||||
------------------------------------------------------------------------
|
||||
Feature: Fully user configurable number format and abbreviations (#11993)
|
||||
Add: Show cargo icons on subsidy list window (#12079)
|
||||
Add: [Script] GetAirportNumHelipads (#12085)
|
||||
Change: Show 6 or 2 orientation buttons in NewGRF road stop picker as appropriate (#12090)
|
||||
Change: Show cargo icons on Industry View window (#12071)
|
||||
Change: Improve performance of finding free pool slots (#12055)
|
||||
Change: Draw north-side farm fences/hedges/walls on tile edge, instead of 1/16th in (#12048)
|
||||
Change: When adding orders, Ctrl+Click on a depot to unbunch, instead of service if required (#12023)
|
||||
Change: Store running AI config inside Company (#12003)
|
||||
Change: Show speed before destination in vehicle status bar (#11932)
|
||||
Change: Replace long list of cargo filter buttons with a multi-select dropdown list (#11552)
|
||||
Change: [Script] Use company randomizer when adding random deviation (#12065)
|
||||
Fix #12074: Don't allow "part" command for dedicated servers (#12075)
|
||||
Fix #12052: NewGRFs clearing industry cargo slots could fallback to default instead of empty (#12053)
|
||||
Fix #12050: Add default size, shade and pin control buttons to company livery widget (#12080)
|
||||
Fix #12041: Tarball extraction failing due to incorrect filename (#12044)
|
||||
Fix #12037: Blurry OpenTTD font on Mac OS (#12047)
|
||||
Fix #12029: Don't show Sandbox Options in multiplayer (#12032)
|
||||
Fix #12024: Autoreplace failed news message for trains must go to lead engine (#12025)
|
||||
Fix #12022: Adjust economy date when changing timekeeping units in Scenario Editor (#12042)
|
||||
Fix #12020: Unbunch and service if needed should be mutually exclusive depot order types (#12021)
|
||||
Fix #12019: Correctly highlight depot unbunch action in dropdown (#12021)
|
||||
Fix #12014: Remove water when area clearing ship depot (#12030)
|
||||
Fix #11840: Ship pathfinder always returns a valid trackdir if one is available (#12031)
|
||||
Fix #10983: [AdminPort] Correct order of messages (#11140)
|
||||
Fix #10405: [Script] Test engine and vehicle type validity for ScriptGroup::GetNumEngines (#11887)
|
||||
Fix #10079: Don't render at 1000fps if HW acceleration + vsync is requested but not active (#12067)
|
||||
Fix: Shadows of individual character glyphs could be drawn over other characters (#12115)
|
||||
Fix: Don't invalidate station list on vehicle load/unload (#12112)
|
||||
Fix: NewGRF roadstops were ignored if only in default class (#12089)
|
||||
Fix: Visually also disable vsync when not using HW acceleration (#12066)
|
||||
Fix: Industry tiles and houses could accept incorrect cargo types (#12062)
|
||||
Fix: Redraw orders when a station feature is added/removed (#12061)
|
||||
Fix: For content service, fallback to TCP downloads when HTTP stalls (#12056)
|
||||
Fix: Don't issue autoreplace failed news message for command test mode (#12026)
|
||||
Remove: Setting "no_http_content_downloads" (#12058)
|
||||
|
||||
|
||||
14.0-beta3 (2024-02-06)
|
||||
------------------------------------------------------------------------
|
||||
Add: [Script] ScriptTileList_StationCoverage to get station coverage area (#12015)
|
||||
@@ -7181,8 +7050,3 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
||||
- Fix: Colours in map window for routes
|
||||
- Fix: Road drive side
|
||||
- Fix: 'Fund road construction' not clickable when unavailable
|
||||
|
||||
|
||||
0.1.0 (2004-03-06)
|
||||
------------------------------------------------------------------------
|
||||
Initial release
|
||||
|
||||
279
cmake/3rdparty/llvm/LICENSE.txt
vendored
279
cmake/3rdparty/llvm/LICENSE.txt
vendored
@@ -1,279 +0,0 @@
|
||||
==============================================================================
|
||||
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
|
||||
==============================================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
---- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
==============================================================================
|
||||
Software from third parties included in the LLVM Project:
|
||||
==============================================================================
|
||||
The LLVM Project contains third party software which is under different license
|
||||
terms. All such code will be identified clearly using at least one of two
|
||||
mechanisms:
|
||||
1) It will be in a separate directory tree with its own `LICENSE.txt` or
|
||||
`LICENSE` file at the top containing the specific license and restrictions
|
||||
which apply to that software, or
|
||||
2) It will contain specific license and restriction terms at the top of every
|
||||
file.
|
||||
|
||||
==============================================================================
|
||||
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
|
||||
==============================================================================
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
#
|
||||
# This was originally part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See (https://llvm.org/)LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
# Modifications have been made to suit building OpenTTD.
|
||||
#
|
||||
|
||||
# atomic builtins are required for threading support.
|
||||
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
@@ -56,8 +48,6 @@ else()
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
# check_library_exists requires the C-compiler as the atomic functions are built-in declared.
|
||||
enable_language(C)
|
||||
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||
if(HAVE_LIBATOMIC)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
@@ -79,8 +69,6 @@ else()
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
# check_library_exists requires the C-compiler as the atomic functions are built-in declared.
|
||||
enable_language(C)
|
||||
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||
if(HAVE_CXX_LIBATOMICS64)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
@@ -74,12 +74,6 @@ macro(compile_flags)
|
||||
|
||||
# We use 'ABCD' multichar for SaveLoad chunks identifiers
|
||||
-Wno-multichar
|
||||
|
||||
# Compilers complains about that we break strict-aliasing.
|
||||
# On most places we don't see how to fix it, and it doesn't
|
||||
# break anything. So disable strict-aliasing to make the
|
||||
# compiler all happy.
|
||||
-fno-strict-aliasing
|
||||
)
|
||||
|
||||
# Ninja processes the output so the output from the compiler
|
||||
|
||||
@@ -39,21 +39,17 @@ foreach(MOD_NAME IN LISTS ICU_FIND_COMPONENTS)
|
||||
endif()
|
||||
pkg_check_modules(PC_ICU_${MOD_NAME} QUIET icu-${MOD_NAME})
|
||||
|
||||
if(NOT ANDROID)
|
||||
# Check the libraries returned by pkg-config really exist.
|
||||
unset(PC_LIBRARIES)
|
||||
foreach(LIBRARY IN LISTS PC_ICU_${MOD_NAME}_LIBRARIES)
|
||||
unset(PC_LIBRARY CACHE)
|
||||
find_library(PC_LIBRARY NAMES ${LIBRARY})
|
||||
if(NOT PC_LIBRARY)
|
||||
unset(PC_ICU_${MOD_NAME}_FOUND)
|
||||
endif()
|
||||
list(APPEND PC_LIBRARIES ${PC_LIBRARY})
|
||||
endforeach()
|
||||
unset(PC_LIBRARY CACHE)
|
||||
else()
|
||||
list(APPEND PC_LIBRARIES ${PC_ICU_${MOD_NAME}_LIBRARY})
|
||||
endif(NOT ANDROID)
|
||||
# Check the libraries returned by pkg-config really exist.
|
||||
unset(PC_LIBRARIES)
|
||||
foreach(LIBRARY IN LISTS PC_ICU_${MOD_NAME}_LIBRARIES)
|
||||
unset(PC_LIBRARY CACHE)
|
||||
find_library(PC_LIBRARY NAMES ${LIBRARY})
|
||||
if(NOT PC_LIBRARY)
|
||||
unset(PC_ICU_${MOD_NAME}_FOUND)
|
||||
endif()
|
||||
list(APPEND PC_LIBRARIES ${PC_LIBRARY})
|
||||
endforeach()
|
||||
unset(PC_LIBRARY CACHE)
|
||||
|
||||
if(${PC_ICU_${MOD_NAME}_FOUND})
|
||||
set(ICU_COMPONENT_FOUND TRUE)
|
||||
|
||||
@@ -56,7 +56,7 @@ function(set_options)
|
||||
|
||||
option(OPTION_DEDICATED "Build dedicated server only (no GUI)" OFF)
|
||||
option(OPTION_INSTALL_FHS "Install with Filesystem Hierarchy Standard folders" ${DEFAULT_OPTION_INSTALL_FHS})
|
||||
option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" OFF)
|
||||
option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" ON)
|
||||
option(OPTION_USE_NSIS "Use NSIS to create windows installer; enable only for stable releases" OFF)
|
||||
option(OPTION_TOOLS_ONLY "Build only tools target" OFF)
|
||||
option(OPTION_DOCS_ONLY "Build only docs target" OFF)
|
||||
|
||||
@@ -195,11 +195,10 @@ Last updated: 2014-02-23
|
||||
'src/network/network_func.h'.
|
||||
(DEBUG_FAILED_DUMP_COMMANDS is explained later)
|
||||
- Put the 'commands-out.log' into the root save folder, and rename
|
||||
it to 'commands.log'. Strip everything and including the "newgame"
|
||||
entry from the log.
|
||||
- Run 'openttd -D -d desync=0 -g startsavegame.sav'.
|
||||
This replays the server log. Use "-d desync=3" to also create a
|
||||
new 'commands-out.log' and 'dmp_cmds_*.sav' in your autosave folder.
|
||||
it to 'commands.log'.
|
||||
- Run 'openttd -D -d desync=3 -g startsavegame.sav'.
|
||||
This replays the server log and creates new 'commands-out.log'
|
||||
and 'dmp_cmds_*.sav' in your autosave folder.
|
||||
|
||||
## 3.2) Evaluation of the replay
|
||||
|
||||
@@ -227,7 +226,7 @@ Last updated: 2014-02-23
|
||||
savegames with your own ones from the replay. You can also comment/disable
|
||||
the 'NOT_REACHED' mentioned above, to get another 'dmp_cmds_*.sav' from
|
||||
the replay after the mismatch has already been detected.
|
||||
See Section 3.3 on how to compare savegames.
|
||||
See Section 3.2 on how to compare savegames.
|
||||
If the saves differ you have located the Desync between the last dmp_cmds
|
||||
that match and the first one that does not. The difference of the saves
|
||||
may point you in the direction of what causes it.
|
||||
@@ -253,14 +252,16 @@ Last updated: 2014-02-23
|
||||
are replayed. Their internal state will thus not change in the
|
||||
replay and will differ.
|
||||
|
||||
To compare savegame more semantically, easiest is to first export them
|
||||
to a JSON format with for example:
|
||||
To compare savegame more semantically, there exist some ugly hackish
|
||||
tools at:
|
||||
http://devs.openttd.org/~frosch/texts/zpipe.c
|
||||
http://devs.openttd.org/~frosch/texts/printhunk.c
|
||||
|
||||
https://github.com/TrueBrain/OpenTTD-savegame-reader
|
||||
The first one decompresses OpenTTD savegames. The second one creates
|
||||
a textual representation of an uncompressed savegame, by parsing hunks
|
||||
and arrays and such. With both tools you need to be a bit careful
|
||||
since they work on stdin and stdout, which may not deal well with
|
||||
binary data.
|
||||
|
||||
By running:
|
||||
|
||||
python -m savegame_reader --export-json dmp_cmds_NNN.sav | jq . > NNN.json
|
||||
|
||||
Now you can use any (JSON) diff tool to compare the two savegames in a
|
||||
somewhat human readable way.
|
||||
If you have the textual representation of the savegames, you can
|
||||
compare them with regular diff tools.
|
||||
|
||||
Binary file not shown.
@@ -4,7 +4,7 @@ class Regression extends AIInfo {
|
||||
function GetShortName() { return "REGR"; }
|
||||
function GetDescription() { return "This runs regression-tests on some commands. On the same map the result should always be the same."; }
|
||||
function GetVersion() { return 1; }
|
||||
function GetAPIVersion() { return "14"; }
|
||||
function GetAPIVersion() { return "15"; }
|
||||
function GetDate() { return "2007-03-18"; }
|
||||
function CreateInstance() { return "Regression"; }
|
||||
function UseAsRandomAI() { return false; }
|
||||
|
||||
@@ -4,7 +4,7 @@ class StationList extends AIInfo {
|
||||
function GetShortName() { return "REGS"; }
|
||||
function GetDescription() { return "This runs stationlist-tests on some commands. On the same map the result should always be the same."; }
|
||||
function GetVersion() { return 1; }
|
||||
function GetAPIVersion() { return "14"; }
|
||||
function GetAPIVersion() { return "15"; }
|
||||
function GetDate() { return "2007-03-18"; }
|
||||
function CreateInstance() { return "StationList"; }
|
||||
function UseAsRandomAI() { return false; }
|
||||
|
||||
4
src/3rdparty/md5/md5.h
vendored
4
src/3rdparty/md5/md5.h
vendored
@@ -57,8 +57,8 @@
|
||||
static const size_t MD5_HASH_BYTES = 16;
|
||||
|
||||
/** Container for storing a MD5 hash/checksum/digest. */
|
||||
struct MD5Hash : std::array<byte, MD5_HASH_BYTES> {
|
||||
MD5Hash() : std::array<byte, MD5_HASH_BYTES>{} {}
|
||||
struct MD5Hash : std::array<uint8_t, MD5_HASH_BYTES> {
|
||||
MD5Hash() : std::array<uint8_t, MD5_HASH_BYTES>{} {}
|
||||
|
||||
/**
|
||||
* Exclusively-or the given hash into this hash.
|
||||
|
||||
@@ -650,8 +650,7 @@ public:
|
||||
_fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
|
||||
}
|
||||
else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
|
||||
SQFloat f = _float(constval);
|
||||
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
|
||||
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref, std::bit_cast<SQInt32>(_float(constval)));
|
||||
}
|
||||
else {
|
||||
_fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
|
||||
@@ -697,7 +696,7 @@ public:
|
||||
break;
|
||||
case TK_FLOAT:
|
||||
if(sizeof(SQFloat) == sizeof(SQInt32)) {
|
||||
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
|
||||
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(), std::bit_cast<SQInt32>(_lex._fvalue));
|
||||
}
|
||||
else {
|
||||
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
|
||||
|
||||
19
src/3rdparty/squirrel/squirrel/sqfuncstate.cpp
vendored
19
src/3rdparty/squirrel/squirrel/sqfuncstate.cpp
vendored
@@ -199,7 +199,7 @@ void SQFuncState::Dump(SQFunctionProto *func)
|
||||
}
|
||||
}
|
||||
else if(inst.op==_OP_LOADFLOAT) {
|
||||
printf("[%03d] %15s %d %f %d %d\n",n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
|
||||
printf("[%03d] %15s %d %f %d %d\n",n,g_InstrDesc[inst.op].name,inst._arg0,std::bit_cast<SQFloat>(inst._arg1),inst._arg2,inst._arg3);
|
||||
}
|
||||
else if(inst.op==_OP_ARITH){
|
||||
printf("[%03d] %15s %d %d %d %c\n",n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
|
||||
@@ -242,19 +242,20 @@ SQInteger SQFuncState::GetConstant(const SQObject &cons)
|
||||
|
||||
void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
|
||||
{
|
||||
_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
|
||||
_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
|
||||
_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
|
||||
_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
|
||||
_instructions[pos]._arg0 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg0);
|
||||
_instructions[pos]._arg1 = (SQInt32)std::bit_cast<SQUnsignedInteger>(arg1);
|
||||
_instructions[pos]._arg2 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg2);
|
||||
_instructions[pos]._arg3 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg3);
|
||||
}
|
||||
|
||||
void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
|
||||
{
|
||||
switch(arg){
|
||||
case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
||||
case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
|
||||
case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
||||
case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
||||
case 0: _instructions[pos]._arg0 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||
case 1:
|
||||
case 4: _instructions[pos]._arg1 = (SQInt32)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||
case 2: _instructions[pos]._arg2 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||
case 3: _instructions[pos]._arg3 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
8
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
8
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -51,7 +51,7 @@ bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,con
|
||||
case BW_XOR: res = i1 ^ i2; break;
|
||||
case BW_SHIFTL: res = i1 << i2; break;
|
||||
case BW_SHIFTR: res = i1 >> i2; break;
|
||||
case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
|
||||
case BW_USHIFTR:res = (SQInteger)(std::bit_cast<SQUnsignedInteger>(i1) >> i2); break;
|
||||
default: { Raise_Error("internal vm error bitwise op failed"); return false; }
|
||||
}
|
||||
}
|
||||
@@ -472,10 +472,10 @@ bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjec
|
||||
|
||||
#define arg0 (_i_._arg0)
|
||||
#define arg1 (_i_._arg1)
|
||||
#define sarg1 (*(const_cast<SQInt32 *>(&_i_._arg1)))
|
||||
#define sarg1 (std::bit_cast<SQInt32>(_i_._arg1))
|
||||
#define arg2 (_i_._arg2)
|
||||
#define arg3 (_i_._arg3)
|
||||
#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3))
|
||||
#define sarg3 ((SQInteger)std::bit_cast<char>(_i_._arg3))
|
||||
|
||||
SQRESULT SQVM::Suspend()
|
||||
{
|
||||
@@ -764,7 +764,7 @@ exception_restore:
|
||||
continue;
|
||||
case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
|
||||
case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
|
||||
case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue;
|
||||
case _OP_LOADFLOAT: TARGET = std::bit_cast<SQFloat>(arg1); continue;
|
||||
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
|
||||
case _OP_TAILCALL:
|
||||
temp_reg = STK(arg1);
|
||||
|
||||
@@ -52,6 +52,8 @@ add_files(
|
||||
animated_tile_func.h
|
||||
articulated_vehicles.cpp
|
||||
articulated_vehicles.h
|
||||
autocompletion.cpp
|
||||
autocompletion.h
|
||||
autoreplace.cpp
|
||||
autoreplace_base.h
|
||||
autoreplace_cmd.cpp
|
||||
@@ -138,6 +140,10 @@ add_files(
|
||||
dock_gui.cpp
|
||||
driver.cpp
|
||||
driver.h
|
||||
dropdown.cpp
|
||||
dropdown_common_type.h
|
||||
dropdown_func.h
|
||||
dropdown_type.h
|
||||
economy.cpp
|
||||
economy_base.h
|
||||
economy_cmd.h
|
||||
@@ -393,6 +399,8 @@ add_files(
|
||||
signs_func.h
|
||||
signs_gui.cpp
|
||||
signs_type.h
|
||||
slider.cpp
|
||||
slider_func.h
|
||||
slope_func.h
|
||||
slope_type.h
|
||||
smallmap_gui.cpp
|
||||
@@ -505,6 +513,8 @@ add_files(
|
||||
tunnelbridge_cmd.cpp
|
||||
tunnelbridge_cmd.h
|
||||
tunnelbridge_map.h
|
||||
tutorial_gui.cpp
|
||||
tutorial_gui.h
|
||||
vehicle.cpp
|
||||
vehicle_base.h
|
||||
vehicle_cmd.cpp
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
/* Clients shouldn't start AIs */
|
||||
if (_networking && !_network_server) return;
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
Company *c = Company::Get(company);
|
||||
|
||||
AIConfig *config = c->ai_config.get();
|
||||
@@ -81,7 +81,7 @@
|
||||
assert(_settings_game.difficulty.competitor_speed <= 4);
|
||||
if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company);
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->is_ai) {
|
||||
PerformanceMeasurer framerate((PerformanceElement)(PFE_AI0 + c->index));
|
||||
@@ -109,7 +109,7 @@
|
||||
if (_networking && !_network_server) return;
|
||||
PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + company));
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
Company *c = Company::Get(company);
|
||||
|
||||
delete c->ai_instance;
|
||||
@@ -129,7 +129,7 @@
|
||||
* for the server owner to unpause the script again. */
|
||||
if (_network_dedicated) return;
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
Company::Get(company)->ai_instance->Pause();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
/* static */ void AI::Unpause(CompanyID company)
|
||||
{
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
Company::Get(company)->ai_instance->Unpause();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
/* static */ bool AI::IsPaused(CompanyID company)
|
||||
{
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
bool paused = Company::Get(company)->ai_instance->IsPaused();
|
||||
|
||||
cur_company.Restore();
|
||||
@@ -259,7 +259,7 @@
|
||||
}
|
||||
|
||||
/* Queue the event */
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
Company::Get(_current_company)->ai_instance->InsertEvent(event);
|
||||
cur_company.Restore();
|
||||
|
||||
@@ -293,7 +293,7 @@
|
||||
|
||||
/* When doing emergency saving, an AI can be not fully initialised. */
|
||||
if (c->ai_instance != nullptr) {
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, company);
|
||||
c->ai_instance->Save();
|
||||
cur_company.Restore();
|
||||
return;
|
||||
|
||||
@@ -82,7 +82,7 @@ static constexpr NWidgetPart _nested_ai_config_widgets[] = {
|
||||
};
|
||||
|
||||
/** Window definition for the configure AI window. */
|
||||
static WindowDesc _ai_config_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _ai_config_desc(
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_GAME_OPTIONS, WC_NONE,
|
||||
0,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
static bool CheckAPIVersion(const std::string &api_version)
|
||||
{
|
||||
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14" };
|
||||
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14", "15" };
|
||||
return versions.find(api_version) != versions.end();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,14 +73,14 @@ struct AircraftCache {
|
||||
*/
|
||||
struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
|
||||
uint16_t crashed_counter; ///< Timer for handling crash animations.
|
||||
byte pos; ///< Next desired position of the aircraft.
|
||||
byte previous_pos; ///< Previous desired position of the aircraft.
|
||||
uint8_t pos; ///< Next desired position of the aircraft.
|
||||
uint8_t previous_pos; ///< Previous desired position of the aircraft.
|
||||
StationID targetairport; ///< Airport to go to next.
|
||||
byte state; ///< State of the airport. @see AirportMovementStates
|
||||
uint8_t state; ///< State of the airport. @see AirportMovementStates
|
||||
Direction last_direction;
|
||||
byte number_consecutive_turns; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point.
|
||||
byte turn_counter; ///< Ticks between each turn to prevent > 45 degree turns.
|
||||
byte flags; ///< Aircraft flags. @see AirVehicleFlags
|
||||
uint8_t number_consecutive_turns; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point.
|
||||
uint8_t turn_counter; ///< Ticks between each turn to prevent > 45 degree turns.
|
||||
uint8_t flags; ///< Aircraft flags. @see AirVehicleFlags
|
||||
|
||||
AircraftCache acache;
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ static StationID FindNearestHangar(const Aircraft *v)
|
||||
const Station *next_dest = nullptr;
|
||||
if (max_range != 0) {
|
||||
if (v->current_order.IsType(OT_GOTO_STATION) ||
|
||||
(v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT)) {
|
||||
(v->current_order.IsType(OT_GOTO_DEPOT) && (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) == 0)) {
|
||||
last_dest = Station::GetIfValid(v->last_station_visited);
|
||||
next_dest = Station::GetIfValid(v->current_order.GetDestination());
|
||||
} else {
|
||||
@@ -655,7 +655,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
||||
* ~ acceleration * 77 (km-ish/h / 256)
|
||||
*/
|
||||
uint spd = v->acceleration * 77;
|
||||
byte t;
|
||||
uint8_t t;
|
||||
|
||||
/* Adjust speed limits by plane speed factor to prevent taxiing
|
||||
* and take-off speeds being too low. */
|
||||
@@ -672,7 +672,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
||||
speed_limit = v->vcache.cached_max_speed;
|
||||
}
|
||||
|
||||
v->subspeed = (t = v->subspeed) + (byte)spd;
|
||||
v->subspeed = (t = v->subspeed) + (uint8_t)spd;
|
||||
|
||||
/* Aircraft's current speed is used twice so that very fast planes are
|
||||
* forced to slow down rapidly in the short distance needed. The magic
|
||||
@@ -699,7 +699,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
||||
spd = v->GetOldAdvanceSpeed(spd);
|
||||
|
||||
spd += v->progress;
|
||||
v->progress = (byte)spd;
|
||||
v->progress = (uint8_t)spd;
|
||||
return spd >> 8;
|
||||
}
|
||||
|
||||
@@ -825,7 +825,7 @@ template int GetAircraftFlightLevel(Aircraft *v, bool takeoff);
|
||||
* @param rotation The rotation of the airport.
|
||||
* @return The index of the entry point
|
||||
*/
|
||||
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
||||
static uint8_t AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
||||
{
|
||||
assert(v != nullptr);
|
||||
assert(apc != nullptr);
|
||||
@@ -1182,13 +1182,10 @@ static bool HandleCrashedAircraft(Aircraft *v)
|
||||
if (v->crashed_counter < 500 && st == nullptr && ((v->crashed_counter % 3) == 0) ) {
|
||||
int z = GetSlopePixelZ(Clamp(v->x_pos, 0, Map::MaxX() * TILE_SIZE), Clamp(v->y_pos, 0, Map::MaxY() * TILE_SIZE));
|
||||
v->z_pos -= 1;
|
||||
if (v->z_pos <= z) {
|
||||
if (v->z_pos == z) {
|
||||
v->crashed_counter = 500;
|
||||
v->z_pos = z + 1;
|
||||
} else {
|
||||
v->crashed_counter = 0;
|
||||
v->z_pos++;
|
||||
}
|
||||
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
|
||||
}
|
||||
|
||||
if (v->crashed_counter < 650) {
|
||||
@@ -1288,7 +1285,7 @@ void HandleMissingAircraftOrders(Aircraft *v)
|
||||
*/
|
||||
const Station *st = GetTargetAirportIfValid(v);
|
||||
if (st == nullptr) {
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::None, {});
|
||||
cur_company.Restore();
|
||||
|
||||
@@ -1654,7 +1651,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass
|
||||
|
||||
/* Send the helicopter to a hangar if needed for replacement */
|
||||
if (v->NeedsAutomaticServicing()) {
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service | DepotCommand::LocateHangar, {});
|
||||
cur_company.Restore();
|
||||
}
|
||||
@@ -1669,7 +1666,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc)
|
||||
/* {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
|
||||
* if it is an airplane, look for LANDING, for helicopter HELILANDING
|
||||
* it is possible to choose from multiple landing runways, so loop until a free one is found */
|
||||
byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
|
||||
uint8_t landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
|
||||
const AirportFTA *current = apc->layout[v->pos].next;
|
||||
while (current != nullptr) {
|
||||
if (current->heading == landingtype) {
|
||||
@@ -1705,7 +1702,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *)
|
||||
|
||||
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
|
||||
if (v->NeedsAutomaticServicing()) {
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service, {});
|
||||
cur_company.Restore();
|
||||
}
|
||||
@@ -1816,8 +1813,8 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
||||
const AirportFTA *current = &apc->layout[v->pos];
|
||||
/* we have arrived in an important state (eg terminal, hangar, etc.) */
|
||||
if (current->heading == v->state) {
|
||||
byte prev_pos = v->pos; // location could be changed in state, so save it before-hand
|
||||
byte prev_state = v->state;
|
||||
uint8_t prev_pos = v->pos; // location could be changed in state, so save it before-hand
|
||||
uint8_t prev_state = v->state;
|
||||
_aircraft_state_handlers[v->state](v, apc);
|
||||
if (v->state != FLYING) v->previous_pos = prev_pos;
|
||||
if (v->state != prev_state || v->pos != prev_pos) UpdateAircraftCache(v);
|
||||
@@ -1953,7 +1950,7 @@ static const MovementTerminalMapping _airport_terminal_mapping[] = {
|
||||
* @param last_terminal Terminal number to stop examining.
|
||||
* @return A terminal or helipad has been found, and has been assigned to the aircraft.
|
||||
*/
|
||||
static bool FreeTerminal(Aircraft *v, byte i, byte last_terminal)
|
||||
static bool FreeTerminal(Aircraft *v, uint8_t i, uint8_t last_terminal)
|
||||
{
|
||||
assert(last_terminal <= lengthof(_airport_terminal_mapping));
|
||||
Station *st = Station::Get(v->targetairport);
|
||||
|
||||
@@ -110,12 +110,12 @@ AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Directi
|
||||
|
||||
AirportFTAClass::AirportFTAClass(
|
||||
const AirportMovingData *moving_data_,
|
||||
const byte *terminals_,
|
||||
const byte num_helipads_,
|
||||
const byte *entry_points_,
|
||||
const uint8_t *terminals_,
|
||||
const uint8_t num_helipads_,
|
||||
const uint8_t *entry_points_,
|
||||
Flags flags_,
|
||||
const AirportFTAbuildup *apFA,
|
||||
byte delta_z_
|
||||
uint8_t delta_z_
|
||||
) :
|
||||
moving_data(moving_data_),
|
||||
terminals(terminals_),
|
||||
@@ -204,7 +204,7 @@ static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildu
|
||||
* @param airport_type %Airport type to query FTA from. @see AirportTypes
|
||||
* @return Finite state machine of the airport.
|
||||
*/
|
||||
const AirportFTAClass *GetAirport(const byte airport_type)
|
||||
const AirportFTAClass *GetAirport(const uint8_t airport_type)
|
||||
{
|
||||
if (airport_type == AT_DUMMY) return &_airportfta_dummy;
|
||||
return AirportSpec::Get(airport_type)->fsm;
|
||||
@@ -215,7 +215,7 @@ const AirportFTAClass *GetAirport(const byte airport_type)
|
||||
* @param hangar_tile The tile on which the vehicle is build
|
||||
* @return The position (index in airport node array) where the aircraft ends up
|
||||
*/
|
||||
byte GetVehiclePosOnBuild(TileIndex hangar_tile)
|
||||
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile)
|
||||
{
|
||||
const Station *st = Station::GetByTile(hangar_tile);
|
||||
const AirportFTAClass *apc = st->airport.GetFTA();
|
||||
|
||||
@@ -152,12 +152,12 @@ public:
|
||||
|
||||
AirportFTAClass(
|
||||
const AirportMovingData *moving_data,
|
||||
const byte *terminals,
|
||||
const byte num_helipads,
|
||||
const byte *entry_points,
|
||||
const uint8_t *terminals,
|
||||
const uint8_t num_helipads,
|
||||
const uint8_t *entry_points,
|
||||
Flags flags,
|
||||
const AirportFTAbuildup *apFA,
|
||||
byte delta_z
|
||||
uint8_t delta_z
|
||||
);
|
||||
|
||||
~AirportFTAClass();
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
* @param position Element number to get movement data about.
|
||||
* @return Pointer to the movement data.
|
||||
*/
|
||||
const AirportMovingData *MovingData(byte position) const
|
||||
const AirportMovingData *MovingData(uint8_t position) const
|
||||
{
|
||||
assert(position < nofelements);
|
||||
return &moving_data[position];
|
||||
@@ -175,12 +175,12 @@ public:
|
||||
|
||||
const AirportMovingData *moving_data; ///< Movement data.
|
||||
struct AirportFTA *layout; ///< state machine for airport
|
||||
const byte *terminals; ///< %Array with the number of terminal groups, followed by the number of terminals in each group.
|
||||
const byte num_helipads; ///< Number of helipads on this airport. When 0 helicopters will go to normal terminals.
|
||||
const uint8_t *terminals; ///< %Array with the number of terminal groups, followed by the number of terminals in each group.
|
||||
const uint8_t num_helipads; ///< Number of helipads on this airport. When 0 helicopters will go to normal terminals.
|
||||
Flags flags; ///< Flags for this airport type.
|
||||
byte nofelements; ///< number of positions the airport consists of
|
||||
const byte *entry_points; ///< when an airplane arrives at this airport, enter it at position entry_point, index depends on direction
|
||||
byte delta_z; ///< Z adjustment for helicopter pads
|
||||
uint8_t nofelements; ///< number of positions the airport consists of
|
||||
const uint8_t *entry_points; ///< when an airplane arrives at this airport, enter it at position entry_point, index depends on direction
|
||||
uint8_t delta_z; ///< Z adjustment for helicopter pads
|
||||
};
|
||||
|
||||
DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags)
|
||||
@@ -190,12 +190,12 @@ DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags)
|
||||
struct AirportFTA {
|
||||
AirportFTA *next; ///< possible extra movement choices from this position
|
||||
uint64_t block; ///< 64 bit blocks (st->airport.flags), should be enough for the most complex airports
|
||||
byte position; ///< the position that an airplane is at
|
||||
byte next_position; ///< next position from this position
|
||||
byte heading; ///< heading (current orders), guiding an airplane to its target on an airport
|
||||
uint8_t position; ///< the position that an airplane is at
|
||||
uint8_t next_position; ///< next position from this position
|
||||
uint8_t heading; ///< heading (current orders), guiding an airplane to its target on an airport
|
||||
};
|
||||
|
||||
const AirportFTAClass *GetAirport(const byte airport_type);
|
||||
byte GetVehiclePosOnBuild(TileIndex hangar_tile);
|
||||
const AirportFTAClass *GetAirport(const uint8_t airport_type);
|
||||
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile);
|
||||
|
||||
#endif /* AIRPORT_H */
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#include "station_type.h"
|
||||
#include "newgrf_airport.h"
|
||||
#include "newgrf_callbacks.h"
|
||||
#include "widgets/dropdown_type.h"
|
||||
#include "dropdown_type.h"
|
||||
#include "dropdown_func.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "hotkeys.h"
|
||||
#include "vehicle_func.h"
|
||||
@@ -42,11 +43,11 @@
|
||||
|
||||
static AirportClassID _selected_airport_class; ///< the currently visible airport class
|
||||
static int _selected_airport_index; ///< the index of the selected airport in the current class or -1
|
||||
static byte _selected_airport_layout; ///< selected airport layout number.
|
||||
static uint8_t _selected_airport_layout; ///< selected airport layout number.
|
||||
|
||||
static void ShowBuildAirportPicker(Window *parent);
|
||||
|
||||
SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout);
|
||||
SpriteID GetCustomAirportSprite(const AirportSpec *as, uint8_t layout);
|
||||
|
||||
void CcBuildAirport(Commands, const CommandCost &result, TileIndex tile)
|
||||
{
|
||||
@@ -64,8 +65,8 @@ static void PlaceAirport(TileIndex tile)
|
||||
{
|
||||
if (_selected_airport_index == -1) return;
|
||||
|
||||
byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||
byte layout = _selected_airport_layout;
|
||||
uint8_t airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||
uint8_t layout = _selected_airport_layout;
|
||||
bool adjacent = _ctrl_pressed;
|
||||
|
||||
auto proc = [=](bool test, StationID to_join) -> bool {
|
||||
@@ -223,7 +224,7 @@ static constexpr NWidgetPart _nested_air_toolbar_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _air_toolbar_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _air_toolbar_desc(
|
||||
WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0,
|
||||
WC_BUILD_TOOLBAR, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
@@ -257,7 +258,7 @@ class BuildAirportWindow : public PickerWindowBase {
|
||||
DropDownList list;
|
||||
|
||||
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(AirportClass::Get((AirportClassID)i)->name, i, false));
|
||||
list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -364,7 +365,7 @@ public:
|
||||
for (int i = 0; i < NUM_AIRPORTS; i++) {
|
||||
const AirportSpec *as = AirportSpec::Get(i);
|
||||
if (!as->enabled) continue;
|
||||
for (byte layout = 0; layout < as->num_table; layout++) {
|
||||
for (uint8_t layout = 0; layout < as->num_table; layout++) {
|
||||
SpriteID sprite = GetCustomAirportSprite(as, layout);
|
||||
if (sprite != 0) {
|
||||
Dimension d = GetSpriteSize(sprite);
|
||||
@@ -380,7 +381,7 @@ public:
|
||||
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
|
||||
const AirportSpec *as = AirportSpec::Get(i);
|
||||
if (!as->enabled) continue;
|
||||
for (byte layout = 0; layout < as->num_table; layout++) {
|
||||
for (uint8_t layout = 0; layout < as->num_table; layout++) {
|
||||
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
|
||||
if (string == STR_UNDEFINED) continue;
|
||||
|
||||
@@ -512,8 +513,8 @@ public:
|
||||
break;
|
||||
|
||||
case WID_AP_AIRPORT_LIST: {
|
||||
int num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
|
||||
if (num_clicked == INT_MAX) break;
|
||||
int32_t num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
|
||||
if (num_clicked == INT32_MAX) break;
|
||||
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
|
||||
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
|
||||
break;
|
||||
@@ -635,7 +636,7 @@ static constexpr NWidgetPart _nested_build_airport_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _build_airport_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _build_airport_desc(
|
||||
WDP_AUTO, nullptr, 0, 0,
|
||||
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
|
||||
WDF_CONSTRUCTION,
|
||||
|
||||
66
src/autocompletion.cpp
Normal file
66
src/autocompletion.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file autocompletion.cpp Generic auto-completion engine. */
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "autocompletion.h"
|
||||
|
||||
#include "console_internal.h"
|
||||
#include "town.h"
|
||||
#include "network/network_base.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
bool AutoCompletion::AutoComplete()
|
||||
{
|
||||
// We are pressing TAB for the first time after reset.
|
||||
if (this->suggestions.empty()) {
|
||||
this->InitSuggestions(this->textbuf->buf);
|
||||
if (this->suggestions.empty()) {
|
||||
return false;
|
||||
}
|
||||
this->ApplySuggestion(prefix, suggestions[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We are pressing TAB again on the same text.
|
||||
if (this->current_suggestion_index + 1 < this->suggestions.size()) {
|
||||
this->ApplySuggestion(prefix, this->suggestions[++this->current_suggestion_index]);
|
||||
} else {
|
||||
// We are out of options, restore original text.
|
||||
this->textbuf->Assign(initial_buf);
|
||||
this->Reset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AutoCompletion::Reset()
|
||||
{
|
||||
this->prefix = "";
|
||||
this->query = "";
|
||||
this->initial_buf.clear();
|
||||
this->suggestions.clear();
|
||||
this->current_suggestion_index = 0;
|
||||
}
|
||||
|
||||
void AutoCompletion::InitSuggestions(std::string_view text)
|
||||
{
|
||||
this->initial_buf = text;
|
||||
size_t space_pos = this->initial_buf.find_last_of(' ');
|
||||
this->query = this->initial_buf;
|
||||
if (space_pos == std::string::npos) {
|
||||
this->prefix = "";
|
||||
} else {
|
||||
this->prefix = this->query.substr(0, space_pos + 1);
|
||||
this->query.remove_prefix(space_pos + 1);
|
||||
}
|
||||
|
||||
this->suggestions = this->GetSuggestions(prefix, query);
|
||||
this->current_suggestion_index = 0;
|
||||
}
|
||||
46
src/autocompletion.h
Normal file
46
src/autocompletion.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file autocompletion.h Generic auto-completion engine. */
|
||||
|
||||
#ifndef AUTOCOMPLETION_H
|
||||
#define AUTOCOMPLETION_H
|
||||
|
||||
#include "textbuf_type.h"
|
||||
|
||||
class AutoCompletion {
|
||||
protected:
|
||||
Textbuf *textbuf;
|
||||
|
||||
private:
|
||||
std::string initial_buf; ///< Value of text buffer when we started current suggestion session.
|
||||
|
||||
std::string_view prefix; ///< Prefix of the text before the last space.
|
||||
std::string_view query; ///< Last token of the text. This is used to based the suggestions on.
|
||||
|
||||
std::vector<std::string> suggestions;
|
||||
size_t current_suggestion_index;
|
||||
|
||||
public:
|
||||
AutoCompletion(Textbuf *textbuf) : textbuf(textbuf)
|
||||
{
|
||||
this->Reset();
|
||||
}
|
||||
virtual ~AutoCompletion() = default;
|
||||
|
||||
// Returns true the textbuf was updated.
|
||||
bool AutoComplete();
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
void InitSuggestions(std::string_view text);
|
||||
|
||||
virtual std::vector<std::string> GetSuggestions(std::string_view prefix, std::string_view query) = 0;
|
||||
virtual void ApplySuggestion(std::string_view prefix, std::string_view suggestion) = 0;
|
||||
};
|
||||
|
||||
#endif /* AUTOCOMPLETION_H */
|
||||
@@ -362,7 +362,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
|
||||
|
||||
/* Refit the vehicle if needed */
|
||||
if (refit_cargo != CARGO_NO_REFIT) {
|
||||
byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
|
||||
uint8_t subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
|
||||
|
||||
cost.AddCost(std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0)));
|
||||
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "rail_gui.h"
|
||||
#include "road_gui.h"
|
||||
#include "widgets/dropdown_func.h"
|
||||
#include "dropdown_type.h"
|
||||
#include "dropdown_func.h"
|
||||
#include "autoreplace_cmd.h"
|
||||
#include "group_cmd.h"
|
||||
#include "settings_cmd.h"
|
||||
@@ -34,7 +35,7 @@
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16_t min, uint16_t max, EngineID selected_id, bool show_count, GroupID selected_group);
|
||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, const Scrollbar &sb, EngineID selected_id, bool show_count, GroupID selected_group);
|
||||
|
||||
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
|
||||
{
|
||||
@@ -86,7 +87,7 @@ class ReplaceVehicleWindow : public Window {
|
||||
bool reset_sel_engine; ///< Also reset #sel_engine while updating left and/or right and no valid engine selected.
|
||||
GroupID sel_group; ///< Group selected to replace.
|
||||
int details_height; ///< Minimal needed height of the details panels, in text lines (found so far).
|
||||
byte sort_criteria; ///< Criteria of sorting vehicles.
|
||||
uint8_t sort_criteria; ///< Criteria of sorting vehicles.
|
||||
bool descending_sort_order; ///< Order of sorting vehicles.
|
||||
bool show_hidden_engines; ///< Whether to show the hidden engines.
|
||||
RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all.
|
||||
@@ -144,7 +145,7 @@ class ReplaceVehicleWindow : public Window {
|
||||
std::vector<EngineID> variants;
|
||||
EngineID selected_engine = INVALID_ENGINE;
|
||||
VehicleType type = (VehicleType)this->window_number;
|
||||
byte side = draw_left ? 0 : 1;
|
||||
uint8_t side = draw_left ? 0 : 1;
|
||||
|
||||
GUIEngineList list;
|
||||
|
||||
@@ -490,11 +491,9 @@ public:
|
||||
case WID_RV_LEFT_MATRIX:
|
||||
case WID_RV_RIGHT_MATRIX: {
|
||||
int side = (widget == WID_RV_LEFT_MATRIX) ? 0 : 1;
|
||||
EngineID start = static_cast<EngineID>(this->vscroll[side]->GetPosition()); // what is the offset for the start (scrolling)
|
||||
EngineID end = static_cast<EngineID>(std::min<size_t>(this->vscroll[side]->GetCapacity() + start, this->engines[side].size()));
|
||||
|
||||
/* Do the actual drawing */
|
||||
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
|
||||
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], *this->vscroll[side], this->sel_engine[side], side == 0, this->sel_group);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -568,8 +567,8 @@ public:
|
||||
|
||||
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
||||
DropDownList list;
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ENGINES, 1, false));
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_WAGONS, 0, false));
|
||||
list.push_back(MakeDropDownListStringItem(STR_REPLACE_ENGINES, 1));
|
||||
list.push_back(MakeDropDownListStringItem(STR_REPLACE_WAGONS, 0));
|
||||
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
@@ -612,7 +611,7 @@ public:
|
||||
|
||||
case WID_RV_LEFT_MATRIX:
|
||||
case WID_RV_RIGHT_MATRIX: {
|
||||
byte click_side;
|
||||
uint8_t click_side;
|
||||
if (widget == WID_RV_LEFT_MATRIX) {
|
||||
click_side = 0;
|
||||
} else {
|
||||
@@ -788,7 +787,7 @@ static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _replace_rail_vehicle_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _replace_rail_vehicle_desc(
|
||||
WDP_AUTO, "replace_vehicle_train", 500, 140,
|
||||
WC_REPLACE_VEHICLE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
@@ -846,7 +845,7 @@ static constexpr NWidgetPart _nested_replace_road_vehicle_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _replace_road_vehicle_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _replace_road_vehicle_desc(
|
||||
WDP_AUTO, "replace_vehicle_road", 500, 140,
|
||||
WC_REPLACE_VEHICLE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
@@ -898,7 +897,7 @@ static constexpr NWidgetPart _nested_replace_vehicle_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _replace_vehicle_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _replace_vehicle_desc(
|
||||
WDP_AUTO, "replace_vehicle", 456, 118,
|
||||
WC_REPLACE_VEHICLE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
|
||||
@@ -314,7 +314,7 @@ static const uint NUM_SONGS_PLAYLIST = 32;
|
||||
|
||||
/* Functions to read DOS music CAT files, similar to but not quite the same as sound effect CAT files */
|
||||
char *GetMusicCatEntryName(const std::string &filename, size_t entrynum);
|
||||
byte *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
|
||||
uint8_t *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
|
||||
|
||||
enum MusicTrackType {
|
||||
MTT_STANDARDMIDI, ///< Standard MIDI file
|
||||
@@ -324,7 +324,7 @@ enum MusicTrackType {
|
||||
/** Metadata about a music track. */
|
||||
struct MusicSongInfo {
|
||||
std::string songname; ///< name of song displayed in UI
|
||||
byte tracknr; ///< track number of song displayed in UI
|
||||
uint8_t tracknr; ///< track number of song displayed in UI
|
||||
std::string filename; ///< file on disk containing song (when used in MusicSet class)
|
||||
MusicTrackType filetype; ///< decoder required for song file
|
||||
int cat_index; ///< entry index in CAT file, for filetype==MTT_MPSMIDI
|
||||
@@ -338,7 +338,7 @@ struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
|
||||
/** Data about individual songs in set. */
|
||||
MusicSongInfo songinfo[NUM_SONGS_AVAILABLE];
|
||||
/** Number of valid songs in set. */
|
||||
byte num_available;
|
||||
uint8_t num_available;
|
||||
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
||||
};
|
||||
|
||||
@@ -19,16 +19,11 @@
|
||||
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
|
||||
extern StationPool _station_pool;
|
||||
|
||||
struct StationSpecList {
|
||||
const StationSpec *spec;
|
||||
uint32_t grfid; ///< GRF ID of this custom station
|
||||
uint16_t localidx; ///< Station ID within GRF of station
|
||||
};
|
||||
|
||||
struct RoadStopSpecList {
|
||||
const RoadStopSpec *spec;
|
||||
uint32_t grfid; ///< GRF ID of this custom road stop
|
||||
uint16_t localidx; ///< Station ID within GRF of road stop
|
||||
template <typename T>
|
||||
struct SpecMapping {
|
||||
const T *spec; ///< Custom spec.
|
||||
uint32_t grfid; ///< GRF ID of this custom spec.
|
||||
uint16_t localidx; ///< Local ID within GRF of this custom spec.
|
||||
};
|
||||
|
||||
struct RoadStopTileData {
|
||||
@@ -64,7 +59,7 @@ struct StationRect : public Rect {
|
||||
struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
TileIndex xy; ///< Base tile of the station
|
||||
TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign
|
||||
byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
|
||||
uint8_t delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
|
||||
|
||||
std::string name; ///< Custom name
|
||||
StringID string_id; ///< Default name (town area) of station
|
||||
@@ -74,13 +69,13 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
Owner owner; ///< The owner of this station
|
||||
StationFacility facilities; ///< The facilities that this station has
|
||||
|
||||
std::vector<StationSpecList> speclist; ///< List of rail station specs of this station.
|
||||
std::vector<RoadStopSpecList> roadstop_speclist; ///< List of road stop specs of this station
|
||||
std::vector<SpecMapping<StationSpec>> speclist; ///< List of rail station specs of this station.
|
||||
std::vector<SpecMapping<RoadStopSpec>> roadstop_speclist; ///< List of road stop specs of this station
|
||||
|
||||
TimerGameCalendar::Date build_date; ///< Date of construction
|
||||
|
||||
uint16_t random_bits; ///< Random bits assigned to this station
|
||||
byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station
|
||||
uint8_t waiting_triggers; ///< Waiting triggers (NewGRF) for this station
|
||||
uint8_t cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen.
|
||||
uint8_t cached_roadstop_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing should happen.
|
||||
CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask
|
||||
@@ -118,7 +113,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
* @param available will return false if ever the variable asked for does not exist
|
||||
* @return the value stored in the corresponding variable
|
||||
*/
|
||||
virtual uint32_t GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const = 0;
|
||||
virtual uint32_t GetNewGRFVariable(const struct ResolverObject &object, uint8_t variable, uint8_t parameter, bool *available) const = 0;
|
||||
|
||||
/**
|
||||
* Update the coordinated of the sign (as shown in the viewport).
|
||||
@@ -184,7 +179,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
return (this->facilities & ~FACIL_WAYPOINT) != 0;
|
||||
}
|
||||
|
||||
inline byte GetRoadStopRandomBits(TileIndex tile) const
|
||||
inline uint8_t GetRoadStopRandomBits(TileIndex tile) const
|
||||
{
|
||||
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||
if (tile_data.tile == tile) return tile_data.random_bits;
|
||||
@@ -192,7 +187,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline byte GetRoadStopAnimationFrame(TileIndex tile) const
|
||||
inline uint8_t GetRoadStopAnimationFrame(TileIndex tile) const
|
||||
{
|
||||
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||
if (tile_data.tile == tile) return tile_data.animation_frame;
|
||||
@@ -201,11 +196,11 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
}
|
||||
|
||||
private:
|
||||
void SetRoadStopTileData(TileIndex tile, byte data, bool animation);
|
||||
void SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation);
|
||||
|
||||
public:
|
||||
inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
|
||||
inline void SetRoadStopAnimationFrame(TileIndex tile, byte frame) { this->SetRoadStopTileData(tile, frame, true); }
|
||||
inline void SetRoadStopRandomBits(TileIndex tile, uint8_t random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
|
||||
inline void SetRoadStopAnimationFrame(TileIndex tile, uint8_t frame) { this->SetRoadStopTileData(tile, frame, true); }
|
||||
void RemoveRoadStopTileData(TileIndex tile);
|
||||
|
||||
static void PostDestructor(size_t index);
|
||||
@@ -310,4 +305,14 @@ struct SpecializedStation : public BaseStation {
|
||||
static Pool::IterateWrapper<T> Iterate(size_t from = 0) { return Pool::IterateWrapper<T>(from); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Get spec mapping list for each supported custom spec type.
|
||||
* @tparam T Spec type.
|
||||
* @param bst Station of custom spec list.
|
||||
* @return Speclist of custom spec type.
|
||||
*/
|
||||
template <class T> std::vector<SpecMapping<T>> &GetStationSpecList(BaseStation *bst);
|
||||
template <> inline std::vector<SpecMapping<StationSpec>> &GetStationSpecList<StationSpec>(BaseStation *bst) { return bst->speclist; }
|
||||
template <> inline std::vector<SpecMapping<RoadStopSpec>> &GetStationSpecList<RoadStopSpec>(BaseStation *bst) { return bst->roadstop_speclist; }
|
||||
|
||||
#endif /* BASE_STATION_BASE_H */
|
||||
|
||||
@@ -34,23 +34,23 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
|
||||
|
||||
for (uint i = bp->skip_top; i != 0; i--) {
|
||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
}
|
||||
|
||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
||||
uint16_t *anim = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
|
||||
|
||||
const byte *remap = bp->remap; // store so we don't have to access it via bp every time
|
||||
const uint8_t *remap = bp->remap; // store so we don't have to access it via bp every time
|
||||
|
||||
for (int y = 0; y < bp->height; y++) {
|
||||
Colour *dst_ln = dst + bp->pitch;
|
||||
uint16_t *anim_ln = anim + this->anim_buf_pitch;
|
||||
|
||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_px++;
|
||||
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
src_n += 2;
|
||||
|
||||
Colour *dst_end = dst + bp->skip_left;
|
||||
|
||||
@@ -33,7 +33,7 @@ template <BlitterMode mode, Blitter_32bppSSE2::ReadMode read_mode, Blitter_32bpp
|
||||
GNU_TARGET("sse4.1")
|
||||
inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom)
|
||||
{
|
||||
const byte * const remap = bp->remap;
|
||||
const uint8_t * const remap = bp->remap;
|
||||
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
|
||||
uint16_t *anim_line = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
|
||||
int effective_width = bp->width;
|
||||
@@ -42,7 +42,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom
|
||||
const Blitter_32bppSSE_Base::SpriteData * const sd = (const Blitter_32bppSSE_Base::SpriteData *) bp->sprite;
|
||||
const SpriteInfo * const si = &sd->infos[zoom];
|
||||
const MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
|
||||
const Colour *src_rgba_line = (const Colour *) ((const byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||
|
||||
if (read_mode != RM_WITH_MARGIN) {
|
||||
src_rgba_line += bp->skip_left;
|
||||
@@ -104,20 +104,20 @@ inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom
|
||||
|
||||
if (animated) {
|
||||
/* Remap colours. */
|
||||
const byte m0 = mvX2;
|
||||
const uint8_t m0 = mvX2;
|
||||
if (m0 >= PALETTE_ANIM_START) {
|
||||
const Colour c0 = (this->LookupColourInPalette(m0).data & 0x00FFFFFF) | (src[0].data & 0xFF000000);
|
||||
InsertFirstUint32(AdjustBrightneSSE(c0, (byte) (mvX2 >> 8)).data, srcABCD);
|
||||
InsertFirstUint32(AdjustBrightneSSE(c0, (uint8_t) (mvX2 >> 8)).data, srcABCD);
|
||||
}
|
||||
const byte m1 = mvX2 >> 16;
|
||||
const uint8_t m1 = mvX2 >> 16;
|
||||
if (m1 >= PALETTE_ANIM_START) {
|
||||
const Colour c1 = (this->LookupColourInPalette(m1).data & 0x00FFFFFF) | (src[1].data & 0xFF000000);
|
||||
InsertSecondUint32(AdjustBrightneSSE(c1, (byte) (mvX2 >> 24)).data, srcABCD);
|
||||
InsertSecondUint32(AdjustBrightneSSE(c1, (uint8_t) (mvX2 >> 24)).data, srcABCD);
|
||||
}
|
||||
|
||||
/* Update anim buffer. */
|
||||
const byte a0 = src[0].a;
|
||||
const byte a1 = src[1].a;
|
||||
const uint8_t a0 = src[0].a;
|
||||
const uint8_t a1 = src[1].a;
|
||||
uint32_t anim01 = 0;
|
||||
if (a0 == 255) {
|
||||
if (a1 == 255) {
|
||||
@@ -185,9 +185,9 @@ bmno_full_transparency:
|
||||
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
|
||||
|
||||
/* Remap colours. */
|
||||
const uint m0 = (byte) mvX2;
|
||||
const uint m0 = (uint8_t) mvX2;
|
||||
const uint r0 = remap[m0];
|
||||
const uint m1 = (byte) (mvX2 >> 16);
|
||||
const uint m1 = (uint8_t) (mvX2 >> 16);
|
||||
const uint r1 = remap[m1];
|
||||
if (mvX2 & 0x00FF00FF) {
|
||||
#define CMOV_REMAP(m_colour, m_colour_init, m_src, m_m) \
|
||||
@@ -195,7 +195,7 @@ bmno_full_transparency:
|
||||
Colour m_colour = m_colour_init; \
|
||||
{ \
|
||||
const Colour srcm = (Colour) (m_src); \
|
||||
const uint m = (byte) (m_m); \
|
||||
const uint m = (uint8_t) (m_m); \
|
||||
const uint r = remap[m]; \
|
||||
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
||||
m_colour = r == 0 ? m_colour : cmap; \
|
||||
@@ -225,8 +225,8 @@ bmno_full_transparency:
|
||||
|
||||
/* Update anim buffer. */
|
||||
if (animated) {
|
||||
const byte a0 = src[0].a;
|
||||
const byte a1 = src[1].a;
|
||||
const uint8_t a0 = src[0].a;
|
||||
const uint8_t a1 = src[1].a;
|
||||
uint32_t anim01 = mvX2 & 0xFF00FF00;
|
||||
if (a0 == 255) {
|
||||
anim01 |= r0;
|
||||
@@ -368,7 +368,7 @@ bmcr_alpha_blend_single:
|
||||
|
||||
next_line:
|
||||
if (mode != BM_TRANSPARENT && mode != BM_TRANSPARENT_REMAP) src_mv_line += si->sprite_width;
|
||||
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
|
||||
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
|
||||
dst_line += bp->pitch;
|
||||
anim_line += this->anim_buf_pitch;
|
||||
}
|
||||
|
||||
@@ -40,26 +40,26 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
|
||||
|
||||
/* skip upper lines in src_px and src_n */
|
||||
for (uint i = bp->skip_top; i != 0; i--) {
|
||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
}
|
||||
|
||||
/* skip lines in dst */
|
||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
||||
|
||||
/* store so we don't have to access it via bp every time (compiler assumes pointer aliasing) */
|
||||
const byte *remap = bp->remap;
|
||||
const uint8_t *remap = bp->remap;
|
||||
|
||||
for (int y = 0; y < bp->height; y++) {
|
||||
/* next dst line begins here */
|
||||
Colour *dst_ln = dst + bp->pitch;
|
||||
|
||||
/* next src line begins here */
|
||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_px++;
|
||||
|
||||
/* next src_n line begins here */
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
src_n += 2;
|
||||
|
||||
/* we will end this line when we reach this point */
|
||||
@@ -405,8 +405,8 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
||||
dst_n_ln = (uint32_t *)dst_n;
|
||||
}
|
||||
|
||||
lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary
|
||||
lengths[z][1] = (byte *)dst_n_ln - (byte *)dst_n_orig[z];
|
||||
lengths[z][0] = (uint8_t *)dst_px_ln - (uint8_t *)dst_px_orig[z]; // all are aligned to 4B boundary
|
||||
lengths[z][1] = (uint8_t *)dst_n_ln - (uint8_t *)dst_n_orig[z];
|
||||
}
|
||||
|
||||
uint len = 0; // total length of data
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
/** Data stored about a (single) sprite. */
|
||||
struct SpriteData {
|
||||
uint32_t offset[ZOOM_LVL_END][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
uint8_t data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
|
||||
@@ -114,7 +114,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
|
||||
(*dst_rgba_line).data = nb_pix_transp;
|
||||
|
||||
Colour *nb_right = dst_rgba_line + 1;
|
||||
dst_rgba_line = (Colour*) ((byte*) dst_rgba_line + sd.infos[z].sprite_line_size);
|
||||
dst_rgba_line = (Colour*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
|
||||
|
||||
/* Count the number of transparent pixels from the right. */
|
||||
dst_rgba = dst_rgba_line - 1;
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
struct SpriteData {
|
||||
SpriteFlags flags;
|
||||
SpriteInfo infos[ZOOM_LVL_END];
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
uint8_t data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
|
||||
|
||||
@@ -221,7 +221,7 @@ inline void Blitter_32bppSSSE3::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
|
||||
#endif
|
||||
{
|
||||
const byte * const remap = bp->remap;
|
||||
const uint8_t * const remap = bp->remap;
|
||||
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
|
||||
int effective_width = bp->width;
|
||||
|
||||
@@ -229,7 +229,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
const SpriteData * const sd = (const SpriteData *) bp->sprite;
|
||||
const SpriteInfo * const si = &sd->infos[zoom];
|
||||
const MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
|
||||
const Colour *src_rgba_line = (const Colour *) ((const byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||
|
||||
if (read_mode != RM_WITH_MARGIN) {
|
||||
src_rgba_line += bp->skip_left;
|
||||
@@ -314,7 +314,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
Colour m_colour = m_colour_init; \
|
||||
{ \
|
||||
const Colour srcm = (Colour) (m_src); \
|
||||
const uint m = (byte) (m_m); \
|
||||
const uint m = (uint8_t) (m_m); \
|
||||
const uint r = remap[m]; \
|
||||
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
||||
m_colour = r == 0 ? m_colour : cmap; \
|
||||
@@ -442,7 +442,7 @@ bmcr_alpha_blend_single:
|
||||
|
||||
next_line:
|
||||
if (mode == BM_COLOUR_REMAP || mode == BM_CRASH_REMAP) src_mv_line += si->sprite_width;
|
||||
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
|
||||
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
|
||||
dst_line += bp->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,8 +104,8 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
|
||||
/* skip upper lines in src_px and src_n */
|
||||
for (uint i = bp->skip_top; i != 0; i--) {
|
||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
}
|
||||
|
||||
/* skip lines in dst */
|
||||
@@ -114,7 +114,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
uint8_t *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32_t *)bp->dst - (uint32_t *)_screen.dst_ptr) + bp->top * bp->pitch + bp->left;
|
||||
|
||||
/* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */
|
||||
const byte *remap = bp->remap;
|
||||
const uint8_t *remap = bp->remap;
|
||||
|
||||
for (int y = 0; y < bp->height; y++) {
|
||||
/* next dst line begins here */
|
||||
@@ -122,11 +122,11 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
uint8_t *anim_ln = anim + bp->pitch;
|
||||
|
||||
/* next src line begins here */
|
||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
||||
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||
src_px++;
|
||||
|
||||
/* next src_n line begins here */
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
||||
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||
src_n += 2;
|
||||
|
||||
/* we will end this line when we reach this point */
|
||||
|
||||
@@ -147,10 +147,10 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
||||
/* Don't allocate memory each time, but just keep some
|
||||
* memory around as this function is called quite often
|
||||
* and the memory usage is quite low. */
|
||||
static ReusableBuffer<byte> temp_buffer;
|
||||
static ReusableBuffer<uint8_t> temp_buffer;
|
||||
SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
|
||||
memset(temp_dst, 0, sizeof(*temp_dst));
|
||||
byte *dst = temp_dst->data;
|
||||
uint8_t *dst = temp_dst->data;
|
||||
|
||||
/* Make the sprites per zoom-level */
|
||||
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
|
||||
@@ -166,7 +166,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
||||
uint trans = 0;
|
||||
uint pixels = 0;
|
||||
uint last_colour = 0;
|
||||
byte *count_dst = nullptr;
|
||||
uint8_t *count_dst = nullptr;
|
||||
|
||||
/* Store the scaled image */
|
||||
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
|
||||
@@ -213,7 +213,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
||||
}
|
||||
}
|
||||
|
||||
uint size = dst - (byte *)temp_dst;
|
||||
uint size = dst - (uint8_t *)temp_dst;
|
||||
|
||||
/* Safety check, to make sure we guessed the size correctly */
|
||||
assert(size < memory);
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
/** Data stored about a (single) sprite. */
|
||||
struct SpriteData {
|
||||
uint32_t offset[ZOOM_LVL_END]; ///< Offsets (from .data) to streams for different zoom levels.
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
uint8_t data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
/** Parameters related to blitting. */
|
||||
struct BlitterParams {
|
||||
const void *sprite; ///< Pointer to the sprite how ever the encoder stored it
|
||||
const byte *remap; ///< XXX -- Temporary storage for remap array
|
||||
const uint8_t *remap; ///< XXX -- Temporary storage for remap array
|
||||
|
||||
int skip_left; ///< How much pixels of the source to skip on the left (based on zoom of dst)
|
||||
int skip_top; ///< How much pixels of the source to skip on the top (based on zoom of dst)
|
||||
|
||||
46
src/bmp.cpp
46
src/bmp.cpp
@@ -39,7 +39,7 @@ static inline bool EndOfBuffer(BmpBuffer *buffer)
|
||||
return buffer->pos == buffer->read;
|
||||
}
|
||||
|
||||
static inline byte ReadByte(BmpBuffer *buffer)
|
||||
static inline uint8_t ReadByte(BmpBuffer *buffer)
|
||||
{
|
||||
if (buffer->read < 0) return 0;
|
||||
|
||||
@@ -83,9 +83,9 @@ static inline void SetStreamOffset(BmpBuffer *buffer, int offset)
|
||||
static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint x, y, i;
|
||||
byte pad = GB(4 - info->width / 8, 0, 2);
|
||||
byte *pixel_row;
|
||||
byte b;
|
||||
uint8_t pad = GB(4 - info->width / 8, 0, 2);
|
||||
uint8_t *pixel_row;
|
||||
uint8_t b;
|
||||
for (y = info->height; y > 0; y--) {
|
||||
x = 0;
|
||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
||||
@@ -110,9 +110,9 @@ static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint x, y;
|
||||
byte pad = GB(4 - info->width / 2, 0, 2);
|
||||
byte *pixel_row;
|
||||
byte b;
|
||||
uint8_t pad = GB(4 - info->width / 2, 0, 2);
|
||||
uint8_t *pixel_row;
|
||||
uint8_t b;
|
||||
for (y = info->height; y > 0; y--) {
|
||||
x = 0;
|
||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
||||
@@ -140,12 +140,12 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint x = 0;
|
||||
uint y = info->height - 1;
|
||||
byte *pixel = &data->bitmap[y * info->width];
|
||||
uint8_t *pixel = &data->bitmap[y * info->width];
|
||||
while (y != 0 || x < info->width) {
|
||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||
|
||||
byte n = ReadByte(buffer);
|
||||
byte c = ReadByte(buffer);
|
||||
uint8_t n = ReadByte(buffer);
|
||||
uint8_t c = ReadByte(buffer);
|
||||
if (n == 0) {
|
||||
switch (c) {
|
||||
case 0: // end of line
|
||||
@@ -159,8 +159,8 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
|
||||
case 2: { // delta
|
||||
if (EndOfBuffer(buffer)) return false;
|
||||
byte dx = ReadByte(buffer);
|
||||
byte dy = ReadByte(buffer);
|
||||
uint8_t dx = ReadByte(buffer);
|
||||
uint8_t dy = ReadByte(buffer);
|
||||
|
||||
/* Check for over- and underflow. */
|
||||
if (x + dx >= info->width || x + dx < x || dy > y) return false;
|
||||
@@ -175,7 +175,7 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
uint i = 0;
|
||||
while (i++ < c) {
|
||||
if (EndOfBuffer(buffer) || x >= info->width) return false;
|
||||
byte b = ReadByte(buffer);
|
||||
uint8_t b = ReadByte(buffer);
|
||||
*pixel++ = GB(b, 4, 4);
|
||||
x++;
|
||||
if (i++ < c) {
|
||||
@@ -214,8 +214,8 @@ static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint i;
|
||||
uint y;
|
||||
byte pad = GB(4 - info->width, 0, 2);
|
||||
byte *pixel;
|
||||
uint8_t pad = GB(4 - info->width, 0, 2);
|
||||
uint8_t *pixel;
|
||||
for (y = info->height; y > 0; y--) {
|
||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||
pixel = &data->bitmap[(y - 1) * info->width];
|
||||
@@ -233,12 +233,12 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint x = 0;
|
||||
uint y = info->height - 1;
|
||||
byte *pixel = &data->bitmap[y * info->width];
|
||||
uint8_t *pixel = &data->bitmap[y * info->width];
|
||||
while (y != 0 || x < info->width) {
|
||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||
|
||||
byte n = ReadByte(buffer);
|
||||
byte c = ReadByte(buffer);
|
||||
uint8_t n = ReadByte(buffer);
|
||||
uint8_t c = ReadByte(buffer);
|
||||
if (n == 0) {
|
||||
switch (c) {
|
||||
case 0: // end of line
|
||||
@@ -252,8 +252,8 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
|
||||
case 2: { // delta
|
||||
if (EndOfBuffer(buffer)) return false;
|
||||
byte dx = ReadByte(buffer);
|
||||
byte dy = ReadByte(buffer);
|
||||
uint8_t dx = ReadByte(buffer);
|
||||
uint8_t dy = ReadByte(buffer);
|
||||
|
||||
/* Check for over- and underflow. */
|
||||
if (x + dx >= info->width || x + dx < x || dy > y) return false;
|
||||
@@ -294,8 +294,8 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
uint x, y;
|
||||
byte pad = GB(4 - info->width * 3, 0, 2);
|
||||
byte *pixel_row;
|
||||
uint8_t pad = GB(4 - info->width * 3, 0, 2);
|
||||
uint8_t *pixel_row;
|
||||
for (y = info->height; y > 0; y--) {
|
||||
pixel_row = &data->bitmap[(y - 1) * info->width * 3];
|
||||
for (x = 0; x < info->width; x++) {
|
||||
@@ -395,7 +395,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||
{
|
||||
assert(info != nullptr && data != nullptr);
|
||||
|
||||
data->bitmap = CallocT<byte>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
|
||||
data->bitmap = CallocT<uint8_t>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
|
||||
|
||||
/* Load image */
|
||||
SetStreamOffset(buffer, info->offset);
|
||||
|
||||
@@ -24,13 +24,13 @@ struct BmpInfo {
|
||||
|
||||
struct BmpData {
|
||||
Colour *palette;
|
||||
byte *bitmap;
|
||||
uint8_t *bitmap;
|
||||
};
|
||||
|
||||
#define BMP_BUFFER_SIZE 1024
|
||||
|
||||
struct BmpBuffer {
|
||||
byte data[BMP_BUFFER_SIZE];
|
||||
uint8_t data[BMP_BUFFER_SIZE];
|
||||
int pos;
|
||||
int read;
|
||||
FILE *file;
|
||||
|
||||
@@ -40,7 +40,7 @@ static constexpr NWidgetPart _background_widgets[] = {
|
||||
/**
|
||||
* Window description for the background window to prevent smearing.
|
||||
*/
|
||||
static WindowDesc _background_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _background_desc(
|
||||
WDP_MANUAL, nullptr, 0, 0,
|
||||
WC_BOOTSTRAP, WC_NONE,
|
||||
WDF_NO_CLOSE,
|
||||
@@ -76,7 +76,7 @@ static constexpr NWidgetPart _nested_bootstrap_errmsg_widgets[] = {
|
||||
};
|
||||
|
||||
/** Window description for the error window. */
|
||||
static WindowDesc _bootstrap_errmsg_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _bootstrap_errmsg_desc(
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_BOOTSTRAP, WC_NONE,
|
||||
WDF_MODAL | WDF_NO_CLOSE,
|
||||
@@ -133,7 +133,7 @@ static constexpr NWidgetPart _nested_bootstrap_download_status_window_widgets[]
|
||||
};
|
||||
|
||||
/** Window description for the download window */
|
||||
static WindowDesc _bootstrap_download_status_window_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _bootstrap_download_status_window_desc(
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_NETWORK_STATUS_WINDOW, WC_NONE,
|
||||
WDF_MODAL | WDF_NO_CLOSE,
|
||||
@@ -185,7 +185,7 @@ static constexpr NWidgetPart _bootstrap_query_widgets[] = {
|
||||
};
|
||||
|
||||
/** The window description for the query. */
|
||||
static WindowDesc _bootstrap_query_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _bootstrap_query_desc(
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_CONFIRM_POPUP_QUERY, WC_NONE,
|
||||
WDF_NO_CLOSE,
|
||||
@@ -385,9 +385,9 @@ bool HandleBootstrap()
|
||||
* This way the mauve and gray colours work and we can show the user interface. */
|
||||
GfxInitPalettes();
|
||||
static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 };
|
||||
for (uint i = 0; i != 16; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
_colour_gradient[i][j] = offsets[i] + j;
|
||||
for (Colours i = COLOUR_BEGIN; i != COLOUR_END; i++) {
|
||||
for (ColourShade j = SHADE_BEGIN; j < SHADE_END; j++) {
|
||||
SetColourGradient(i, j, offsets[i] + j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef uint BridgeType; ///< Bridge spec number.
|
||||
*/
|
||||
struct BridgeSpec {
|
||||
TimerGameCalendar::Year avail_year; ///< the year where it becomes available
|
||||
byte min_length; ///< the minimum length (not counting start and end tile)
|
||||
uint8_t min_length; ///< the minimum length (not counting start and end tile)
|
||||
uint16_t max_length; ///< the maximum length (not counting start and end tile)
|
||||
uint16_t price; ///< the price multiplier
|
||||
uint16_t speed; ///< maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
|
||||
@@ -50,7 +50,7 @@ struct BridgeSpec {
|
||||
StringID material; ///< the string that contains the bridge description
|
||||
StringID transport_name[2]; ///< description of the bridge, when built for road or rail
|
||||
PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
|
||||
byte flags; ///< bit 0 set: disable drawing of far pillars.
|
||||
uint8_t flags; ///< bit 0 set: disable drawing of far pillars.
|
||||
};
|
||||
|
||||
extern BridgeSpec _bridge[MAX_BRIDGES];
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "gfx_func.h"
|
||||
#include "tunnelbridge.h"
|
||||
#include "sortlist_type.h"
|
||||
#include "widgets/dropdown_func.h"
|
||||
#include "dropdown_func.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "tunnelbridge_map.h"
|
||||
#include "road_gui.h"
|
||||
@@ -55,7 +55,7 @@ typedef GUIList<BuildBridgeData> GUIBridgeList; ///< List of bridges, used in #B
|
||||
* @param tile_start start tile
|
||||
* @param transport_type transport type.
|
||||
*/
|
||||
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, byte)
|
||||
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t)
|
||||
{
|
||||
if (result.Failed()) return;
|
||||
if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile);
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
TileIndex start_tile;
|
||||
TileIndex end_tile;
|
||||
TransportType transport_type;
|
||||
byte road_rail_type;
|
||||
uint8_t road_rail_type;
|
||||
GUIBridgeList bridges;
|
||||
int icon_width; ///< Scaled width of the the bridge icon sprite.
|
||||
Scrollbar *vscroll;
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, GUIBridgeList &&bl) : Window(desc),
|
||||
BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type, GUIBridgeList &&bl) : Window(desc),
|
||||
start_tile(start),
|
||||
end_tile(end),
|
||||
transport_type(transport_type),
|
||||
@@ -233,11 +233,11 @@ public:
|
||||
case WID_BBS_BRIDGE_LIST: {
|
||||
Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges.size(); i++) {
|
||||
const BuildBridgeData &bridge_data = this->bridges.at(i);
|
||||
const BridgeSpec *b = bridge_data.spec;
|
||||
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->bridges);
|
||||
for (auto it = first; it != last; ++it) {
|
||||
const BridgeSpec *b = it->spec;
|
||||
DrawSpriteIgnorePadding(b->sprite, b->pal, tr.WithWidth(this->icon_width, rtl), SA_HOR_CENTER | SA_BOTTOM);
|
||||
DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(bridge_data));
|
||||
DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(*it));
|
||||
tr = tr.Translate(0, this->resize.step_height);
|
||||
}
|
||||
break;
|
||||
@@ -343,7 +343,7 @@ static constexpr NWidgetPart _nested_build_bridge_widgets[] = {
|
||||
};
|
||||
|
||||
/** Window definition for the rail bridge selection window. */
|
||||
static WindowDesc _build_bridge_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _build_bridge_desc(
|
||||
WDP_AUTO, "build_bridge", 200, 114,
|
||||
WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
|
||||
WDF_CONSTRUCTION,
|
||||
@@ -360,7 +360,7 @@ static WindowDesc _build_bridge_desc(__FILE__, __LINE__,
|
||||
* @param transport_type The transport type
|
||||
* @param road_rail_type The road/rail type
|
||||
*/
|
||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
|
||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type)
|
||||
{
|
||||
CloseWindowByClass(WC_BUILD_BRIDGE);
|
||||
|
||||
|
||||
@@ -69,10 +69,9 @@ TileIndex GetOtherBridgeEnd(TileIndex tile)
|
||||
*/
|
||||
int GetBridgeHeight(TileIndex t)
|
||||
{
|
||||
int h;
|
||||
Slope tileh = GetTileSlope(t, &h);
|
||||
auto [tileh, h] = GetTileSlopeZ(t);
|
||||
Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetTunnelBridgeDirection(t)));
|
||||
|
||||
/* one height level extra for the ramp */
|
||||
return h + 1 + ApplyFoundationToSlope(f, &tileh);
|
||||
return h + 1 + ApplyFoundationToSlope(f, tileh);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ static const NWidgetPart _nested_build_info_widgets[] = {
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _build_info_desc(__FILE__, __LINE__,
|
||||
WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
|
||||
static WindowDesc _build_info_desc(
|
||||
WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
|
||||
WC_TOOLTIPS, WC_NONE,
|
||||
WDF_NO_FOCUS,
|
||||
std::begin(_nested_build_info_widgets), std::end(_nested_build_info_widgets)
|
||||
@@ -208,11 +208,11 @@ struct BuildConfirmationWindow : Window {
|
||||
DrawFrameRect(x, y, x + w, y + h, COLOUR_GREY, FR_BORDERONLY);
|
||||
Dimension d = GetStringBoundingBox(str);
|
||||
DrawFrameRect(x + w / 2 - d.width / 2 - 1,
|
||||
y + h / 2 - d.height / 2 - 2,
|
||||
CenterBounds(y, h, d.height) - 2,
|
||||
x + w / 2 + d.width / 2 + 1,
|
||||
y + h / 2 - d.height / 2 + d.height,
|
||||
CenterBounds(y, h, d.height) + d.height,
|
||||
COLOUR_GREY, FR_NONE);
|
||||
DrawString(x, x + w, y + h / 2 - d.height / 2 - 2, str, TC_FROMSTRING, SA_HOR_CENTER);
|
||||
DrawString(x, x + w, CenterBounds(y, h, d.height), str, TC_FROMSTRING, SA_HOR_CENTER);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ static const NWidgetPart _nested_build_confirmation_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _build_confirmation_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _build_confirmation_desc(
|
||||
WDP_MANUAL, "build_confirmation", 0, 0,
|
||||
WC_BUILD_CONFIRMATION, WC_NONE,
|
||||
0,
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include "window_func.h"
|
||||
#include "timer/timer_game_calendar.h"
|
||||
#include "vehicle_func.h"
|
||||
#include "widgets/dropdown_func.h"
|
||||
#include "dropdown_type.h"
|
||||
#include "dropdown_func.h"
|
||||
#include "engine_gui.h"
|
||||
#include "cargotype.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
@@ -97,7 +98,7 @@ static constexpr NWidgetPart _nested_build_vehicle_widgets[] = {
|
||||
|
||||
|
||||
bool _engine_sort_direction; ///< \c false = descending, \c true = ascending.
|
||||
byte _engine_sort_last_criteria[] = {0, 0, 0, 0}; ///< Last set sort criteria, for each vehicle type.
|
||||
uint8_t _engine_sort_last_criteria[] = {0, 0, 0, 0}; ///< Last set sort criteria, for each vehicle type.
|
||||
bool _engine_sort_last_order[] = {false, false, false, false}; ///< Last set direction of the sort order, for each vehicle type.
|
||||
bool _engine_sort_show_hidden_engines[] = {false, false, false, false}; ///< Last set 'show hidden engines' setting for each vehicle type.
|
||||
static CargoID _engine_sort_last_cargo_criteria[] = {CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY}; ///< Last set filter criteria, for each vehicle type.
|
||||
@@ -1000,18 +1001,16 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
|
||||
* @param type Type of vehicle (VEH_*)
|
||||
* @param r The Rect of the list
|
||||
* @param eng_list What engines to draw
|
||||
* @param min where to start in the list
|
||||
* @param max where in the list to end
|
||||
* @param sb Scrollbar of list.
|
||||
* @param selected_id what engine to highlight as selected, if any
|
||||
* @param show_count Whether to show the amount of engines or not
|
||||
* @param selected_group the group to list the engines of
|
||||
*/
|
||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16_t min, uint16_t max, EngineID selected_id, bool show_count, GroupID selected_group)
|
||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, const Scrollbar &sb, EngineID selected_id, bool show_count, GroupID selected_group)
|
||||
{
|
||||
static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
|
||||
|
||||
/* Obligatory sanity checks! */
|
||||
assert(max <= eng_list.size());
|
||||
auto [first, last] = sb.GetVisibleRangeIterators(eng_list);
|
||||
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
int step_size = GetEngineListHeight(type);
|
||||
@@ -1019,7 +1018,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
||||
int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
|
||||
int sprite_width = sprite_left + sprite_right;
|
||||
int circle_width = std::max(GetScaledSpriteSize(SPR_CIRCLE_FOLDED).width, GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED).width);
|
||||
int linecolour = _colour_gradient[COLOUR_ORANGE][4];
|
||||
int linecolour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL);
|
||||
|
||||
Rect ir = r.WithHeight(step_size).Shrink(WidgetDimensions::scaled.matrix);
|
||||
int sprite_y_offset = ScaleSpriteTrad(sprite_y_offsets[type]) + ir.Height() / 2;
|
||||
@@ -1030,9 +1029,8 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
||||
replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE);
|
||||
|
||||
uint biggest_num_engines = 0;
|
||||
for (auto i = min; i < max; i++) {
|
||||
const auto &item = eng_list[i];
|
||||
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, item.engine_id);
|
||||
for (auto it = first; it != last; ++it) {
|
||||
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, it->engine_id);
|
||||
biggest_num_engines = std::max(biggest_num_engines, num_engines);
|
||||
}
|
||||
|
||||
@@ -1050,8 +1048,8 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
||||
int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2;
|
||||
|
||||
int y = ir.top;
|
||||
for (; min < max; min++, y += step_size) {
|
||||
const auto &item = eng_list[min];
|
||||
for (auto it = first; it != last; ++it) {
|
||||
const auto &item = *it;
|
||||
uint indent = item.indent * WidgetDimensions::scaled.hsep_indent;
|
||||
bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None;
|
||||
bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None;
|
||||
@@ -1087,10 +1085,11 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
||||
/* Draw tree lines */
|
||||
Rect fr = ir.Indent(indent - WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(circle_width, rtl);
|
||||
int ycenter = y + normal_text_y_offset + GetCharacterHeight(FS_NORMAL) / 2;
|
||||
bool continues = (min + 1U) < eng_list.size() && eng_list[min + 1].indent == item.indent;
|
||||
bool continues = std::next(it) != std::end(eng_list) && std::next(it)->indent == item.indent;
|
||||
GfxDrawLine(fr.left + circle_width / 2, y - WidgetDimensions::scaled.matrix.top, fr.left + circle_width / 2, continues ? y - WidgetDimensions::scaled.matrix.top + step_size - 1 : ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
||||
GfxDrawLine(fr.left + circle_width / 2, ycenter, fr.right, ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
||||
}
|
||||
y += step_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1130,7 +1129,7 @@ struct BuildVehicleWindow : Window {
|
||||
RoadType roadtype; ///< Road type to show, or #INVALID_ROADTYPE.
|
||||
} filter; ///< Filter to apply.
|
||||
bool descending_sort_order; ///< Sort direction, @see _engine_sort_direction
|
||||
byte sort_criteria; ///< Current sort criterium.
|
||||
uint8_t sort_criteria; ///< Current sort criterium.
|
||||
bool show_hidden_engines; ///< State of the 'show hidden engines' button.
|
||||
bool listview_mode; ///< If set, only display the available vehicles and do not show a 'build' button.
|
||||
EngineID sel_engine; ///< Currently selected engine, or #INVALID_ENGINE
|
||||
@@ -1569,20 +1568,20 @@ struct BuildVehicleWindow : Window {
|
||||
DropDownList list;
|
||||
|
||||
/* Add item for disabling filtering. */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
|
||||
/* Specific filters for trains. */
|
||||
if (this->vehicle_type == VEH_TRAIN) {
|
||||
/* Add item for locomotives only in case of trains. */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES));
|
||||
/* Add item for vehicles not carrying anything, e.g. train engines.
|
||||
* This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
|
||||
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
|
||||
}
|
||||
|
||||
/* Add cargos */
|
||||
Dimension d = GetLargestCargoIconSize();
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
|
||||
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -1794,8 +1793,7 @@ struct BuildVehicleWindow : Window {
|
||||
this->vehicle_type,
|
||||
r,
|
||||
this->eng_list,
|
||||
this->vscroll->GetPosition(),
|
||||
static_cast<uint16_t>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())),
|
||||
*this->vscroll,
|
||||
this->sel_engine,
|
||||
false,
|
||||
DEFAULT_GROUP
|
||||
@@ -1824,7 +1822,7 @@ struct BuildVehicleWindow : Window {
|
||||
int needed_height = this->details_height;
|
||||
/* Draw details panels. */
|
||||
if (this->sel_engine != INVALID_ENGINE) {
|
||||
const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
|
||||
const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
|
||||
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te);
|
||||
needed_height = std::max(needed_height, (text_end - r.top) / GetCharacterHeight(FS_NORMAL));
|
||||
}
|
||||
@@ -1902,7 +1900,7 @@ struct BuildVehicleWindow : Window {
|
||||
}};
|
||||
};
|
||||
|
||||
static WindowDesc _build_vehicle_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _build_vehicle_desc(
|
||||
WDP_AUTO, "build_vehicle", 240, 268,
|
||||
WC_BUILD_VEHICLE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
|
||||
@@ -19,7 +19,7 @@ using CargoLabel = StrongType::Typedef<uint32_t, struct CargoLabelTag, StrongTyp
|
||||
/**
|
||||
* Cargo slots to indicate a cargo type within a game.
|
||||
*/
|
||||
using CargoID = byte;
|
||||
using CargoID = uint8_t;
|
||||
|
||||
/**
|
||||
* Available types of cargo
|
||||
@@ -134,7 +134,7 @@ struct CargoArray : std::array<uint, NUM_CARGO> {
|
||||
|
||||
|
||||
/** Types of cargo source and destination */
|
||||
enum class SourceType : byte {
|
||||
enum class SourceType : uint8_t {
|
||||
Industry, ///< Source/destination is an industry
|
||||
Town, ///< Source/destination is a town
|
||||
Headquarters, ///< Source/destination are company headquarters
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "core/bitmath_func.hpp"
|
||||
|
||||
/** Town growth effect when delivering cargo. */
|
||||
enum TownAcceptanceEffect : byte {
|
||||
enum TownAcceptanceEffect : uint8_t {
|
||||
TAE_BEGIN = 0,
|
||||
TAE_NONE = TAE_BEGIN, ///< Cargo has no effect.
|
||||
TAE_PASSENGERS, ///< Cargo behaves passenger-like.
|
||||
@@ -31,7 +31,7 @@ enum TownAcceptanceEffect : byte {
|
||||
};
|
||||
|
||||
/** Town effect when producing cargo. */
|
||||
enum TownProductionEffect : byte {
|
||||
enum TownProductionEffect : uint8_t {
|
||||
TPE_NONE, ///< Town will not produce this cargo type.
|
||||
TPE_PASSENGERS, ///< Cargo behaves passenger-like for production.
|
||||
TPE_MAIL, ///< Cargo behaves mail-like for production.
|
||||
@@ -60,7 +60,7 @@ enum CargoClass {
|
||||
CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
|
||||
};
|
||||
|
||||
static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
|
||||
static const uint8_t INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
|
||||
|
||||
static const uint TOWN_PRODUCTION_DIVISOR = 256;
|
||||
|
||||
|
||||
@@ -426,7 +426,7 @@ struct CheatWindow : Window {
|
||||
};
|
||||
|
||||
/** Window description of the cheats GUI. */
|
||||
static WindowDesc _cheats_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _cheats_desc(
|
||||
WDP_AUTO, "cheats", 0, 0,
|
||||
WC_CHEATS, WC_NONE,
|
||||
0,
|
||||
|
||||
@@ -44,7 +44,7 @@ static CommandCost ClearTile_Clear(TileIndex tile, DoCommandFlag flags)
|
||||
return price;
|
||||
}
|
||||
|
||||
void DrawClearLandTile(const TileInfo *ti, byte set)
|
||||
void DrawClearLandTile(const TileInfo *ti, uint8_t set)
|
||||
{
|
||||
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh) + set * 19, PAL_NONE);
|
||||
}
|
||||
@@ -129,8 +129,7 @@ static void DrawTile_Clear(TileInfo *ti)
|
||||
|
||||
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool)
|
||||
{
|
||||
int z;
|
||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
||||
auto [tileh, z] = GetTilePixelSlope(tile);
|
||||
|
||||
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
|
||||
}
|
||||
@@ -145,25 +144,25 @@ static void UpdateFences(TileIndex tile)
|
||||
assert(IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
|
||||
bool dirty = false;
|
||||
|
||||
bool neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
|
||||
bool neighbour = (IsTileType(TileAddXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, 1, 0), CLEAR_FIELDS));
|
||||
if (!neighbour && GetFence(tile, DIAGDIR_SW) == 0) {
|
||||
SetFence(tile, DIAGDIR_SW, 3);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
|
||||
neighbour = (IsTileType(TileAddXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, 1), CLEAR_FIELDS));
|
||||
if (!neighbour && GetFence(tile, DIAGDIR_SE) == 0) {
|
||||
SetFence(tile, DIAGDIR_SE, 3);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
neighbour = (IsTileType(TILE_ADDXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, -1, 0), CLEAR_FIELDS));
|
||||
neighbour = (IsTileType(TileAddXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, -1, 0), CLEAR_FIELDS));
|
||||
if (!neighbour && GetFence(tile, DIAGDIR_NE) == 0) {
|
||||
SetFence(tile, DIAGDIR_NE, 3);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
neighbour = (IsTileType(TILE_ADDXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, -1), CLEAR_FIELDS));
|
||||
neighbour = (IsTileType(TileAddXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, -1), CLEAR_FIELDS));
|
||||
if (!neighbour && GetFence(tile, DIAGDIR_NW) == 0) {
|
||||
SetFence(tile, DIAGDIR_NW, 3);
|
||||
dirty = true;
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
#include "tile_cmd.h"
|
||||
|
||||
void DrawHillyLandTile(const TileInfo *ti);
|
||||
void DrawClearLandTile(const TileInfo *ti, byte set);
|
||||
void DrawClearLandTile(const TileInfo *ti, uint8_t set);
|
||||
|
||||
#endif /* CLEAR_FUNC_H */
|
||||
|
||||
@@ -372,7 +372,7 @@ protected:
|
||||
assert(AllClientIdsSet(args, std::index_sequence_for<Targs...>{}));
|
||||
}
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company);
|
||||
if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) {
|
||||
cur_company.Trash();
|
||||
return MakeResult(CMD_ERROR);
|
||||
|
||||
@@ -462,7 +462,7 @@ template <Commands Tcmd> struct CommandTraits;
|
||||
};
|
||||
|
||||
/** Storage buffer for serialized command data. */
|
||||
typedef std::vector<byte> CommandDataBuffer;
|
||||
typedef std::vector<uint8_t> CommandDataBuffer;
|
||||
|
||||
/**
|
||||
* Define a callback function for the client, after the command is finished.
|
||||
|
||||
@@ -78,20 +78,21 @@ struct CompanyProperties {
|
||||
CompanyManagerFace face; ///< Face description of the president.
|
||||
|
||||
Money money; ///< Money owned by the company.
|
||||
byte money_fraction; ///< Fraction of money of the company, too small to represent in #money.
|
||||
uint8_t money_fraction; ///< Fraction of money of the company, too small to represent in #money.
|
||||
Money current_loan; ///< Amount of money borrowed from the bank.
|
||||
Money max_loan; ///< Max allowed amount of the loan or COMPANY_MAX_LOAN_DEFAULT.
|
||||
|
||||
Colours colour; ///< Company colour.
|
||||
|
||||
byte block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics).
|
||||
uint8_t block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics).
|
||||
|
||||
TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none.
|
||||
TileIndex last_build_coordinate; ///< Coordinate of the last build thing by this company.
|
||||
|
||||
TimerGameEconomy::Year inaugurated_year; ///< Economy year of starting the company.
|
||||
|
||||
byte months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
|
||||
uint8_t months_empty = 0; ///< NOSAVE: Number of months this company has not had a client in multiplayer.
|
||||
uint8_t months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
|
||||
CompanyMask bankrupt_asked; ///< which companies were asked about buying it?
|
||||
int16_t bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company.
|
||||
Money bankrupt_value;
|
||||
@@ -110,7 +111,7 @@ struct CompanyProperties {
|
||||
std::array<Expenses, 3> yearly_expenses{}; ///< Expenses of the company for the last three years.
|
||||
CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter.
|
||||
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
|
||||
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
||||
uint8_t num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
||||
|
||||
Livery livery[LS_END];
|
||||
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
#include "game/game.hpp"
|
||||
#include "goal_base.h"
|
||||
#include "story_base.h"
|
||||
#include "widgets/statusbar_widget.h"
|
||||
#include "company_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
#include "timer/timer_game_economy.h"
|
||||
#include "timer/timer_game_tick.h"
|
||||
|
||||
#include "widgets/statusbar_widget.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
@@ -146,8 +147,8 @@ void SetLocalCompany(CompanyID new_company)
|
||||
*/
|
||||
TextColour GetDrawStringCompanyColour(CompanyID company)
|
||||
{
|
||||
if (!Company::IsValidID(company)) return (TextColour)_colour_gradient[COLOUR_WHITE][4] | TC_IS_PALETTE_COLOUR;
|
||||
return (TextColour)_colour_gradient[_company_colours[company]][4] | TC_IS_PALETTE_COLOUR;
|
||||
if (!Company::IsValidID(company)) return (TextColour)GetColourGradient(COLOUR_WHITE, SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
|
||||
return (TextColour)GetColourGradient(_company_colours[company], SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,10 +299,10 @@ void SubtractMoneyFromCompany(const CommandCost &cost)
|
||||
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
|
||||
{
|
||||
Company *c = Company::Get(company);
|
||||
byte m = c->money_fraction;
|
||||
uint8_t m = c->money_fraction;
|
||||
Money cost = cst.GetCost();
|
||||
|
||||
c->money_fraction = m - (byte)cost;
|
||||
c->money_fraction = m - (uint8_t)cost;
|
||||
cost >>= 8;
|
||||
if (c->money_fraction > m) cost++;
|
||||
if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
|
||||
@@ -447,7 +448,7 @@ bad_town_name:;
|
||||
}
|
||||
|
||||
/** Sorting weights for the company colours. */
|
||||
static const byte _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
|
||||
static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
|
||||
/** Similar colours, so we can try to prevent same coloured companies. */
|
||||
static const Colours _similar_colour[COLOUR_END][2] = {
|
||||
{ COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
|
||||
@@ -477,7 +478,7 @@ static Colours GenerateCompanyColour()
|
||||
Colours colours[COLOUR_END];
|
||||
|
||||
/* Initialize array */
|
||||
for (uint i = 0; i < COLOUR_END; i++) colours[i] = (Colours)i;
|
||||
for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast<Colours>(i);
|
||||
|
||||
/* And randomize it */
|
||||
for (uint i = 0; i < 100; i++) {
|
||||
@@ -635,7 +636,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
}
|
||||
|
||||
/** Start a new competitor company if possible. */
|
||||
TimeoutTimer<TimerGameTick> _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() {
|
||||
TimeoutTimer<TimerGameTick> _new_competitor_timeout(0, []() {
|
||||
if (_game_mode == GM_MENU || !AI::CanStartNew()) return;
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return;
|
||||
|
||||
@@ -776,7 +777,7 @@ void OnTick_Companies()
|
||||
/* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */
|
||||
timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8;
|
||||
|
||||
_new_competitor_timeout.Reset({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, static_cast<uint>(std::max(1, timeout)) });
|
||||
_new_competitor_timeout.Reset(std::max(1, timeout));
|
||||
}
|
||||
|
||||
_cur_company_tick_index = (_cur_company_tick_index + 1) % MAX_COMPANIES;
|
||||
@@ -1181,7 +1182,6 @@ CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text)
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateWindowClassesData(WC_COMPANY, 1);
|
||||
MarkWholeScreenDirty();
|
||||
CompanyAdminUpdate(c);
|
||||
}
|
||||
@@ -1256,7 +1256,7 @@ CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_compan
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* Add money to company */
|
||||
Backup<CompanyID> cur_company(_current_company, dest_company, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, dest_company);
|
||||
SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
|
||||
cur_company.Restore();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "livery.h"
|
||||
|
||||
enum ClientID : uint32_t;
|
||||
enum Colours : byte;
|
||||
enum Colours : uint8_t;
|
||||
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id);
|
||||
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company);
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#include "company_manager_face.h"
|
||||
#include "strings_func.h"
|
||||
#include "timer/timer_game_economy.h"
|
||||
#include "widgets/dropdown_type.h"
|
||||
#include "dropdown_type.h"
|
||||
#include "dropdown_common_type.h"
|
||||
#include "tilehighlight_func.h"
|
||||
#include "company_base.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "company_cmd.h"
|
||||
#include "economy_cmd.h"
|
||||
#include "group_cmd.h"
|
||||
#include "group_gui.h"
|
||||
#include "misc_cmd.h"
|
||||
#include "object_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
@@ -530,7 +532,7 @@ struct CompanyFinancesWindow : Window {
|
||||
/** First conservative estimate of the maximum amount of money */
|
||||
Money CompanyFinancesWindow::max_money = INT32_MAX;
|
||||
|
||||
static WindowDesc _company_finances_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _company_finances_desc(
|
||||
WDP_AUTO, "company_finances", 0, 0,
|
||||
WC_FINANCES, WC_NONE,
|
||||
0,
|
||||
@@ -592,8 +594,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef GUIList<const Group*> GUIGroupList;
|
||||
|
||||
/** Company livery colour scheme window. */
|
||||
struct SelectCompanyLiveryWindow : public Window {
|
||||
private:
|
||||
@@ -603,7 +603,6 @@ private:
|
||||
uint rows;
|
||||
uint line_height;
|
||||
GUIGroupList groups;
|
||||
std::vector<int> indents;
|
||||
Scrollbar *vscroll;
|
||||
|
||||
void ShowColourDropDownMenu(uint32_t widget)
|
||||
@@ -611,7 +610,7 @@ private:
|
||||
uint32_t used_colours = 0;
|
||||
const Livery *livery, *default_livery = nullptr;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
byte default_col = 0;
|
||||
uint8_t default_col = 0;
|
||||
|
||||
/* Disallow other company colours for the primary colour */
|
||||
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
||||
@@ -652,7 +651,7 @@ private:
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(i, HasBit(used_colours, i)));
|
||||
}
|
||||
|
||||
byte sel;
|
||||
uint8_t sel;
|
||||
if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
sel = primary ? livery->colour1 : livery->colour2;
|
||||
} else {
|
||||
@@ -661,57 +660,15 @@ private:
|
||||
ShowDropDownList(this, std::move(list), sel, widget);
|
||||
}
|
||||
|
||||
void AddChildren(GUIGroupList &source, GroupID parent, int indent)
|
||||
{
|
||||
for (const Group *g : source) {
|
||||
if (g->parent != parent) continue;
|
||||
this->groups.push_back(g);
|
||||
this->indents.push_back(indent);
|
||||
AddChildren(source, g->index, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildGroupList(CompanyID owner)
|
||||
{
|
||||
if (!this->groups.NeedRebuild()) return;
|
||||
|
||||
this->groups.clear();
|
||||
this->indents.clear();
|
||||
|
||||
if (this->livery_class >= LC_GROUP_RAIL) {
|
||||
GUIGroupList list;
|
||||
VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL);
|
||||
|
||||
for (const Group *g : Group::Iterate()) {
|
||||
if (g->owner == owner && g->vehicle_type == vtype) {
|
||||
list.push_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
list.ForceResort();
|
||||
|
||||
/* Sort the groups by their name */
|
||||
const Group *last_group[2] = { nullptr, nullptr };
|
||||
std::string last_name[2] = { {}, {} };
|
||||
list.Sort([&](const Group * const &a, const Group * const &b) -> bool {
|
||||
if (a != last_group[0]) {
|
||||
last_group[0] = a;
|
||||
SetDParam(0, a->index);
|
||||
last_name[0] = GetString(STR_GROUP_NAME);
|
||||
}
|
||||
|
||||
if (b != last_group[1]) {
|
||||
last_group[1] = b;
|
||||
SetDParam(0, b->index);
|
||||
last_name[1] = GetString(STR_GROUP_NAME);
|
||||
}
|
||||
|
||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
});
|
||||
|
||||
AddChildren(list, INVALID_GROUP, 0);
|
||||
BuildGuiGroupList(this->groups, false, owner, vtype);
|
||||
}
|
||||
|
||||
this->groups.shrink_to_fit();
|
||||
@@ -775,7 +732,7 @@ public:
|
||||
|
||||
/* Position scrollbar to selected group */
|
||||
for (uint i = 0; i < this->rows; i++) {
|
||||
if (this->groups[i]->index == sel) {
|
||||
if (this->groups[i].group->index == sel) {
|
||||
this->vscroll->SetPosition(i - this->vscroll->GetCapacity() / 2);
|
||||
break;
|
||||
}
|
||||
@@ -945,11 +902,11 @@ public:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.size()));
|
||||
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
|
||||
const Group *g = this->groups[i];
|
||||
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->groups);
|
||||
for (auto it = first; it != last; ++it) {
|
||||
const Group *g = it->group;
|
||||
SetDParam(0, g->index);
|
||||
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * WidgetDimensions::scaled.hsep_indent);
|
||||
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, it->indent * WidgetDimensions::scaled.hsep_indent);
|
||||
}
|
||||
|
||||
if (this->vscroll->GetCount() == 0) {
|
||||
@@ -992,7 +949,7 @@ public:
|
||||
this->BuildGroupList((CompanyID)this->window_number);
|
||||
|
||||
if (!this->groups.empty()) {
|
||||
this->sel = this->groups[0]->index;
|
||||
this->sel = this->groups[0].group->index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1009,10 +966,10 @@ public:
|
||||
break;
|
||||
|
||||
case WID_SCL_MATRIX: {
|
||||
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCL_MATRIX);
|
||||
if (row >= this->rows) return;
|
||||
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget);
|
||||
if (row >= this->rows) return;
|
||||
|
||||
LiveryScheme j = (LiveryScheme)row;
|
||||
|
||||
for (LiveryScheme scheme = LS_BEGIN; scheme <= j && scheme < LS_END; scheme++) {
|
||||
@@ -1026,7 +983,10 @@ public:
|
||||
this->sel = 1 << j;
|
||||
}
|
||||
} else {
|
||||
this->sel = this->groups[row]->index;
|
||||
auto it = this->vscroll->GetScrolledItemFromWidget(this->groups, pt.y, this, widget);
|
||||
if (it == std::end(this->groups)) return;
|
||||
|
||||
this->sel = it->group->index;
|
||||
}
|
||||
this->SetDirty();
|
||||
break;
|
||||
@@ -1079,7 +1039,7 @@ public:
|
||||
|
||||
if (!Group::IsValidID(this->sel)) {
|
||||
this->sel = INVALID_GROUP;
|
||||
if (!this->groups.empty()) this->sel = this->groups[0]->index;
|
||||
if (!this->groups.empty()) this->sel = this->groups[0].group->index;
|
||||
}
|
||||
|
||||
this->SetDirty();
|
||||
@@ -1140,7 +1100,7 @@ static constexpr NWidgetPart _nested_select_company_livery_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _select_company_livery_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _select_company_livery_desc(
|
||||
WDP_AUTO, "company_color_scheme", 0, 0,
|
||||
WC_COMPANY_COLOUR, WC_NONE,
|
||||
0,
|
||||
@@ -1769,7 +1729,7 @@ public:
|
||||
};
|
||||
|
||||
/** Company manager face selection window description */
|
||||
static WindowDesc _select_company_manager_face_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _select_company_manager_face_desc(
|
||||
WDP_AUTO, nullptr, 0, 0,
|
||||
WC_COMPANY_MANAGER_FACE, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
@@ -2146,7 +2106,7 @@ struct CompanyInfrastructureWindow : Window
|
||||
}
|
||||
};
|
||||
|
||||
static WindowDesc _company_infrastructure_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _company_infrastructure_desc(
|
||||
WDP_AUTO, "company_infrastructure", 0, 0,
|
||||
WC_COMPANY_INFRASTRUCTURE, WC_NONE,
|
||||
0,
|
||||
@@ -2497,14 +2457,6 @@ struct CompanyWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
void OnResize() override
|
||||
{
|
||||
NWidgetResizeBase *wid = this->GetWidget<NWidgetResizeBase>(WID_C_FACE_TITLE);
|
||||
SetDParam(0, this->owner);
|
||||
int y = GetStringHeight(STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE, wid->current_x);
|
||||
if (wid->UpdateVerticalSize(y)) this->ReInit(0, 0);
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
@@ -2537,7 +2489,7 @@ struct CompanyWindow : Window
|
||||
}
|
||||
|
||||
case WID_C_BUILD_HQ:
|
||||
if ((byte)this->window_number != _local_company) return;
|
||||
if ((uint8_t)this->window_number != _local_company) return;
|
||||
if (this->IsWidgetLowered(WID_C_BUILD_HQ)) {
|
||||
ResetObjectToPlace();
|
||||
this->RaiseButtons();
|
||||
@@ -2622,7 +2574,7 @@ struct CompanyWindow : Window
|
||||
default: NOT_REACHED();
|
||||
|
||||
case WID_C_GIVE_MONEY: {
|
||||
Money money = std::strtoull(str, nullptr, 10) / _currency->rate;
|
||||
Money money = std::strtoull(str, nullptr, 10) / GetCurrency().rate;
|
||||
Command<CMD_GIVE_MONEY>::Post(STR_ERROR_CAN_T_GIVE_MONEY, money, (CompanyID)this->window_number);
|
||||
break;
|
||||
}
|
||||
@@ -2640,17 +2592,9 @@ struct CompanyWindow : Window
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (gui_scope && data == 1) {
|
||||
/* Manually call OnResize to adjust minimum height of president name widget. */
|
||||
OnResize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static WindowDesc _company_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _company_desc(
|
||||
WDP_AUTO, "company", 0, 0,
|
||||
WC_COMPANY, WC_NONE,
|
||||
0,
|
||||
@@ -2784,7 +2728,7 @@ static constexpr NWidgetPart _nested_buy_company_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _buy_company_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _buy_company_desc(
|
||||
WDP_AUTO, nullptr, 0, 0,
|
||||
WC_BUY_COMPANY, WC_NONE,
|
||||
WDF_CONSTRUCTION,
|
||||
|
||||
@@ -54,9 +54,9 @@ DECLARE_POSTFIX_INCREMENT(CompanyManagerFaceVariable)
|
||||
|
||||
/** Information about the valid values of CompanyManagerFace bitgroups as well as the sprites to draw */
|
||||
struct CompanyManagerFaceBitsInfo {
|
||||
byte offset; ///< Offset in bits into the CompanyManagerFace
|
||||
byte length; ///< Number of bits used in the CompanyManagerFace
|
||||
byte valid_values[GE_END]; ///< The number of valid values per gender/ethnicity
|
||||
uint8_t offset; ///< Offset in bits into the CompanyManagerFace
|
||||
uint8_t length; ///< Number of bits used in the CompanyManagerFace
|
||||
uint8_t valid_values[GE_END]; ///< The number of valid values per gender/ethnicity
|
||||
SpriteID first_sprite[GE_END]; ///< The first sprite per gender/ethnicity
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/**
|
||||
* Enum for all companies/owners.
|
||||
*/
|
||||
enum Owner : byte {
|
||||
enum Owner : uint8_t {
|
||||
/* All companies below MAX_COMPANIES are playable
|
||||
* companies, above, they are special, computer controlled 'companies' */
|
||||
OWNER_BEGIN = 0x00, ///< First owner
|
||||
|
||||
@@ -206,7 +206,7 @@ static std::string RemoveUnderscores(std::string name)
|
||||
* @param tokencount the number of parameters passed
|
||||
* @param *tokens are the parameters given to the original command (0 is the first param)
|
||||
*/
|
||||
static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
|
||||
static void IConsoleAliasExec(const IConsoleAlias *alias, uint8_t tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
|
||||
{
|
||||
std::string alias_buffer;
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static ConsoleFileList _console_file_list_scenario{FT_SCENARIO, false}; ///< Fil
|
||||
static ConsoleFileList _console_file_list_heightmap{FT_HEIGHTMAP, false}; ///< File storage cache for heightmaps.
|
||||
|
||||
/* console command defines */
|
||||
#define DEF_CONSOLE_CMD(function) static bool function([[maybe_unused]] byte argc, [[maybe_unused]] char *argv[])
|
||||
#define DEF_CONSOLE_CMD(function) static bool function([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *argv[])
|
||||
#define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
|
||||
|
||||
|
||||
@@ -850,6 +850,7 @@ DEF_CONSOLE_CMD(ConRcon)
|
||||
if (argc == 0) {
|
||||
IConsolePrint(CC_HELP, "Remote control the server from another client. Usage: 'rcon <password> <command>'.");
|
||||
IConsolePrint(CC_HELP, "Remember to enclose the command in quotes, otherwise only the first parameter is sent.");
|
||||
IConsolePrint(CC_HELP, "When your client's public key is in the 'authorized keys' for 'rcon', the password is not checked and may be '*'.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1975,6 +1976,86 @@ DEF_CONSOLE_CMD(ConCompanyPassword)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** All the known authorized keys with their name. */
|
||||
static std::vector<std::pair<std::string_view, NetworkAuthorizedKeys *>> _console_cmd_authorized_keys{
|
||||
{ "rcon", &_settings_client.network.rcon_authorized_keys },
|
||||
{ "server", &_settings_client.network.server_authorized_keys },
|
||||
};
|
||||
|
||||
DEF_CONSOLE_CMD(ConNetworkAuthorizedKey)
|
||||
{
|
||||
if (argc <= 2) {
|
||||
IConsolePrint(CC_HELP, "List and update authorized keys. Usage: 'authorized_key list [type]|add [type] [key]|remove [type] [key]'.");
|
||||
IConsolePrint(CC_HELP, " list: list all the authorized keys of the given type.");
|
||||
IConsolePrint(CC_HELP, " add: add the given key to the authorized keys of the given type.");
|
||||
IConsolePrint(CC_HELP, " remove: remove the given key from the authorized keys of the given type; use 'all' to remove all authorized keys.");
|
||||
IConsolePrint(CC_HELP, "Instead of a key, use 'client:<id>' to add/remove the key of that given client.");
|
||||
|
||||
std::string buffer;
|
||||
for (auto [name, _] : _console_cmd_authorized_keys) fmt::format_to(std::back_inserter(buffer), ", {}", name);
|
||||
IConsolePrint(CC_HELP, "The supported types are: all{}.", buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool valid_type = false; ///< Whether a valid type was given.
|
||||
|
||||
for (auto [name, authorized_keys] : _console_cmd_authorized_keys) {
|
||||
if (!StrEqualsIgnoreCase(argv[2], name) && !StrEqualsIgnoreCase(argv[2], "all")) continue;
|
||||
|
||||
valid_type = true;
|
||||
|
||||
if (StrEqualsIgnoreCase(argv[1], "list")) {
|
||||
IConsolePrint(CC_WHITE, "The authorized keys for {} are:", name);
|
||||
for (auto &authorized_key : *authorized_keys) IConsolePrint(CC_INFO, " {}", authorized_key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc <= 3) {
|
||||
IConsolePrint(CC_ERROR, "You must enter the key.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string authorized_key = argv[3];
|
||||
if (StrStartsWithIgnoreCase(authorized_key, "client:")) {
|
||||
std::string id_string(authorized_key.substr(7));
|
||||
authorized_key = NetworkGetPublicKeyOfClient(static_cast<ClientID>(std::stoi(id_string)));
|
||||
if (authorized_key.empty()) {
|
||||
IConsolePrint(CC_ERROR, "You must enter a valid client id; see 'clients'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (StrEqualsIgnoreCase(argv[1], "add")) {
|
||||
if (authorized_keys->Add(authorized_key)) {
|
||||
IConsolePrint(CC_INFO, "Added {} to {}.", authorized_key, name);
|
||||
} else {
|
||||
IConsolePrint(CC_WARNING, "Not added {} to {} as it already exists.", authorized_key, name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StrEqualsIgnoreCase(argv[1], "remove")) {
|
||||
if (authorized_keys->Remove(authorized_key)) {
|
||||
IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name);
|
||||
} else {
|
||||
IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
IConsolePrint(CC_WARNING, "No valid action was given.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!valid_type) {
|
||||
IConsolePrint(CC_WARNING, "No valid type was given.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Content downloading only is available with ZLIB */
|
||||
#if defined(WITH_ZLIB)
|
||||
#include "network/network_content.h"
|
||||
@@ -2112,10 +2193,14 @@ DEF_CONSOLE_CMD(ConFont)
|
||||
IConsolePrint(CC_HELP, "Manage the fonts configuration.");
|
||||
IConsolePrint(CC_HELP, "Usage 'font'.");
|
||||
IConsolePrint(CC_HELP, " Print out the fonts configuration.");
|
||||
IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [<name>] [<size>] [aa|noaa]'.");
|
||||
IConsolePrint(CC_HELP, " The \"Currently active\" configuration is the one actually in effect (after interface scaling and replacing unavailable fonts).");
|
||||
IConsolePrint(CC_HELP, " The \"Requested\" configuration is the one requested via console command or config file.");
|
||||
IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [<font name>] [<size>] [aa|noaa]'.");
|
||||
IConsolePrint(CC_HELP, " Change the configuration for a font.");
|
||||
IConsolePrint(CC_HELP, " Omitting an argument will keep the current value.");
|
||||
IConsolePrint(CC_HELP, " Set <name> to \"\" for the sprite font (size and aa have no effect on sprite font).");
|
||||
IConsolePrint(CC_HELP, " Set <font name> to \"\" for the default font. Note that <size> and aa/noaa have no effect if the default font is in use, and fixed defaults are used instead.");
|
||||
IConsolePrint(CC_HELP, " If the sprite font is enabled in Game Options, it is used instead of the default font.");
|
||||
IConsolePrint(CC_HELP, " The <size> is automatically multiplied by the current interface scaling.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2133,7 +2218,7 @@ DEF_CONSOLE_CMD(ConFont)
|
||||
uint size = setting->size;
|
||||
bool aa = setting->aa;
|
||||
|
||||
byte arg_index = 2;
|
||||
uint8_t arg_index = 2;
|
||||
/* We may encounter "aa" or "noaa" but it must be the last argument. */
|
||||
if (StrEqualsIgnoreCase(argv[arg_index], "aa") || StrEqualsIgnoreCase(argv[arg_index], "noaa")) {
|
||||
aa = !StrStartsWithIgnoreCase(argv[arg_index++], "no");
|
||||
@@ -2173,7 +2258,9 @@ DEF_CONSOLE_CMD(ConFont)
|
||||
InitFontCache(fs == FS_MONO);
|
||||
fc = FontCache::Get(fs);
|
||||
}
|
||||
IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font, setting->size, setting->aa ? "aa" : "noaa");
|
||||
IConsolePrint(CC_DEFAULT, "{} font:", FontSizeToName(fs));
|
||||
IConsolePrint(CC_DEFAULT, "Currently active: \"{}\", size {}, {}", fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa");
|
||||
IConsolePrint(CC_DEFAULT, "Requested: \"{}\", size {}, {}", setting->font, setting->size, setting->aa ? "aa" : "noaa");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2743,6 +2830,9 @@ void IConsoleStdLibRegister()
|
||||
IConsole::CmdRegister("pause", ConPauseGame, ConHookServerOrNoNetwork);
|
||||
IConsole::CmdRegister("unpause", ConUnpauseGame, ConHookServerOrNoNetwork);
|
||||
|
||||
IConsole::CmdRegister("authorized_key", ConNetworkAuthorizedKey, ConHookServerOnly);
|
||||
IConsole::AliasRegister("ak", "authorized_key %+");
|
||||
|
||||
IConsole::CmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
|
||||
IConsole::AliasRegister("company_password", "company_pw %+");
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "textbuf_type.h"
|
||||
#include "window_gui.h"
|
||||
#include "autocompletion.h"
|
||||
#include "console_gui.h"
|
||||
#include "console_internal.h"
|
||||
#include "window_func.h"
|
||||
@@ -73,9 +74,44 @@ static std::deque<IConsoleLine> _iconsole_buffer;
|
||||
|
||||
static bool TruncateBuffer();
|
||||
|
||||
class ConsoleAutoCompletion final : public AutoCompletion {
|
||||
public:
|
||||
using AutoCompletion::AutoCompletion;
|
||||
|
||||
private:
|
||||
std::vector<std::string> GetSuggestions(std::string_view prefix, std::string_view query) override
|
||||
{
|
||||
prefix = StrTrimView(prefix);
|
||||
std::vector<std::string> suggestions;
|
||||
|
||||
/* We only suggest commands or aliases, so we only do it for the first token or an argument to help command. */
|
||||
if (!prefix.empty() && prefix != "help") {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
for (const auto &[_, command] : IConsole::Commands()) {
|
||||
if (command.name.starts_with(query)) {
|
||||
suggestions.push_back(command.name);
|
||||
}
|
||||
}
|
||||
for (const auto &[_, alias] : IConsole::Aliases()) {
|
||||
if (alias.name.starts_with(query)) {
|
||||
suggestions.push_back(alias.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
void ApplySuggestion(std::string_view prefix, std::string_view suggestion) override
|
||||
{
|
||||
this->textbuf->Assign(fmt::format("{}{} ", prefix, suggestion));
|
||||
}
|
||||
};
|
||||
|
||||
/* ** main console cmd buffer ** */
|
||||
static Textbuf _iconsole_cmdline(ICON_CMDLN_SIZE);
|
||||
static ConsoleAutoCompletion _iconsole_tab_completion(&_iconsole_cmdline);
|
||||
static std::deque<std::string> _iconsole_history;
|
||||
static ptrdiff_t _iconsole_historypos;
|
||||
IConsoleModes _iconsole_mode;
|
||||
@@ -91,6 +127,7 @@ static void IConsoleClearCommand()
|
||||
_iconsole_cmdline.pixels = 0;
|
||||
_iconsole_cmdline.caretpos = 0;
|
||||
_iconsole_cmdline.caretxoffs = 0;
|
||||
_iconsole_tab_completion.Reset();
|
||||
SetWindowDirty(WC_CONSOLE, 0);
|
||||
}
|
||||
|
||||
@@ -107,7 +144,7 @@ static constexpr NWidgetPart _nested_console_window_widgets[] = {
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_BACKGROUND), SetResize(1, 1),
|
||||
};
|
||||
|
||||
static WindowDesc _console_window_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _console_window_desc(
|
||||
WDP_MANUAL, nullptr, 0, 0,
|
||||
WC_CONSOLE, WC_NONE,
|
||||
0,
|
||||
@@ -274,8 +311,18 @@ struct IConsoleWindow : Window
|
||||
IConsoleCmdExec("clear");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (_iconsole_cmdline.HandleKeyPress(key, keycode) != HKPR_NOT_HANDLED) {
|
||||
case WKC_TAB:
|
||||
if (_iconsole_tab_completion.AutoComplete()) {
|
||||
this->SetDirty();
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
HandleKeyPressResult handle_result = _iconsole_cmdline.HandleKeyPress(key, keycode);
|
||||
if (handle_result != HKPR_NOT_HANDLED) {
|
||||
if (handle_result == HKPR_EDITING) {
|
||||
_iconsole_tab_completion.Reset();
|
||||
}
|
||||
IConsoleWindow::scroll = 0;
|
||||
IConsoleResetHistoryPos();
|
||||
this->SetDirty();
|
||||
@@ -283,6 +330,7 @@ struct IConsoleWindow : Window
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ES_HANDLED;
|
||||
}
|
||||
@@ -290,13 +338,14 @@ struct IConsoleWindow : Window
|
||||
void InsertTextString(WidgetID, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
|
||||
{
|
||||
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
|
||||
_iconsole_tab_completion.Reset();
|
||||
IConsoleWindow::scroll = 0;
|
||||
IConsoleResetHistoryPos();
|
||||
this->SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
Textbuf *GetFocusedTextbuf() const override
|
||||
const Textbuf *GetFocusedTextbuf() const override
|
||||
{
|
||||
return &_iconsole_cmdline;
|
||||
}
|
||||
@@ -397,14 +446,15 @@ void IConsoleSwitch()
|
||||
#ifdef __ANDROID__
|
||||
{
|
||||
char buf[1024] = "";
|
||||
char *pos = &buf[0];
|
||||
|
||||
//for (const IConsoleLine *print = IConsoleLine::Get(0); print != NULL; print = print->previous) {
|
||||
for (IConsoleLine &line : _iconsole_buffer) {
|
||||
if (!line.buffer.empty()) {
|
||||
pos = fmt::format_to(pos, "{}\n", line.buffer);
|
||||
strecat(buf, line.buffer.c_str(), lastof(buf));
|
||||
strecat(buf, "\n", lastof(buf));
|
||||
}
|
||||
}
|
||||
pos = fmt::format_to(pos, "\n\n\n\n\n\n\n\n");
|
||||
strecat(buf, "\n\n\n\n\n\n\n\n", lastof(buf)); // Move all text to top
|
||||
SDL_ANDROID_SetScreenKeyboardHintMesage(buf);
|
||||
char text[512] = "";
|
||||
SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); /* Invoke Android built-in screen keyboard */
|
||||
@@ -468,6 +518,7 @@ static void IConsoleHistoryNavigate(int direction)
|
||||
} else {
|
||||
_iconsole_cmdline.Assign(_iconsole_history[_iconsole_historypos]);
|
||||
}
|
||||
_iconsole_tab_completion.Reset();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,8 +578,8 @@ bool IsValidConsoleColour(TextColour c)
|
||||
/* A text colour from the palette is used; must be the company
|
||||
* colour gradient, so it must be one of those. */
|
||||
c &= ~TC_IS_PALETTE_COLOUR;
|
||||
for (uint i = COLOUR_BEGIN; i < COLOUR_END; i++) {
|
||||
if (_colour_gradient[i][4] == c) return true;
|
||||
for (Colours i = COLOUR_BEGIN; i < COLOUR_END; i++) {
|
||||
if (GetColourGradient(i, SHADE_NORMAL) == c) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -30,7 +30,7 @@ enum ConsoleHookResult {
|
||||
* If you want to handle multiple words as one, enclose them in double-quotes
|
||||
* eg. 'say "hello everybody"'
|
||||
*/
|
||||
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
|
||||
typedef bool IConsoleCmdProc(uint8_t argc, char *argv[]);
|
||||
typedef ConsoleHookResult IConsoleHook(bool echo);
|
||||
struct IConsoleCmd {
|
||||
IConsoleCmd(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook) : name(name), proc(proc), hook(hook) {}
|
||||
|
||||
@@ -93,14 +93,14 @@ public:
|
||||
* @param size the amount of bytes to allocate.
|
||||
* @return the given amounts of bytes zeroed.
|
||||
*/
|
||||
inline void *operator new(size_t size) { return CallocT<byte>(size); }
|
||||
inline void *operator new(size_t size) { return CallocT<uint8_t>(size); }
|
||||
|
||||
/**
|
||||
* Memory allocator for an array of class instances.
|
||||
* @param size the amount of bytes to allocate.
|
||||
* @return the given amounts of bytes zeroed.
|
||||
*/
|
||||
inline void *operator new[](size_t size) { return CallocT<byte>(size); }
|
||||
inline void *operator new[](size_t size) { return CallocT<uint8_t>(size); }
|
||||
|
||||
/**
|
||||
* Memory release for a single class instance.
|
||||
|
||||
@@ -22,20 +22,18 @@ struct Backup {
|
||||
/**
|
||||
* Backup variable.
|
||||
* @param original Variable to backup.
|
||||
* @param file Filename for debug output. Use FILE_LINE macro.
|
||||
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
||||
* @param location Source location for debug output.
|
||||
*/
|
||||
Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {}
|
||||
Backup(T &original, const std::source_location location = std::source_location::current()) : original(original), valid(true), original_value(original), location(location) {}
|
||||
|
||||
/**
|
||||
* Backup variable and switch to new value.
|
||||
* @param original Variable to backup.
|
||||
* @param new_value New value for variable.
|
||||
* @param file Filename for debug output. Use FILE_LINE macro.
|
||||
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
||||
* @param location Source location for debug output.
|
||||
*/
|
||||
template <typename U>
|
||||
Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line)
|
||||
Backup(T &original, const U &new_value, const std::source_location location = std::source_location::current()) : original(original), valid(true), original_value(original), location(location)
|
||||
{
|
||||
/* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
|
||||
original = new_value;
|
||||
@@ -51,7 +49,7 @@ struct Backup {
|
||||
{
|
||||
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
|
||||
* Exceptions are especially used to abort world generation. */
|
||||
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->file, this->line);
|
||||
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->location.file_name(), this->location.line());
|
||||
this->Restore();
|
||||
}
|
||||
}
|
||||
@@ -140,8 +138,7 @@ private:
|
||||
bool valid;
|
||||
T original_value;
|
||||
|
||||
const char * const file;
|
||||
const int line;
|
||||
const std::source_location location;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,7 +46,7 @@ inline void MemMoveT(T *destination, const T *source, size_t num = 1)
|
||||
* @param num number of items to be set (!not number of bytes!)
|
||||
*/
|
||||
template <typename T>
|
||||
inline void MemSetT(T *ptr, byte value, size_t num = 1)
|
||||
inline void MemSetT(T *ptr, uint8_t value, size_t num = 1)
|
||||
{
|
||||
memset(ptr, value, num * sizeof(T));
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const uint16_t factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const uint8_t factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||
|
||||
/* Operators for division. */
|
||||
inline constexpr OverflowSafeInt& operator /= (const int64_t divisor) { this->m_value /= divisor; return *this; }
|
||||
@@ -200,10 +200,10 @@ template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint a
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const byte a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const byte a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const byte a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const byte a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const uint8_t a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const uint8_t a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint8_t a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint8_t a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
typedef OverflowSafeInt<int64_t> OverflowSafeInt64;
|
||||
typedef OverflowSafeInt<int32_t> OverflowSafeInt32;
|
||||
|
||||
@@ -123,9 +123,9 @@ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
|
||||
memset((void *)item, 0, sizeof(Titem));
|
||||
}
|
||||
} else if (Tzero) {
|
||||
item = (Titem *)CallocT<byte>(size);
|
||||
item = (Titem *)CallocT<uint8_t>(size);
|
||||
} else {
|
||||
item = (Titem *)MallocT<byte>(size);
|
||||
item = (Titem *)MallocT<uint8_t>(size);
|
||||
}
|
||||
this->data[index] = item;
|
||||
SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
|
||||
|
||||
@@ -49,17 +49,6 @@ uint32_t Randomizer::Next()
|
||||
return this->state[1] = std::rotr(s, 3) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the next pseudo random number scaled to \a limit, excluding \a limit
|
||||
* itself.
|
||||
* @param limit Limit of the range to be generated from.
|
||||
* @return Random number in [0,\a limit)
|
||||
*/
|
||||
uint32_t Randomizer::Next(uint32_t limit)
|
||||
{
|
||||
return ((uint64_t)this->Next() * (uint64_t)limit) >> 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)set the state of the random number generator.
|
||||
* @param seed the new state
|
||||
@@ -81,19 +70,14 @@ void SetRandomSeed(uint32_t seed)
|
||||
}
|
||||
|
||||
#ifdef RANDOM_DEBUG
|
||||
uint32_t DoRandom(int line, const char *file)
|
||||
uint32_t Random(const std::source_location location)
|
||||
{
|
||||
if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
|
||||
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", TimerGameEconomy::date, TimerGameEconomy::date_fract, _frame_counter, (byte)_current_company, file, line);
|
||||
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", TimerGameEconomy::date, TimerGameEconomy::date_fract, _frame_counter, (uint8_t)_current_company, location.file_name(), location.line());
|
||||
}
|
||||
|
||||
return _random.Next();
|
||||
}
|
||||
|
||||
uint32_t DoRandomRange(uint32_t limit, int line, const char *file)
|
||||
{
|
||||
return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32;
|
||||
}
|
||||
#endif /* RANDOM_DEBUG */
|
||||
|
||||
/**
|
||||
@@ -113,7 +97,7 @@ 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__) || defined(__OpenBSD__)
|
||||
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
arc4random_buf(buf.data(), buf.size());
|
||||
return;
|
||||
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
|
||||
|
||||
@@ -10,10 +10,16 @@
|
||||
#ifndef RANDOM_FUNC_HPP
|
||||
#define RANDOM_FUNC_HPP
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Apple already has Random declared */
|
||||
# define Random OTTD_Random
|
||||
#endif /* __APPLE__ */
|
||||
/**
|
||||
* Scale a uint32_t number to be within the range [0,\a limit).
|
||||
* @param value The value to scale.
|
||||
* @param limit The limit to scale to.
|
||||
* @return The scaled value.
|
||||
*/
|
||||
static constexpr uint32_t ScaleToLimit(uint32_t value, uint32_t limit)
|
||||
{
|
||||
return ((uint64_t)value * (uint64_t)limit) >> 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure to encapsulate the pseudo random number generators.
|
||||
@@ -23,8 +29,15 @@ struct Randomizer {
|
||||
uint32_t state[2];
|
||||
|
||||
uint32_t Next();
|
||||
uint32_t Next(uint32_t limit);
|
||||
void SetSeed(uint32_t seed);
|
||||
|
||||
/**
|
||||
* Generate the next pseudo random number scaled to \a limit, excluding \a limit
|
||||
* itself.
|
||||
* @param limit Limit of the range to be generated from.
|
||||
* @return Random number in [0,\a limit)
|
||||
*/
|
||||
inline uint32_t Next(uint32_t limit) { return ScaleToLimit(this->Next(), limit); }
|
||||
};
|
||||
extern Randomizer _random; ///< Random used in the game state calculations
|
||||
extern Randomizer _interactive_random; ///< Random used everywhere else, where it does not (directly) influence the game state
|
||||
@@ -57,33 +70,26 @@ inline void RestoreRandomSeeds(const SavedRandomSeeds &storage)
|
||||
|
||||
void SetRandomSeed(uint32_t seed);
|
||||
#ifdef RANDOM_DEBUG
|
||||
# ifdef __APPLE__
|
||||
# define OTTD_Random() DoRandom(__LINE__, __FILE__)
|
||||
# else
|
||||
# define Random() DoRandom(__LINE__, __FILE__)
|
||||
# endif
|
||||
uint32_t DoRandom(int line, const char *file);
|
||||
# define RandomRange(limit) DoRandomRange(limit, __LINE__, __FILE__)
|
||||
uint32_t DoRandomRange(uint32_t limit, int line, const char *file);
|
||||
uint32_t Random(const std::source_location location = std::source_location::current());
|
||||
#else
|
||||
static inline uint32_t Random()
|
||||
inline uint32_t Random([[maybe_unused]] const std::source_location location = std::source_location::current())
|
||||
{
|
||||
return _random.Next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a random number between 0 and \a limit - 1, inclusive. That means 0
|
||||
* can be returned and \a limit - 1 can be returned, but \a limit can not be
|
||||
* returned.
|
||||
* @param limit Limit for the range to be picked from.
|
||||
* @return A random number in [0,\a limit).
|
||||
*/
|
||||
static inline uint32_t RandomRange(uint32_t limit)
|
||||
{
|
||||
return _random.Next(limit);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pick a random number between 0 and \a limit - 1, inclusive. That means 0
|
||||
* can be returned and \a limit - 1 can be returned, but \a limit can not be
|
||||
* returned.
|
||||
* @param limit Limit for the range to be picked from.
|
||||
* @return A random number in [0,\a limit).
|
||||
*/
|
||||
inline uint32_t RandomRange(uint32_t limit, const std::source_location location = std::source_location::current())
|
||||
{
|
||||
return ScaleToLimit(Random(location), limit);
|
||||
}
|
||||
|
||||
inline uint32_t InteractiveRandom()
|
||||
{
|
||||
return _interactive_random.Next();
|
||||
@@ -109,7 +115,7 @@ inline uint32_t InteractiveRandomRange(uint32_t limit)
|
||||
* @param r The given randomize-number
|
||||
* @return True if the probability given by r is less or equal to (a/b)
|
||||
*/
|
||||
inline bool Chance16I(const uint a, const uint b, const uint32_t r)
|
||||
inline bool Chance16I(const uint32_t a, const uint32_t b, const uint32_t r)
|
||||
{
|
||||
assert(b != 0);
|
||||
return (((uint16_t)r * b + b / 2) >> 16) < a;
|
||||
@@ -125,14 +131,10 @@ inline bool Chance16I(const uint a, const uint b, const uint32_t r)
|
||||
* @param b The denominator of the fraction
|
||||
* @return True with (a/b) probability
|
||||
*/
|
||||
#ifdef RANDOM_DEBUG
|
||||
# define Chance16(a, b) Chance16I(a, b, DoRandom(__LINE__, __FILE__))
|
||||
#else
|
||||
inline bool Chance16(const uint a, const uint b)
|
||||
inline bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location = std::source_location::current())
|
||||
{
|
||||
return Chance16I(a, b, Random());
|
||||
return Chance16I(a, b, Random(location));
|
||||
}
|
||||
#endif /* RANDOM_DEBUG */
|
||||
|
||||
/**
|
||||
* Flips a coin with a given probability and saves the randomize-number in a variable.
|
||||
@@ -149,15 +151,11 @@ inline bool Chance16(const uint a, const uint b)
|
||||
* @param r The variable to save the randomize-number from Random()
|
||||
* @return True in (a/b) percent
|
||||
*/
|
||||
#ifdef RANDOM_DEBUG
|
||||
# define Chance16R(a, b, r) (r = DoRandom(__LINE__, __FILE__), Chance16I(a, b, r))
|
||||
#else
|
||||
inline bool Chance16R(const uint a, const uint b, uint32_t &r)
|
||||
inline bool Chance16R(const uint32_t a, const uint32_t b, uint32_t &r, const std::source_location location = std::source_location::current())
|
||||
{
|
||||
r = Random();
|
||||
r = Random(location);
|
||||
return Chance16I(a, b, r);
|
||||
}
|
||||
#endif /* RANDOM_DEBUG */
|
||||
|
||||
void RandomBytesWithFallback(std::span<uint8_t> buf);
|
||||
|
||||
|
||||
@@ -56,11 +56,12 @@ static void SurveyRecentNews(nlohmann::json &json)
|
||||
json = nlohmann::json::array();
|
||||
|
||||
int i = 0;
|
||||
for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) {
|
||||
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news->date);
|
||||
for (const auto &news : GetNews()) {
|
||||
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news.date);
|
||||
json.push_back(fmt::format("({}-{:02}-{:02}) StringID: {}, Type: {}, Ref1: {}, {}, Ref2: {}, {}",
|
||||
ymd.year, ymd.month + 1, ymd.day, news->string_id, news->type,
|
||||
news->reftype1, news->ref1, news->reftype2, news->ref2));
|
||||
ymd.year, ymd.month + 1, ymd.day, news.string_id, news.type,
|
||||
news.reftype1, news.ref1, news.reftype2, news.ref2));
|
||||
if (++i > 32) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* | | Euro year | | | | name
|
||||
* | | | | | | | | */
|
||||
/** The original currency specifications. */
|
||||
static const CurrencySpec origin_currency_specs[CURRENCY_END] = {
|
||||
static const std::array<CurrencySpec, CURRENCY_END> origin_currency_specs = {{
|
||||
{ 1, "", CF_NOEURO, "\u00a3", "", "GBP", 0, STR_GAME_OPTIONS_CURRENCY_GBP }, ///< british pound
|
||||
{ 2, "", CF_NOEURO, "$", "", "USD", 0, STR_GAME_OPTIONS_CURRENCY_USD }, ///< american dollar
|
||||
{ 2, "", CF_ISEURO, "\u20ac", "", "EUR", 0, STR_GAME_OPTIONS_CURRENCY_EUR }, ///< euro
|
||||
@@ -70,10 +70,11 @@ static const CurrencySpec origin_currency_specs[CURRENCY_END] = {
|
||||
{ 19, "", CF_NOEURO, "Rp", "", "IDR", 0, STR_GAME_OPTIONS_CURRENCY_IDR }, ///< Indonesian Rupiah
|
||||
{ 5, "", CF_NOEURO, "RM", "", "MYR", 0, STR_GAME_OPTIONS_CURRENCY_MYR }, ///< Malaysian Ringgit
|
||||
{ 1, "", 2014, "", NBSP "Ls", "LVL", 1, STR_GAME_OPTIONS_CURRENCY_LVL }, ///< latvian lats
|
||||
};
|
||||
{ 400, "", 2002, "", "$00", "PTE", 1, STR_GAME_OPTIONS_CURRENCY_PTE }, ///< portuguese escudo
|
||||
}};
|
||||
|
||||
/** Array of currencies used by the system */
|
||||
CurrencySpec _currency_specs[CURRENCY_END];
|
||||
std::array<CurrencySpec, CURRENCY_END> _currency_specs;
|
||||
|
||||
/**
|
||||
* This array represent the position of OpenTTD's currencies,
|
||||
@@ -81,7 +82,7 @@ CurrencySpec _currency_specs[CURRENCY_END];
|
||||
* When a grf sends currencies, they are based on the order defined by TTDPatch.
|
||||
* So, we must reindex them to our own order.
|
||||
*/
|
||||
const byte TTDPatch_To_OTTDIndex[] =
|
||||
const uint8_t TTDPatch_To_OTTDIndex[] =
|
||||
{
|
||||
CURRENCY_GBP,
|
||||
CURRENCY_USD,
|
||||
@@ -112,7 +113,7 @@ const byte TTDPatch_To_OTTDIndex[] =
|
||||
* @param grfcurr_id currency id coming from newgrf
|
||||
* @return the corrected index
|
||||
*/
|
||||
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
|
||||
uint8_t GetNewgrfCurrencyIdConverted(uint8_t grfcurr_id)
|
||||
{
|
||||
return (grfcurr_id >= lengthof(TTDPatch_To_OTTDIndex)) ? grfcurr_id : TTDPatch_To_OTTDIndex[grfcurr_id];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define CURRENCY_H
|
||||
|
||||
#include "timer/timer_game_calendar.h"
|
||||
#include "string_func.h"
|
||||
#include "settings_type.h"
|
||||
#include "strings_type.h"
|
||||
|
||||
static constexpr TimerGameCalendar::Year CF_NOEURO = 0; ///< Currency never switches to the Euro (as far as known).
|
||||
@@ -67,6 +67,7 @@ enum Currencies {
|
||||
CURRENCY_IDR, ///< Indonesian Rupiah
|
||||
CURRENCY_MYR, ///< Malaysian Ringgit
|
||||
CURRENCY_LVL, ///< Latvian Lats
|
||||
CURRENCY_PTE, ///< Portuguese Escudo
|
||||
CURRENCY_END, ///< always the last item
|
||||
};
|
||||
|
||||
@@ -87,25 +88,39 @@ struct CurrencySpec {
|
||||
* It is not a spec from Newgrf,
|
||||
* rather a way to let users do what they want with custom currency
|
||||
*/
|
||||
byte symbol_pos;
|
||||
uint8_t symbol_pos;
|
||||
StringID name;
|
||||
|
||||
CurrencySpec() = default;
|
||||
|
||||
CurrencySpec(uint16_t rate, const char *separator, TimerGameCalendar::Year to_euro, const char *prefix, const char *suffix, const char *code, byte symbol_pos, StringID name) :
|
||||
CurrencySpec(uint16_t rate, const char *separator, TimerGameCalendar::Year to_euro, const char *prefix, const char *suffix, const char *code, uint8_t symbol_pos, StringID name) :
|
||||
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), code(code), symbol_pos(symbol_pos), name(name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
extern CurrencySpec _currency_specs[CURRENCY_END];
|
||||
extern std::array<CurrencySpec, CURRENCY_END> _currency_specs;
|
||||
|
||||
/* XXX small hack, but makes the rest of the code a bit nicer to read */
|
||||
#define _custom_currency (_currency_specs[CURRENCY_CUSTOM])
|
||||
#define _currency ((const CurrencySpec*)&_currency_specs[GetGameSettings().locale.currency])
|
||||
/**
|
||||
* Get the custom currency.
|
||||
* @return Reference to custom currency.
|
||||
*/
|
||||
inline CurrencySpec &GetCustomCurrency()
|
||||
{
|
||||
return _currency_specs[CURRENCY_CUSTOM];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently selected currency.
|
||||
* @return Read-only reference to the current currency.
|
||||
*/
|
||||
inline const CurrencySpec &GetCurrency()
|
||||
{
|
||||
return _currency_specs[GetGameSettings().locale.currency];
|
||||
}
|
||||
|
||||
uint64_t GetMaskOfAllowedCurrencies();
|
||||
void ResetCurrencies(bool preserve_custom = true);
|
||||
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id);
|
||||
uint8_t GetNewgrfCurrencyIdConverted(uint8_t grfcurr_id);
|
||||
|
||||
#endif /* CURRENCY_H */
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
#include "window_gui.h"
|
||||
#include "date_gui.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "dropdown_type.h"
|
||||
#include "dropdown_func.h"
|
||||
|
||||
#include "widgets/dropdown_type.h"
|
||||
#include "widgets/date_widget.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
@@ -75,14 +76,14 @@ struct SetDateWindow : Window {
|
||||
|
||||
case WID_SD_DAY:
|
||||
for (uint i = 0; i < 31; i++) {
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_DAY_NUMBER_1ST + i, i + 1, false));
|
||||
list.push_back(MakeDropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1));
|
||||
}
|
||||
selected = this->date.day;
|
||||
break;
|
||||
|
||||
case WID_SD_MONTH:
|
||||
for (uint i = 0; i < 12; i++) {
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_MONTH_JAN + i, i, false));
|
||||
list.push_back(MakeDropDownListStringItem(STR_MONTH_JAN + i, i));
|
||||
}
|
||||
selected = this->date.month;
|
||||
break;
|
||||
@@ -90,7 +91,7 @@ struct SetDateWindow : Window {
|
||||
case WID_SD_YEAR:
|
||||
for (TimerGameEconomy::Year i = this->min_year; i <= this->max_year; i++) {
|
||||
SetDParam(0, i);
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_INT, i.base(), false));
|
||||
list.push_back(MakeDropDownListStringItem(STR_JUST_INT, i.base()));
|
||||
}
|
||||
selected = this->date.year.base();
|
||||
break;
|
||||
@@ -195,7 +196,7 @@ static constexpr NWidgetPart _nested_set_date_widgets[] = {
|
||||
};
|
||||
|
||||
/** Description of the date setting window. */
|
||||
static WindowDesc _set_date_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _set_date_desc(
|
||||
WDP_CENTER, nullptr, 0, 0,
|
||||
WC_SET_DATE, WC_NONE,
|
||||
0,
|
||||
|
||||
@@ -117,7 +117,7 @@ void DebugPrint(const char *category, int level, const std::string &message)
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "OpenTTD", "[%s] %s", level, message.c_str());
|
||||
#endif
|
||||
if (strcmp(category, "desync") == 0 && level != 0) {
|
||||
if (strcmp(category, "desync") == 0) {
|
||||
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == nullptr) return;
|
||||
|
||||
|
||||
@@ -60,9 +60,6 @@ void DumpDebugFacilityNames(std::back_insert_iterator<std::string> &output_itera
|
||||
void SetDebugString(const char *s, void (*error_func)(const std::string &));
|
||||
std::string GetDebugString();
|
||||
|
||||
/* Shorter form for passing filename and linenumber */
|
||||
#define FILE_LINE __FILE__, __LINE__
|
||||
|
||||
/** TicToc profiling.
|
||||
* Usage:
|
||||
* static TicToc::State state("A name", 1);
|
||||
|
||||
@@ -85,28 +85,28 @@ static constexpr NWidgetPart _nested_train_depot_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _train_depot_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _train_depot_desc(
|
||||
WDP_AUTO, "depot_train", 362, 123,
|
||||
WC_VEHICLE_DEPOT, WC_NONE,
|
||||
0,
|
||||
std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
|
||||
);
|
||||
|
||||
static WindowDesc _road_depot_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _road_depot_desc(
|
||||
WDP_AUTO, "depot_roadveh", 316, 97,
|
||||
WC_VEHICLE_DEPOT, WC_NONE,
|
||||
0,
|
||||
std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
|
||||
);
|
||||
|
||||
static WindowDesc _ship_depot_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _ship_depot_desc(
|
||||
WDP_AUTO, "depot_ship", 306, 99,
|
||||
WC_VEHICLE_DEPOT, WC_NONE,
|
||||
0,
|
||||
std::begin(_nested_train_depot_widgets), std::end(_nested_train_depot_widgets)
|
||||
);
|
||||
|
||||
static WindowDesc _aircraft_depot_desc(__FILE__, __LINE__,
|
||||
static WindowDesc _aircraft_depot_desc(
|
||||
WDP_AUTO, "depot_aircraft", 332, 99,
|
||||
WC_VEHICLE_DEPOT, WC_NONE,
|
||||
0,
|
||||
@@ -384,7 +384,7 @@ struct DepotWindow : Window {
|
||||
*/
|
||||
if (this->type == VEH_TRAIN && _consistent_train_width != 0) {
|
||||
int w = ScaleSpriteTrad(2 * _consistent_train_width);
|
||||
int col = _colour_gradient[wid->colour][4];
|
||||
int col = GetColourGradient(wid->colour, SHADE_NORMAL);
|
||||
Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
|
||||
int first_line = w + (-this->hscroll->GetPosition()) % w;
|
||||
if (rtl) {
|
||||
@@ -459,10 +459,10 @@ struct DepotWindow : Window {
|
||||
}
|
||||
ym = (y - matrix_widget->pos_y) % this->resize.step_height;
|
||||
|
||||
int row = this->vscroll->GetScrolledRowFromWidget(y, this, WID_D_MATRIX);
|
||||
int32_t row = this->vscroll->GetScrolledRowFromWidget(y, this, WID_D_MATRIX);
|
||||
uint pos = (row * this->num_columns) + xt;
|
||||
|
||||
if (row == INT_MAX || this->vehicle_list.size() + this->wagon_list.size() <= pos) {
|
||||
if (row == INT32_MAX || this->vehicle_list.size() + this->wagon_list.size() <= pos) {
|
||||
/* Clicking on 'line' / 'block' without a vehicle */
|
||||
if (this->type == VEH_TRAIN) {
|
||||
/* End the dragging */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* your viewport and not rotated by 45 degrees left or right to get
|
||||
* a "north" used in you games.
|
||||
*/
|
||||
enum Direction : byte {
|
||||
enum Direction : uint8_t {
|
||||
DIR_BEGIN = 0, ///< Used to iterate
|
||||
DIR_N = 0, ///< North
|
||||
DIR_NE = 1, ///< Northeast
|
||||
@@ -70,7 +70,7 @@ enum DirDiff {
|
||||
*
|
||||
* This enumeration is used for the 4 direction of the tile-edges.
|
||||
*/
|
||||
enum DiagDirection : byte {
|
||||
enum DiagDirection : uint8_t {
|
||||
DIAGDIR_BEGIN = 0, ///< Used for iterations
|
||||
DIAGDIR_NE = 0, ///< Northeast, upper right on your monitor
|
||||
DIAGDIR_SE = 1, ///< Southeast
|
||||
@@ -113,7 +113,7 @@ DECLARE_POSTFIX_INCREMENT(DiagDirDiff)
|
||||
* (and south-east edge). The Y axis must be so the one which goes
|
||||
* align the north-east edge (and south-west) edge.
|
||||
*/
|
||||
enum Axis : byte {
|
||||
enum Axis : uint8_t {
|
||||
AXIS_X = 0, ///< The X axis
|
||||
AXIS_Y = 1, ///< The y axis
|
||||
AXIS_END, ///< Used for iterations
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user