Compare commits

..

No commits in common. 'jgrpp' and 'jgrpp-0.58.0' have entirely different histories.

@ -14,7 +14,3 @@ notifications:
pull-request:
issue:
tag-created:
workflow-run:
only:
- .github/workflows/release.yml
- .github/workflows/ci-nightly.yml

@ -1,4 +1,4 @@
name: CI - Build
name: CI
on:
pull_request:
@ -22,22 +22,87 @@ jobs:
emscripten:
name: Emscripten
uses: ./.github/workflows/ci-emscripten.yml
secrets: inherit
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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) -t openttd
echo "::endgroup::"
linux:
strategy:
fail-fast: false
matrix:
include:
- name: Clang
- name: Clang - Debug
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++
@ -47,57 +112,338 @@ jobs:
name: Linux (${{ matrix.name }})
uses: ./.github/workflows/ci-linux.yml
secrets: inherit
runs-on: ubuntu-latest
env:
CC: ${{ matrix.compiler }}
CXX: ${{ matrix.cxxcompiler }}
steps:
- name: Checkout
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
with:
compiler: ${{ matrix.compiler }}
cxxcompiler: ${{ matrix.cxxcompiler }}
libraries: ${{ matrix.libraries }}
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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 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 \
libzstd-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 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 .. ${{ matrix.extra-cmake-parameters }}
echo "::endgroup::"
echo "::group::Build"
echo "Running on $(nproc) cores"
cmake --build . -j $(nproc) -t all openttd_test
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
macos:
strategy:
fail-fast: false
matrix:
include:
- 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
- arch: x64
full_arch: x86_64
name: Mac OS (${{ matrix.arch }})
runs-on: macos-latest
env:
MACOSX_DEPLOYMENT_TARGET: 10.13
name: Mac OS (${{ matrix.name }})
steps:
- name: Checkout
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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 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::"
uses: ./.github/workflows/ci-macos.yml
secrets: inherit
rm -f opengfx-all.zip
with:
arch: ${{ matrix.arch }}
full_arch: ${{ matrix.full_arch }}
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
- 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=/usr/local/share/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) -t all openttd_test
echo "::endgroup::"
- name: Test
run: |
cd build
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120
windows:
strategy:
fail-fast: false
matrix:
os: [windows-latest, windows-2019]
arch: [x86, x64]
name: Windows (${{ matrix.os }} / ${{ matrix.arch }})
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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 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
run: |
mkdir build
cd build
echo "::group::CMake"
cmake .. \
-GNinja \
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
# EOF
echo "::endgroup::"
echo "::group::Build"
cmake --build . -t all openttd_test
echo "::endgroup::"
- name: Test
shell: bash
run: |
cd build
ctest --timeout 120
msys2:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
arch: x86
- os: windows-latest
arch: x64
- msystem: MINGW64
arch: x86_64
- msystem: MINGW32
arch: i686
name: MinGW (${{ matrix.arch }})
runs-on: windows-latest
steps:
- name: Checkout
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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
- 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}
run: |
mkdir build
cd build
name: Windows (${{ matrix.arch }})
echo "::group::CMake"
cmake .. -DOPTION_NO_WARN_UNINIT=1 -G"MSYS Makefiles"
echo "::endgroup::"
uses: ./.github/workflows/ci-windows.yml
secrets: inherit
echo "::group::Build"
echo "Running on $(nproc) cores"
cmake --build . -j $(nproc) -t all openttd_test
echo "::endgroup::"
with:
os: ${{ matrix.os }}
arch: ${{ matrix.arch }}
- name: Test
shell: msys2 {0}
run: |
cd build
ctest --timeout 120
check_annotations:
name: Check Annotations
@ -106,6 +452,7 @@ jobs:
- linux
- macos
- windows
- msys2
if: always() && github.event_name == 'pull_request'

@ -1,69 +0,0 @@
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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::"

@ -1,131 +0,0 @@
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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 \
libzstd-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) --target all openttd_test
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

@ -1,97 +0,0 @@
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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) --target all openttd_test
echo "::endgroup::"
- name: Test
run: |
cd build
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120

@ -1,91 +0,0 @@
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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" \
-DOPTION_NO_WARN_UNINIT=1 \
# EOF
echo "::endgroup::"
echo "::group::Build"
cmake --build . --target all openttd_test
echo "::endgroup::"
- name: Test
shell: msys2 {0}
run: |
cd build
ctest --timeout 120

@ -1,84 +0,0 @@
name: CI - Nightly
on:
workflow_dispatch:
inputs:
ref:
description: 'Ref to build (for Pull Requests, use refs/pull/NNN/head)'
required: true
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

@ -1,94 +0,0 @@
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
if: github.event_name != 'workflow_dispatch'
uses: actions/checkout@v4
- name: Checkout (Manual)
if: github.event_name == 'workflow_dispatch'
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- 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 . --target all openttd_test
echo "::endgroup::"
- name: Test
shell: bash
run: |
cd build
ctest --timeout 120

@ -38,19 +38,6 @@ jobs:
with:
ref: ${{ github.event.inputs.ref }}
- 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"
@ -69,28 +56,13 @@ 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: Prepare build
- name: Set number of make jobs
run: |
mkdir build
cd build
echo "::group::CMake"
cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake
echo "::endgroup::"
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
@ -98,14 +70,8 @@ jobs:
languages: cpp
config-file: ./.github/codeql/codeql-config.yml
- name: Build
run: |
cd build
echo "::group::Build"
echo "Running on $(nproc) cores"
cmake --build . -j $(nproc)
echo "::endgroup::"
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

@ -7,7 +7,6 @@ on:
- synchronize
branches:
- master
- release/**
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}

@ -14,14 +14,14 @@ jobs:
runs-on: ubuntu-latest
container:
# manylinux_2_28 is based on AlmaLinux 8, and already has a lot of things
# manylinux2014 is based on CentOS 7, and already has a lot of things
# installed and preconfigured. It makes it easier to build OpenTTD.
# This distro is based on glibc 2.28, released in 2018.
image: quay.io/pypa/manylinux_2_28_x86_64
# This distro is based on glibc 2.17, released in 2012.
image: quay.io/pypa/manylinux2014_x86_64
steps:
- name: Download source
uses: actions/download-artifact@v4
uses: actions/download-artifact@v3
with:
name: internal-source
@ -29,14 +29,34 @@ jobs:
run: |
tar -xf source.tar.gz --strip-components=1
# curl is too old for most of the tools to work properly. For example,
# rust-toolchain doesn't work properly, neither vcpkg caching.
# The easier solution here is to upgrade curl.
- name: Update curl
run: |
yum install -y \
openssl-devel \
# EOF
mkdir /curl
cd /curl
curl -o curl-7.81.0.zip https://curl.se/download/curl-7.81.0.zip
unzip curl-7.81.0.zip
cd curl-7.81.0
./configure --with-ssl --with-zlib --prefix=/usr --libdir=/usr/lib64
make -j $(nproc)
make install
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Enable Rust cache
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@v2.7.0
with:
key: dedicated
- name: Setup vcpkg caching
uses: actions/github-script@v7
uses: actions/github-script@v6
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
@ -62,6 +82,15 @@ jobs:
cp /usr/share/aclocal/* /usr/local/share/aclocal/
echo "::endgroup::"
# The container we use is old enough, that it doesn't know SHF_COMPRESSED.
# But, breakpad needs this symbol to exist. So we patch it in our system
# libraries.
(
cd /
patch -p1 < ${GITHUB_WORKSPACE}/os/linux/shf-compressed.patch
)
echo "::endgroup::"
# We use vcpkg for our dependencies, to get more up-to-date version.
echo "::group::Install vcpkg and dependencies"
@ -72,6 +101,17 @@ jobs:
./bootstrap-vcpkg.sh -disableMetrics
)
# Make Python3 available for other packages. This needs to be done
# first, as otherwise dependencies fail to build because Python3 is
# not available.
(
cd /
/vcpkg/vcpkg install python3
ln -sf /vcpkg/installed/x64-linux/tools/python3/python3.[0-9][0-9] /usr/bin/python3
)
echo "::endgroup::"
- name: Patch bundle name
run: |
sed -i 's/generic/dedicated/g' cmake/InstallAndPackage.cmake
@ -113,7 +153,7 @@ jobs:
echo "::endgroup::"
- name: Store bundles
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: openttd-linux-dedicated
path: build/bundles

@ -39,7 +39,7 @@ jobs:
steps:
- name: Download source
uses: actions/download-artifact@v4
uses: actions/download-artifact@v3
with:
name: internal-source
@ -116,7 +116,7 @@ jobs:
echo "::endgroup::"
- name: Store bundles
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: openttd-linux-${{ matrix.bundle_name }}
path: build/bundles

@ -0,0 +1,206 @@
name: Release (Linux, Legacy)
on:
workflow_call:
inputs:
survey_key:
required: false
type: string
default: ""
jobs:
linux:
name: Linux (Legacy)
runs-on: ubuntu-latest
container:
# manylinux2014 is based on CentOS 7, and already has a lot of things
# installed and preconfigured. It makes it easier to build OpenTTD.
# This distro is based on glibc 2.17, released in 2012.
image: quay.io/pypa/manylinux2014_x86_64
steps:
- name: Download source
uses: actions/download-artifact@v3
with:
name: internal-source
- name: Unpack source
run: |
tar -xf source.tar.gz --strip-components=1
# curl is too old for most of the tools to work properly. For example,
# rust-toolchain doesn't work properly, neither vcpkg caching.
# The easier solution here is to upgrade curl.
- name: Update curl
run: |
yum install -y \
openssl-devel \
# EOF
mkdir /curl
cd /curl
curl -o curl-7.81.0.zip https://curl.se/download/curl-7.81.0.zip
unzip curl-7.81.0.zip
cd curl-7.81.0
./configure --with-ssl --with-zlib --prefix=/usr --libdir=/usr/lib64
make -j $(nproc)
make install
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Enable Rust cache
uses: Swatinem/rust-cache@v2.7.0
with:
key: legacy
- name: Setup vcpkg caching
uses: actions/github-script@v6
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 dependencies
run: |
echo "::group::Install system dependencies"
# perl-IPC-Cmd, wget, and zip are needed to run vcpkg.
# autoconf-archive is needed to build ICU.
yum install -y \
autoconf-archive \
perl-IPC-Cmd \
wget \
zip \
# EOF
# aclocal looks first in /usr/local/share/aclocal, and if that doesn't
# exist only looks in /usr/share/aclocal. We have files in both that
# are important. So copy the latter to the first, and we are good to
# go.
cp /usr/share/aclocal/* /usr/local/share/aclocal/
echo "::endgroup::"
# The yum variant of fluidsynth depends on all possible audio drivers,
# like jack, ALSA, pulseaudio, etc. This is not really useful for us,
# as we route the output of fluidsynth back via our sound driver, and
# as such do not use these audio driver outputs at all.
# The vcpkg variant of fluidsynth depends on ALSA. Similar issue here.
# So instead, we compile fluidsynth ourselves, with as few
# dependencies as possible. We do it before anything else is installed,
# to make sure it doesn't pick up on any of the drivers.
echo "::group::Install fluidsynth"
wget https://github.com/FluidSynth/fluidsynth/archive/v2.3.3.tar.gz
tar xf v2.3.3.tar.gz
(
cd fluidsynth-2.3.3
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
cmake --build . -j $(nproc)
cmake --install .
)
# The container we use is old enough, that it doesn't know SHF_COMPRESSED.
# But, breakpad needs this symbol to exist. So we patch it in our system
# libraries.
(
cd /
patch -p1 < ${GITHUB_WORKSPACE}/os/linux/shf-compressed.patch
)
echo "::endgroup::"
echo "::group::Install audio drivers"
# These audio libs are to make sure the SDL version of vcpkg adds
# sound-support; these libraries are not added to the resulting
# binary, but the headers are used to enable them in SDL.
yum install -y \
alsa-lib-devel \
jack-audio-connection-kit-devel \
pulseaudio-libs-devel \
# EOF
echo "::endgroup::"
echo "::group::Install video drivers"
# These video libs are to make sure the SDL version of vcpkg adds
# video-support; these libraries are not added to the resulting
# binary, but the headers are used to enable them in SDL.
yum install -y \
libX11-devel \
libXcursor-devel \
libXext-devel \
libXfixes-devel \
libXi-devel \
libxkbcommon-devel \
libXrandr-devel \
libXScrnSaver-devel \
# EOF
echo "::endgroup::"
# We use vcpkg for our dependencies, to get more up-to-date version.
echo "::group::Install vcpkg and dependencies"
git clone https://github.com/microsoft/vcpkg /vcpkg
(
cd /vcpkg
./bootstrap-vcpkg.sh -disableMetrics
)
# Make Python3 available for other packages. This needs to be done
# first, as otherwise dependencies fail to build because Python3 is
# not available.
(
cd /
/vcpkg/vcpkg install python3
ln -sf /vcpkg/installed/x64-linux/tools/python3/python3.[0-9][0-9] /usr/bin/python3
)
echo "::endgroup::"
- name: Patch bundle name
run: |
sed -i 's/generic/legacy/g' cmake/InstallAndPackage.cmake
- name: Build
run: |
mkdir -p build
cd build
echo "::group::CMake"
cmake ${GITHUB_WORKSPACE} \
-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DOPTION_COMPRESS_DEBUG=ON \
-DOPTION_LTO=ON \
-DOPTION_TRIM_PATH_PREFIX=ON \
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
-DOPTION_PACKAGE_DEPENDENCIES=ON \
# EOF
echo "::endgroup::"
echo "::group::Build"
echo "Running on $(nproc) cores"
cmake --build . -j $(nproc) --target openttd
echo "::endgroup::"
- name: Create bundles
run: |
cd ${GITHUB_WORKSPACE}/build
echo "::group::Run CPack"
cpack
echo "::endgroup::"
echo "::group::Cleanup"
# Remove the sha256 files CPack generates; we will do this ourself at
# the end of this workflow.
rm -f bundles/*.sha256
echo "::endgroup::"
- name: Store bundles
uses: actions/upload-artifact@v3
with:
name: openttd-linux-legacy
path: build/bundles
retention-days: 5

@ -12,16 +12,11 @@ jobs:
macos:
name: MacOS
runs-on: macos-14
runs-on: macos-latest
env:
MACOSX_DEPLOYMENT_TARGET: 10.13
steps:
- name: Setup Xcode version
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Download source
uses: actions/download-artifact@v4
with:
@ -45,11 +40,6 @@ jobs:
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
env:
HOMEBREW_NO_AUTO_UPDATE: 1
@ -99,7 +89,7 @@ jobs:
cmake ${GITHUB_WORKSPACE} \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DVCPKG_TARGET_TRIPLET=arm64-osx \
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
-DCMAKE_BUILD_TYPE=Release \
-DOPTION_TRIM_PATH_PREFIX=ON \
@ -121,7 +111,7 @@ jobs:
cmake ${GITHUB_WORKSPACE} \
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
-DVCPKG_TARGET_TRIPLET=x64-osx \
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
-DCMAKE_BUILD_TYPE=Release \
-DOPTION_TRIM_PATH_PREFIX=ON \

@ -53,11 +53,6 @@ jobs:
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 dependencies
shell: bash
run: |
@ -94,6 +89,22 @@ jobs:
with:
arch: ${{ matrix.host }}
- name: Import code signing certificate
if: ${{ false }} # Disabled
shell: powershell
# If this is run on a fork, there may not be a certificate set up - continue in this case
continue-on-error: true
run: |
$tempFile = [System.IO.Path]::GetTempFileName()
$bytes = [System.Convert]::FromBase64String($env:WINDOWS_CERTIFICATE_P12)
[IO.File]::WriteAllBytes($tempFile, $bytes)
$pwd = ConvertTo-SecureString $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force
Import-PfxCertificate -FilePath $tempFile -CertStoreLocation Cert:\CurrentUser\My -Password $pwd
Remove-Item $tempFile
env:
WINDOWS_CERTIFICATE_P12: ${{ secrets.WINDOWS_CERTIFICATE_P12 }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
- name: Build (with installer)
if: inputs.is_tag == 'true'
shell: bash
@ -105,11 +116,12 @@ jobs:
cmake ${GITHUB_WORKSPACE} \
-GNinja \
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
-DOPTION_USE_NSIS=ON \
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
# EOF
echo "::endgroup::"
@ -117,12 +129,7 @@ jobs:
cmake --build . --target openttd
echo "::endgroup::"
env:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_CODESIGN_ACCOUNT_NAME: ${{ secrets.AZURE_CODESIGN_ACCOUNT_NAME }}
AZURE_CODESIGN_ENDPOINT: ${{ secrets.AZURE_CODESIGN_ENDPOINT }}
AZURE_CODESIGN_PROFILE_NAME: ${{ secrets.AZURE_CODESIGN_PROFILE_NAME }}
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
- name: Build (without installer)
if: inputs.is_tag != 'true'
@ -135,10 +142,11 @@ jobs:
cmake ${GITHUB_WORKSPACE} \
-GNinja \
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
# EOF
echo "::endgroup::"
@ -146,12 +154,7 @@ jobs:
cmake --build . --target openttd
echo "::endgroup::"
env:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_CODESIGN_ACCOUNT_NAME: ${{ secrets.AZURE_CODESIGN_ACCOUNT_NAME }}
AZURE_CODESIGN_ENDPOINT: ${{ secrets.AZURE_CODESIGN_ENDPOINT }}
AZURE_CODESIGN_PROFILE_NAME: ${{ secrets.AZURE_CODESIGN_PROFILE_NAME }}
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
- name: Create bundles
shell: bash
@ -176,15 +179,13 @@ jobs:
- name: Sign installer
if: ${{ false }} # inputs.is_tag == 'true'
shell: bash
# If this is run on a fork, there may not be a certificate set up - continue in this case
continue-on-error: true
run: |
${GITHUB_WORKSPACE}/os/windows/sign.bat "${GITHUB_WORKSPACE}/build/bundles"
cd ${GITHUB_WORKSPACE}/build/bundles
../../os/windows/sign.bat *.exe "${WINDOWS_CERTIFICATE_COMMON_NAME}"
env:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_CODESIGN_ACCOUNT_NAME: ${{ secrets.AZURE_CODESIGN_ACCOUNT_NAME }}
AZURE_CODESIGN_ENDPOINT: ${{ secrets.AZURE_CODESIGN_ENDPOINT }}
AZURE_CODESIGN_PROFILE_NAME: ${{ secrets.AZURE_CODESIGN_PROFILE_NAME }}
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
- name: Store bundles
uses: actions/upload-artifact@v4

@ -31,6 +31,16 @@ jobs:
with:
version: ${{ needs.source.outputs.version }}
linux-legacy:
name: Linux (Legacy)
needs: source
uses: ./.github/workflows/release-linux-legacy.yml
secrets: inherit
with:
survey_key: ${{ needs.source.outputs.survey_key }}
linux:
name: Linux (Generic)
needs: source

@ -1,2 +1,2 @@
jgrpp-0.59.1 20240519 0 5e971bfc026aa9a58773d89c583e78765156b9e4 1 0 2024
f0d82005ae0e64dc0f833d5cbd6776afb06c9a513cc83119ce8fd0a2e5be097b -
jgrpp-0.58.0 20240224 0 64be289942b09943e8280f5ca468c8be4757f083 1 0 2024
cbec696a8bef3ab0b3b16c340c5730ddaf724d5eb5a14990d03656d5265cf3f9 -

@ -5,7 +5,7 @@ if(NOT BINARY_NAME)
endif()
project(${BINARY_NAME}
VERSION 15.0
VERSION 14.0
)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
@ -536,10 +536,6 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(-DPOINTER_IS_64BIT)
endif()
if(OPTION_NO_TAGGED_PTRS)
add_definitions(-DNO_TAGGED_PTRS)
endif()
enable_testing()
add_subdirectory(regression)

@ -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.
* Non-trivial fall throughs must be documented, using a `[[fallthrough]]` attribute.
* All fall throughs must be documented, using a **FALLTHROUGH** define/macro.
* 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, uint8_t Tnumber_of_something>
template <typename T, typename Tsomething, int N, byte Tnumber_of_something>
int Func();
```

@ -110,6 +110,9 @@ builds.
- `-DOPTION_USE_ASSERTS=OFF`: disable asserts. Use with care, as assert
statements capture early signs of trouble. Release builds have them
disabled by default.
- `-DOPTION_USE_THREADS=OFF`: disable the use of threads. This will block
the interface in many places, and in general gives a worse experience of
the game. Use with care.
- `-DOPTION_TOOLS_ONLY=ON`: only build tools like `strgen`. Does not build
the game itself. Useful for cross-compiling.

@ -3,15 +3,14 @@
- Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3)
- Christoph Elsenhans (frosch) - General coding (since 0.6)
- Loïc Guilloux (glx) - General / Windows Expert (since 0.4.5)
- Koen Bussemaker (Kuhnovic) - General / Ship pathfinder (since 14)
- Charles Pigott (LordAro) - General / Correctness police (since 1.9)
- Michael Lutz (michi_cc) - General / Path based signals (since 0.7)
- Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)
- Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)
- Peter Nelson (peter1138) - Spiritual descendant from NewGRF gods (since 0.4.5)
- Peter Nelson (peter1138) - Spiritual descendant from newGRF gods (since 0.4.5)
- Remko Bijker (Rubidium) - Coder and way more (since 0.4.5)
- Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op
- Tyler Trahan (2TallTyler) - General / Time Lord (since 13)
- Tyler Trahan (2TallTyler) - General coding (since 13)
### Inactive Developers:

@ -1,10 +1,6 @@
## JGR's Patchpack version 0.59.1
## JGR's Patchpack version 0.58.0
This is a collection of features and other modifications applied to [OpenTTD](http://www.openttd.org/).
It's a separate version of the game which can be installed and played alongside the standard game, not a loadable mod (NewGRF, script, or so on).
This is mainly intended to be used by players who are already familiar with the standard game and how to play it.
It is not aimed at beginner/novice players. Some features and settings are there for very experienced players and so may have a steep learning curve.
This is a collection of patches applied to [OpenTTD](http://www.openttd.org/)
* * *
@ -20,14 +16,14 @@ section "Licensing" below for details,
See [below](#openttd) for the original OpenTTD readme.
The thread for this patchpack can be found [here](http://www.tt-forums.net/viewtopic.php?f=33&t=73469).
See [jgrpp-changelog.md](jgrpp-changelog.md) for the changelog.
See the [wiki](https://github.com/JGRennison/OpenTTD-patches/wiki) for guides on how to use some of the included features.
See [installation.md](/installation.md) for instructions on how to install.
The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums.net/viewtopic.php?f=33&t=73469).
(Nearly all of the patches which are listed below have been modified, fixed or extended in some way, and so are not the same as the originals which are linked).
#### Railways and Trains
@ -120,6 +116,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
* Open train vehicle details window on total cargo tab if shift pressed.
* Add news/advice setting to warn if no depot order in vehicle schedule.
* [Add buttons to collapse/expand all groups](http://www.tt-forums.net/viewtopic.php?f=33&t=74365).
* Add a menu item to the vehicle list to assign all listed vehicles to a new group.
* Add a setting to include the train length and group name in the vehicle details window.
* Add a setting for whether to open the new vehicle GUI when share-cloning.
* Add setting to disable mass action buttons for top-level vehicle lists.
@ -135,6 +132,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
* [Automated timetables and separation](http://www.tt-forums.net/viewtopic.php?f=33&t=46391).
* Allow clearing of timetable time fields which are at 0. Allow explicitly setting timetable time fields to 0 without clearing them.
* Allow changing/clearing the timetabled waiting time and max speed of all of a vehicle's orders at once.
* Add client setting to show the remainder ticks in timetable, after dividing to days or minutes.
* Add a company setting to control the number of ticks used in auto-fill timetable rounding.
* [Cargo type orders](https://www.tt-forums.net/viewtopic.php?p=1047749).
@ -169,6 +167,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
* [Departure boards](https://www.tt-forums.net/viewtopic.php?f=33&t=49956).
* Add road waypoints.
* Add NewGRF road stops.
* Add a setting to increase the station catchment radius.
* Station rating: track "last visited vehicle type" separately per cargo.
* Add setting to scale station cargo capacity and rating tolerance by size.
@ -189,6 +188,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
#### Towns
* [Town cargo generation factor](http://www.tt-forums.net/viewtopic.php?t=46399).
* [Rating in town label](http://www.tt-forums.net/viewtopic.php?f=33&t=42598).
* [Random town road reconstruction](https://www.tt-forums.net/viewtopic.php?f=33&t=36438). This defaults to off.
* Add very and extremely slow options to town growth rate setting.
@ -205,6 +205,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
#### Industries
* Industry cargo generation factor.
* Allow linking only inputs or outputs to the smallmap and map mode viewports in the industry chain window.
#### Map and Landscaping
@ -214,13 +215,14 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
* Add a new tree placement mode (perfect).
* [Minimum town distance](https://www.tt-forums.net/viewtopic.php?f=33&t=33625).
* Add map generation settings to control river/lake, rocky patch, and tropic zone generation.
* Add generation of wide rivers.
* Add settings to customise the size of town zones, and city zones.
* Add setting to show purchased land using clear tile ground sprites (dirt, grass, snow, desert, etc).
#### Construction
* Enable building rivers in game. Off by default.
* Add a setting to disable removing sea/rivers.
* Allow building objects by area (1x1 objects only).
* Allow purchasing a region of tiles at once, by dragging.
* Add setting to control if and how land purchasing is permitted.
* Add a company rate limit for land purchasing.
@ -302,6 +304,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
* Add setting to allow non server admins to use the money cheat in multiplayer.
* Allow clicking the money text in the cheats window to enter a quantity.
* Add cheats to set inflation income and cost factors.
* Add cheat to set all station ratings to 100%.
* Add cheat to set all town local authority ratings to Outstanding.
#### Cargo Distribution and Link Graph
@ -320,6 +323,7 @@ The TT-Forums thread for this patchpack can be found [here](http://www.tt-forums
#### Console and Scripts
* Add basic tab-completion to the console window.
* Add console commands for conditional execution from game date.
* [Daily/monthly/yearly scripts](http://www.tt-forums.net/viewtopic.php?f=33&t=49595)

@ -4,5 +4,3 @@
* 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.");

@ -1,6 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/

@ -4,5 +4,3 @@
* 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.");

@ -1,6 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/

@ -41,12 +41,6 @@ macro(compile_flags)
"$<$<CONFIG:Debug>:-Wa,-mbig-obj>" # Switch to pe-bigobj-x86-64 as x64 Debug builds push pe-x86-64 to the limits (linking errors with ASLR, ...)
)
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
# Fix MinGW's incorrect assumption that the incoming stack at function calls is 16-byte aligned
# The Win32 API/calling convention only requires and guarantees 4-byte alignment, leading to alignment problems with SSE/AVX/etc
add_compile_options(-mincoming-stack-boundary=2 -mpreferred-stack-boundary=2)
endif()
add_compile_options(-Wno-stringop-overflow) # This warning false-positives on some MinGW versions so just turn it off
endif()
# Prepare a generator that checks if we are not a debug, and don't have asserts
@ -91,6 +85,8 @@ macro(compile_flags)
# break anything. So disable strict-aliasing to make the
# compiler all happy.
-fno-strict-aliasing
)
if(OPTION_TRIM_PATH_PREFIX)
@ -141,13 +137,6 @@ macro(compile_flags)
# and of course they both warn when the other compiler is happy
"$<$<COMPILE_LANGUAGE:CXX>:-Wno-redundant-move>"
)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11)
add_compile_options(
# GCC >= 11 has false positives if operator new is inlined but operator delete isn't, or vice versa
"-Wno-mismatched-new-delete"
)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")

@ -171,10 +171,10 @@ elseif(WIN32)
set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}")
if(DEFINED ENV{AZURE_CODESIGN_PROFILE_NAME})
if(WINDOWS_CERTIFICATE_COMMON_NAME)
add_custom_command(TARGET openttd
POST_BUILD
COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "${BINARY_DESTINATION_DIR}"
COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "$<TARGET_FILE:openttd>" "${WINDOWS_CERTIFICATE_COMMON_NAME}"
)
endif()
elseif(UNIX)

@ -57,6 +57,13 @@ 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" ON)
if(EMSCRIPTEN)
# Although pthreads is supported, it is not in a way yet that is
# useful for us.
option(OPTION_USE_THREADS "Use threads" OFF)
else()
option(OPTION_USE_THREADS "Use threads" ON)
endif()
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)
@ -78,6 +85,7 @@ function(show_options)
message(STATUS "Option Dedicated - ${OPTION_DEDICATED}")
message(STATUS "Option Install FHS - ${OPTION_INSTALL_FHS}")
message(STATUS "Option Use assert - ${OPTION_USE_ASSERTS}")
message(STATUS "Option Use threads - ${OPTION_USE_THREADS}")
message(STATUS "Option Use NSIS - ${OPTION_USE_NSIS}")
if(OPTION_SURVEY_KEY)
@ -101,6 +109,10 @@ function(add_definitions_based_on_options)
add_definitions(-DDEDICATED)
endif()
if(NOT OPTION_USE_THREADS)
add_definitions(-DNO_THREADS)
endif()
if(OPTION_USE_ASSERTS)
add_definitions(-DWITH_ASSERT)
else()

@ -49,8 +49,7 @@ if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
string(SUBSTRING "${FULLHASH}" 0 10 SHORTHASH)
# Get the last commit date
set(ENV{TZ} "UTC0")
execute_process(COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_SOURCE_DIR}" show -s --date=iso-local --pretty=format:%cd HEAD
execute_process(COMMAND ${GIT_EXECUTABLE} -C "${CMAKE_SOURCE_DIR}" show -s --pretty=format:%ci HEAD
OUTPUT_VARIABLE COMMITDATE
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}

@ -56,14 +56,11 @@ foreach(ENUM IN LISTS ENUM_LINES)
endif()
# Check for enum match
if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN}( *: *[^ ]*)? *\{")
if("${LINE}" MATCHES "^ *enum *${ENUM_PATTERN} *\{")
# REGEX REPLACE does a REGEX MATCHALL and fails if an empty string is matched
string(REGEX MATCH "[^ ]*" RESULT "${LINE}")
string(REPLACE "${RESULT}" "" RM_INDENT "${LINE}")
string(REGEX MATCH " *: *[^ ]*" RESULT "${LINE}")
string(REPLACE "${RESULT}" "" LINE "${LINE}")
set(ACTIVE 1)
if(ACTIVE_COMMENT GREATER 0)
string(APPEND ${PLACE_HOLDER} "\n${COMMENT}")

@ -304,7 +304,7 @@
<tr><td>use_land_ground</td><td>0 or 1</td><td>
Sets whether to use the underlying ground as the object ground sprite, ignoring the ground sprite provided in the sprite layout.<br />
When enabled, the ground sprite will be bare ground, grass, snow, desert, etc. as if it were a clear ground tile.<br />
In edge foundation mode, or when foundations are disabled, the ground may be coast/shore when flooded.
In edge foundation mode, the ground may be coast/shore when flooded.
</td></tr>
<tr><td>edge_foundation_mode</td><td>[mode0, mode1, mode2, mode3]</td><td>
Enables edge foundation mode for the object.<br />
@ -675,13 +675,6 @@ item (FEAT_GLOBALVARS) {
Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the <span class="code">define_style</span> property).
</td>
</tr>
<tr><td>style_both_sides</td><td>0 or 1</td>
<td>
Set whether signals should be drawn on both sides of the track for the most recently defined style (defined using the <span class="code">define_style</span> property).<br />
If set, the <span class="code">signal_context_is_second</span> variable is true when drawing the second signal.<br />
If this and <span class="code">style_opposite_side</span> are both set, the first signal is drawn on the opposite side and the second signal is drawn on the usual side.
</td>
</tr>
<tr><td>style_realistic_braking_only</td><td>0 or 1</td>
<td>
Set whether signals using this style may only be built when realistic braking is enabled, for the most recently defined style (defined using the <span class="code">define_style</span> property).
@ -731,11 +724,6 @@ item (FEAT_GLOBALVARS) {
The signal is being drawn on a tunnel entrance/exit (not a bridge)
</td>
</tr>
<tr><td>signal_context_is_second</td><td>0 or 1</td>
<td>
The second signal is being drawn (on the opposite side to the first signal), see the style_both_sides property
</td>
</tr>
<tr><td>signal_context_info</td><td></td>
<td>
Above signal context variables in one variable (all of the signals_signal_context variable)

@ -554,16 +554,6 @@
The Action 0 Id field is not used, the value is ignored.
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_both_sides">Set custom signal style signal drawn on both sides (mappable property: signals_style_both_sides)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
When enabled, signals using this style are drawn on both sides of the track.<br />
Bit 9 of <a href="#signals_signal_context">signals_signal_context</a> is set when drawing the second signal on the opposite side.</p>
<p>If this and <a href="#signals_style_opposite_side">signals_style_opposite_side</a> are both set, the first signal is drawn on the opposite side
and the second signal is drawn on the usual side.</p>
<p>The property length is 1 byte. 0 is disabled (default). 1 is enabled.<br />
The Action 0 Id field is not used, the value is ignored.
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 3</p>
<h4 id="signals_style_realistic_braking_only">Set custom signal style signal requires realistic braking (mappable property: signals_style_realistic_braking_only)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
When enabled, signals using this style may only be built when realistic braking is enabled.</p>
@ -583,7 +573,7 @@
<h4 id="object_use_land_ground">Object uses land ground sprite (mappable property: object_use_land_ground)</h4>
<p>This property sets whether to use the underlying ground as the object ground sprite, ignoring the ground sprite provided in the sprite layout.<br />
When enabled, the ground sprite will be bare ground, grass, snow, desert, etc. as if it were a clear ground tile.<br />
In edge foundation mode, or when foundations are disabled, the ground may be coast/shore when flooded.<br />
In edge foundation mode, the ground may be coast/shore when flooded.<br />
The property length is 1 byte. 0 is disabled (default). 1 is enabled.</p>
<p>This is indicated by the feature name: <font face="monospace">action0_object_use_land_ground</font>, version 1</p>
<h4 id="object_edge_foundation_mode">Enable object edge foundation mode (mappable property: object_edge_foundation_mode)</h4>
@ -939,7 +929,6 @@
</table>
</td></tr>
<tr><td>8</td><td>Tunnel tile</td></tr>
<tr><td>9</td><td>Second signal (being drawn on opposite side), see: <a href="#signals_style_both_sides">signals_style_both_sides</a></td></tr>
</table>
</p>
<p>This is indicated by the feature name: <font face="monospace">varaction2_signals_signal_context</font>, version 1</p>

@ -129,8 +129,8 @@
<tr><td>stop_type</td><td>RST_TYPE_XXX</td><td>XXX = BUS | TRUCK | WAYPOINT (<b>Not in standard specification</b>)</td></tr>
<tr><td>terrain_type</td><td>TILETYPE_XXX</td><td>XXX = NORMAL | DESERT | RAIN_FOREST | SNOW</td></tr>
<tr><td>tile_slope</td><td>SLOPE_XXX</td><td>See <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:List_of_tile_slopes">tile slopes</a> for an overview of possible values</td></tr>
<tr><td>has_road</td><td>0 | 1</td><td>1 if this road stop has road</td></tr>
<tr><td>has_tram</td><td>0 | 1</td><td>1 if this road stop has tram</td></tr>
<tr><td>has_road</td><td>0 | 1</td><td>1 is this road stop has road</td></tr>
<tr><td>has_tram</td><td>0 | 1</td><td>1 is this road stop has tram</td></tr>
<tr><td>road_type</td><td>road type | 0xFF</td><td>Road type. If there is no road the value will be 0xFF. If the roadtype has no entry in the roadtype translation table of the GRF, this value will be 0xFF. If no translation table is present, the raw value will be returned.</td></tr>
<tr><td>tram_type</td><td>tram type | 0xFF</td><td>Tram type. If there is no tram the value will be 0xFF. If the tramtype has no entry in the tramtype translation table of the GRF, this value will be 0xFF. If no translation table is present, the raw value will be returned.</td></tr>
<tr><td>town_manhattan_dist</td><td></td><td>Manhattan distance to the associated town</td></tr>
@ -142,6 +142,7 @@
<tr><td>company_colour2</td><td>COLOUR_XXX</td><td></td></tr>
<tr><td>animation_frame</td><td>0..255</td><td>Animation frame of the current tile</td></tr>
<tr><td>waiting_triggers</td><td>0..255</td><td>Waiting triggers</td></tr>
<tr><td>random_bits</td><td>0..16777215</td><td>All random bits</td></tr>
<tr><td>random_bits_tile</td><td>0..255</td><td>Random bits (per tile), see also <a href="https://newgrf-specs.tt-wiki.net/wiki/NML:Stations#Base_station_variables">random_bits_station</a></td></tr>
<tr><td>one_way_info<br /><b>Not in standard specification</b></td><td>RST_OWI_XXX</td><td>One-way road information of drive-through stop tile<br />XXX = TWO_WAY | WEST_BOUND | EAST_BOUND | NO_ENTRY</td></tr>
<tr><td>one_way_info_inferred<br /><b>Not in standard specification</b></td><td>RST_OWI_XXX</td><td>Inferred one-way road information of drive-through stop tile<br />XXX = TWO_WAY | WEST_BOUND | EAST_BOUND | NO_ENTRY</td></tr>

@ -74,7 +74,7 @@
<ul>
<li>The number of houses in the town changes</li>
<li>When the game is loaded</li>
<li>When settings, NewGRFs or other relevant game configuration is changed</li>
<li>When settings, NewGRFs or other relavant game configuration is changed</li>
</ul>
</p>

@ -105,7 +105,7 @@
<ul>
<li>The number of houses in the town changes</li>
<li>When the game is loaded</li>
<li>When settings, NewGRFs or other relevant game configuration is changed</li>
<li>When settings, NewGRFs or other relavant game configuration is changed</li>
</ul>
</p>

@ -19,7 +19,7 @@ Now simply open up the `crash.dmp`, and start debugging.
The best tool to use is `minidump-stackwalk` as published in the Rust's cargo index:
```bash
cargo install --locked minidump-stackwalk
cargo install minidump-stackwalk
```
For how to install Rust, please see [here](https://doc.rust-lang.org/cargo/getting-started/installation.html).

@ -2,102 +2,6 @@
* * *
### v0.59.1 (2024-05-20)
* Fix crash when sorting by capacity in autoreplace window.
* Fix non-percentage servicing interval when using wallclock mode.
* Fix road vehicles skipping orders when using implicit orders.
* Fix setting default value for industry cargo scaling mode when loading old savegames.
* Fix setting display for industry cargo scaling.
* Fix crash which could occur when using autorenew/autoreplace wagon removal with leading engines longer than the train length limit.
* Fix crash which could occur with loading certain GRFs.
* Fix multiplayer desync when joining a server after previously loading a scenario.
* Fix keyboard input issues on Linux/SDL.
* Realistic braking:
* Fix accuracy issues with realistic acceleration and braking when a train is underpowered for ascending or descending a steep slope.
* Reduce sensitivity of train brakes overheated breakdown.
* Add setting to shorten vehicle view status text.
* Bump trunk base from commit bd7120bae41b6e7ac86c664c8220b59cd57242bb to commit 88cf99017a26f887230d2c14d057a97bbf077f7c.
### v0.59.0 (2024-05-05)
* Fix loading recent vanilla savegame versions resulting in incorrect industry cargoes.
* Fix incorrect station catchment/acceptance which could occur when an oil rig/water industry completed construction, which could cause multiplayer desyncs.
* Fix AI construction of block signals when using realistic braking.
* Fix incorrect train weights being used for calculating infrastructure sharing track fees.
* Fix vehicles leaving dots behind in viewport map mode in some cases.
* Fix NewGRF train motion animations for some NewGRFs which use articulated engines.
* Fix template-based train replacement not triggering replacements for companies nominally in debt when using the infinite money setting.
* Fix text filters in dual-pane train purchase window when using NewGRFs with variable vehicle names.
* Road vehicles no longer remaining loading when the next order is for the same station if the next order has a different required direction.
* Enable the cargo capacity/running cost sort mode in the dual pane train purchase window.
* The vehicle capacity sort modes in the build vehicle windows now take into account the selected refit cargo.
* Timekeeping:
* The day length factor setting is now enabled in wallclock timekeeping mode. This scales the economy speed, but not the calendar speed.
* Fix timing of engine preview offers in wallclock timekeeping mode.
* Scheduled dispatch:
* When using scheduled dispatch and timetable automation at the same time, vehicle lateness values are no longer reset when congestion is detected.
* The number of vehicles required text is now clarified to be an estimate.
* Further increase effect size of cargo dist effect of distance on demand setting for values greater than 100%.
* Further reduce the possibility of stuttering when playing sound effects on Windows.
* Bump trunk base from commit 3e625b5b1a81b00f774ca87b48d3e4f4e9d014c3 to commit bd7120bae41b6e7ac86c664c8220b59cd57242bb.
### v0.58.3 (2024-04-10)
* Fix stuttering when playing sound effects on Windows.
* Fix incorrect cargo payment calculations for cargo in the mail compartment of aircraft and in non-first parts of multi-part ships.
* Fix path-only signal cycle mode being ignored when using realistic braking.
* Template-based train replacement:
* Fix replacement failing when using NewGRFs with complex wagon attachment and/or start/stop restrictions.
* Fix incorrect cost estimation when using NewGRFs with complex start/stop restrictions.
* Wallclock timekeeping mode:
* Fix game units (tiles/second) being shown as tiles/day.
* Fix time units shown for past production in the industry window.
* Fix cargo dist effect of distance on demand setting for values greater than 100%. (The scaling/demand allocation algorithm has been adjusted in general).
* Fix velocity units used in cargo payments graph x-axis label.
* Fix click/tooltip alignment of cargo lines in the industry chains window.
* Fix changing sprite alignments in the sprite aligner window not being applied as expected.
### v0.58.2 (2024-03-28)
* Fix crash with some GRFs when the maximum sprite resolution setting was set to 2x.
* Fix crash which could occur when clearing a crashed road vehicle from a drive-through road stop.
* Fix crash when the autosave uses real time setting and the autosave interval were both disabled.
* Fix crash which could occur after removing road from a one-way road/tram road stop.
* Fix drawing of black text in some drop-down menus.
* Fix incorrect handling of invalid or empty dispatch schedules in the departure board window.
* Fix handling of missing last or next scheduled dispatch times.
* Fix changes to the title game zoom level when changing the UI scale setting.
* Fix vehicles leaving dots behind in viewport map mode in some cases.
* Fix incorrect sprites being shown for some GRFs.
* Fix crash in the engine preview window with certain GRFs.
* Fix road vehicles not remaining loading as expected when the next order is for the same station.
* Fix train unit numbers being incorrectly marked as in use after an autoreplace operation.
* Allow manually removing/setting train speed restrictions from the vehicle details window.
* Allow removing a vehicle from slots owned by the current company from the vehicle details window.
* Show viewport route step markers for go via station orders using a different tag.
* Add setting to show purchased land using clear tile ground sprites (dirt, grass, snow, desert, etc).
* Add ctrl-click scroll-to for stations referenced by conditional orders.
* Allow industry monthly production and transported totals to be greater than 64k.
* Allow engine reliability increases but not decreases after the no vehicles expire after year setting is reached.
* Remove setting to disable script parameter randomisation, because the feature has been removed.
* Fix signature validation for social/presence plugins.
* Bump trunk base from commit a602845d0a35331f1e012cd13ca921c6bc42b58d to commit 3e625b5b1a81b00f774ca87b48d3e4f4e9d014c3.
### v0.58.1 (2024-03-02)
* Fix multiplayer desync after joining a server with the flood from edges setting enabled.
* Fix timetabled waiting in depots.
* Fix incorrect accounting of company quarterly statistics.
* Fix trains failing to load at stations in some cases after leaving a conditional order loading loop at the previous station.
* Fix the company infrastructure window not being drawn as a company window and not being removed on company deletion.
* Fix main viewport crash or only partial redraw when changing the UI scale using the slider.
* Fix display of ships entering viewports on an aqueduct.
* Allow adding plans in the scenario editor.
* Add setting for whether to show vehicle running costs per calendar year.
* Add setting for whether to show speed before destination in vehicle status bar.
* Add setting to disable script parameter randomisation.
* Add "path signals only" mode to the signal cycle setting.
* Adjust display of period numbers in wallclock time-keeping mode.
* Stop engine reliability decay once the no vehicles expire after year setting is reached, instead of when the no vehicles expire and introduced after year settings are both reached.
* Add NewGRF custom signal style flag to draw signal sprites on both sides.
* Bump trunk base from commit 8bccb5805a94eb2acb0e581185ca34090f2b1397 to commit a602845d0a35331f1e012cd13ca921c6bc42b58d.
### v0.58.0 (2024-02-24)
* Fix crash when road vehicles change length in drive-through road stops (e.g. due to refits).
* Fix crash when showing the savegame file overwrite warning for a save with no readable version.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -3,4 +3,4 @@
The OpenTTD TrueType font was created by Zephyris and is maintained on [Github](https://github.com/zephyris/openttd-ttf).
It is licensed under GPL-2.0.
The currently included files correspond to release v0.6.
The currently included files correspond to release v0.5.

@ -1,2 +1,18 @@
@echo off
pwsh -File "%~dp0sign_azure.ps1" %1
REM Signing script
REM Arguments: sign.bat exe_to_sign certificate_subject_name
REM This is a loose wrapper around the Microsoft signtool application (included in the Windows SDK).
REM See https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe for more details.
REM Path to signtool.exe
IF NOT DEFINED SIGNTOOL_PATH (SET SIGNTOOL_PATH=signtool)
REM URL of the timestamp server
IF NOT DEFINED SIGNTOOL_TIMESTAMP_URL (SET SIGNTOOL_TIMESTAMP_URL=http://timestamp.digicert.com)
REM Sign with SHA-1 for Windows 7 and below
"%SIGNTOOL_PATH%" sign -v -n %2 -t %SIGNTOOL_TIMESTAMP_URL% -fd sha1 %1
REM Sign with SHA-256 for Windows 8 and above
"%SIGNTOOL_PATH%" sign -v -n %2 -tr %SIGNTOOL_TIMESTAMP_URL% -fd sha256 -td sha256 -as %1

@ -1,40 +0,0 @@
# Signing script for Azure Code Signing
# Arguments: sign_azure.ps1 path_to_sign
#
# Environment variables must be set up before use:
#
# AZURE_TENANT_ID
# AZURE_CLIENT_ID
# AZURE_CLIENT_SECRET
# AZURE_CODESIGN_ACCOUNT_NAME
# AZURE_CODESIGN_ENDPOINT
# AZURE_CODESIGN_PROFILE_NAME
Param
(
# Files folder
[Parameter(Mandatory=$true, Position=0)]
$FilesFolder
)
if (!$Env:AZURE_CODESIGN_ENDPOINT -or !$Env:AZURE_CODESIGN_ACCOUNT_NAME -or !$Env:AZURE_CODESIGN_PROFILE_NAME -or
!$Env:AZURE_TENANT_ID -or !$Env:AZURE_CLIENT_ID -or !$Env:AZURE_CLIENT_SECRET)
{
"Code signing variables not found; most likely running in a fork. Skipping signing."
exit
}
Install-Module -Name AzureCodeSigning -Scope CurrentUser -RequiredVersion 0.3.0 -Force -Repository PSGallery
$params = @{}
$params["Endpoint"] = $Env:AZURE_CODESIGN_ENDPOINT
$params["CodeSigningAccountName"] = $Env:AZURE_CODESIGN_ACCOUNT_NAME
$params["CertificateProfileName"] = $Env:AZURE_CODESIGN_PROFILE_NAME
$params["FilesFolder"] = $FilesFolder
$params["FilesFolderFilter"] = "exe"
$params["FileDigest"] = "SHA256"
$params["TimestampRfc3161"] = "http://timestamp.acs.microsoft.com"
$params["TimestampDigest"] = "SHA256"
Invoke-AzureCodeSigning @params

@ -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 "15"; }
function GetAPIVersion() { return "14"; }
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 "15"; }
function GetAPIVersion() { return "14"; }
function GetDate() { return "2007-03-18"; }
function CreateInstance() { return "StationList"; }
function UseAsRandomAI() { return false; }

@ -59,8 +59,8 @@
static const size_t MD5_HASH_BYTES = 16;
/** Container for storing a MD5 hash/checksum/digest. */
struct MD5Hash : std::array<uint8_t, MD5_HASH_BYTES> {
MD5Hash() : std::array<uint8_t, MD5_HASH_BYTES>{} {}
struct MD5Hash : std::array<byte, MD5_HASH_BYTES> {
MD5Hash() : std::array<byte, MD5_HASH_BYTES>{} {}
/**
* Exclusively-or the given hash into this hash.

@ -1,8 +1,3 @@
if (MSVC)
# Disable warning 4244 for monocypher.cpp
set_compile_flags(monocypher.cpp COMPILE_FLAGS /wd4244)
endif()
add_files(
monocypher-ed25519.cpp
monocypher-ed25519.h

@ -15,8 +15,6 @@
#include "sqvm.h"
#include "sqtable.h"
#include "../../../core/bit_cast.hpp"
#include "../../../string_func.h"
#include "../../../safeguards.h"
@ -662,7 +660,8 @@ public:
_fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
}
else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref, std::bit_cast<SQInt32>(_float(constval)));
SQFloat f = _float(constval);
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
}
else {
_fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
@ -708,7 +707,7 @@ public:
break;
case TK_FLOAT:
if(sizeof(SQFloat) == sizeof(SQInt32)) {
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(), std::bit_cast<SQInt32>(_lex._fvalue));
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
}
else {
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));

@ -12,8 +12,6 @@
#include "sqopcodes.h"
#include "sqfuncstate.h"
#include "../../../core/bit_cast.hpp"
#include "../../../safeguards.h"
#ifdef _DEBUG_DUMP
@ -200,7 +198,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,std::bit_cast<SQFloat>(inst._arg1),inst._arg2,inst._arg3);
printf("[%03d] %15s %d %f %d %d\n",n,g_InstrDesc[inst.op].name,inst._arg0,*((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);
@ -243,20 +241,19 @@ SQInteger SQFuncState::GetConstant(const SQObject &cons)
void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger 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);
_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);
}
void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
{
switch(arg){
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;
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;
};
}

@ -17,8 +17,6 @@
#include "sqarray.h"
#include "sqclass.h"
#include "../../../core/bit_cast.hpp"
#include "../../../string_func.h"
#include "../../../safeguards.h"
@ -52,7 +50,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)(std::bit_cast<SQUnsignedInteger>(i1) >> i2); break;
case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
default: { Raise_Error("internal vm error bitwise op failed"); return false; }
}
}
@ -473,10 +471,10 @@ bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjec
#define arg0 (_i_._arg0)
#define arg1 (_i_._arg1)
#define sarg1 (std::bit_cast<SQInt32>(_i_._arg1))
#define sarg1 (*(const_cast<SQInt32 *>(&_i_._arg1)))
#define arg2 (_i_._arg2)
#define arg3 (_i_._arg3)
#define sarg3 ((SQInteger)std::bit_cast<char>(_i_._arg3))
#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3))
SQRESULT SQVM::Suspend()
{
@ -765,7 +763,7 @@ exception_restore:
continue;
case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
case _OP_LOADFLOAT: TARGET = std::bit_cast<SQFloat>(arg1); continue;
case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue;
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
case _OP_TAILCALL:
temp_reg = STK(arg1);

@ -147,10 +147,6 @@ 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_func.h
@ -165,7 +161,6 @@ add_files(
engine_func.h
engine_gui.cpp
engine_gui.h
engine_override.h
engine_type.h
error.h
error_gui.cpp
@ -263,7 +258,6 @@ add_files(
music_gui.cpp
newgrf.cpp
newgrf.h
newgrf_act5.h
newgrf_airport.cpp
newgrf_airport.h
newgrf_airporttiles.cpp
@ -286,7 +280,6 @@ add_files(
newgrf_config.h
newgrf_debug.h
newgrf_debug_gui.cpp
newgrf_dump.h
newgrf_engine.cpp
newgrf_engine.h
newgrf_extension.cpp
@ -427,8 +420,6 @@ add_files(
signs_func.h
signs_gui.cpp
signs_type.h
slider.cpp
slider_func.h
slope_func.h
slope_type.h
smallmap_colours.h

@ -27,8 +27,9 @@ public:
/**
* Start a new AI company.
* @param company At which slot the AI company should start.
* @param deviate Whether to apply random deviation to the configured AI.
*/
static void StartNew(CompanyID company);
static void StartNew(CompanyID company, bool deviate = true);
/**
* Called every game-tick to let AIs do something.

@ -35,7 +35,7 @@
return !_networking || (_network_server && _settings_game.ai.ai_in_multiplayer);
}
/* static */ void AI::StartNew(CompanyID company)
/* static */ void AI::StartNew(CompanyID company, bool deviate)
{
assert(Company::IsValidID(company));
@ -58,6 +58,7 @@
/* Load default data and store the name in the settings */
config->Change(info->GetName(), -1, false);
}
if (deviate) config->AddRandomDeviation(company);
config->AnchorUnchangeableSettings();
c->ai_info = info;
@ -212,30 +213,25 @@
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName().c_str());
_settings_game.ai_config[c]->Change(std::nullopt);
if (Company::IsValidAiID(c)) {
/* The code belonging to an already running AI was deleted. We can only do
* one thing here to keep everything sane and that is kill the AI. After
* killing the offending AI we start a random other one in it's place, just
* like what would happen if the AI was missing during loading. */
AI::Stop(c);
AI::StartNew(c, false);
}
} else if (Company::IsValidAiID(c)) {
/* Update the reference in the Company struct. */
Company::Get(c)->ai_info = _settings_game.ai_config[c]->GetInfo();
}
}
if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName().c_str());
_settings_newgame.ai_config[c]->Change(std::nullopt);
}
}
if (Company::IsValidAiID(c) && Company::Get(c)->ai_config != nullptr) {
AIConfig *config = Company::Get(c)->ai_config.get();
if (!config->ResetInfo(true)) {
/* The code belonging to an already running AI was deleted. We can only do
* one thing here to keep everything sane and that is kill the AI. After
* killing the offending AI we start a random other one in it's place, just
* like what would happen if the AI was missing during loading. */
AI::Stop(c);
AI::StartNew(c);
} else {
/* Update the reference in the Company struct. */
Company::Get(c)->ai_info = config->GetInfo();
}
}
}
}

@ -127,20 +127,20 @@ struct AIConfigWindow : public Window {
}
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
switch (widget) {
case WID_AIC_DECREASE_NUMBER:
case WID_AIC_INCREASE_NUMBER:
case WID_AIC_DECREASE_INTERVAL:
case WID_AIC_INCREASE_INTERVAL:
size = maxdim(size, NWidgetScrollbar::GetHorizontalDimension());
*size = maxdim(*size, NWidgetScrollbar::GetHorizontalDimension());
break;
case WID_AIC_LIST:
this->line_height = GetCharacterHeight(FS_NORMAL) + padding.height;
resize.height = this->line_height;
size.height = 8 * this->line_height;
resize->height = this->line_height;
size->height = 8 * this->line_height;
break;
}
}

@ -27,7 +27,7 @@
*/
static bool CheckAPIVersion(const std::string &api_version)
{
static constexpr std::initializer_list<const char*> 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" };
static constexpr std::initializer_list<const char*> 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" };
return std::find_if(versions.begin(), versions.end(), [&](const char *v) { return api_version == v; }) != versions.end();
}

@ -67,24 +67,22 @@ int GetAircraftFlightLevel(T *v, bool takeoff = false);
struct AircraftCache {
uint32_t cached_max_range_sqr; ///< Cached squared maximum range.
uint16_t cached_max_range; ///< Cached maximum range.
uint8_t image_movement_state; ///< Cached image aircraft movement state
bool operator==(const AircraftCache &) const = default;
byte image_movement_state; ///< Cached image aircraft movement state
};
/**
* Aircraft, helicopters, rotors and their shadows belong to this class.
*/
struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
uint16_t crashed_counter; ///< Timer for handling crash animations.
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.
uint8_t state; ///< State of the airport. @see AirportMovementStates
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.
StationID targetairport; ///< Airport to go to next.
byte state; ///< State of the airport. @see AirportMovementStates
Direction last_direction;
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
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
AircraftCache acache;
@ -116,7 +114,6 @@ struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
void OnPeriodic() override;
uint Crash(bool flooded = false) override;
TileIndex GetOrderStationLocation(StationID station) override;
TileIndex GetCargoTile() const override { return this->First()->tile; }
ClosestDepot FindClosestDepot() override;
/**
@ -148,6 +145,6 @@ void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteS
Station *GetTargetAirportIfValid(const Aircraft *v);
void HandleMissingAircraftOrders(Aircraft *v);
const char *AirportMovementStateToString(uint8_t state);
const char *AirportMovementStateToString(byte state);
#endif /* AIRCRAFT_H */

@ -133,7 +133,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) == 0)) {
(v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT)) {
last_dest = Station::GetIfValid(v->last_station_visited);
next_dest = Station::GetIfValid(v->current_order.GetDestination());
} else {
@ -486,7 +486,6 @@ void Aircraft::OnNewDay()
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
if (!EconTime::UsingWallclockUnits()) AgeVehicle(this);
EconomyAgeVehicle(this);
}
void Aircraft::OnPeriodic()
@ -692,7 +691,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
* ~ acceleration * 77 (km-ish/h / 256)
*/
uint spd = v->acceleration * 77;
uint8_t t;
byte t;
/* Adjust speed limits by plane speed factor to prevent taxiing
* and take-off speeds being too low. */
@ -710,7 +709,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
speed_limit = v->vcache.cached_max_speed;
}
v->subspeed = (t = v->subspeed) + (uint8_t)spd;
v->subspeed = (t = v->subspeed) + (byte)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
@ -737,7 +736,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
spd = v->GetOldAdvanceSpeed(spd);
spd += v->progress;
v->progress = (uint8_t)spd;
v->progress = (byte)spd;
return spd >> 8;
}
@ -861,7 +860,7 @@ template int GetAircraftFlightLevel(Aircraft *v, bool takeoff);
* @param rotation The rotation of the airport.
* @return The index of the entry point
*/
static uint8_t AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
{
assert(v != nullptr);
assert(apc != nullptr);
@ -1269,13 +1268,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, MapMaxX() * TILE_SIZE), Clamp(v->y_pos, 0, MapMaxY() * 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) {
@ -1775,7 +1771,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 */
uint8_t landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
const AirportFTA *current = apc->layout[v->pos].next;
while (current != nullptr) {
if (current->heading == landingtype) {
@ -1922,8 +1918,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) {
uint8_t prev_pos = v->pos; // location could be changed in state, so save it before-hand
uint8_t prev_state = v->state;
byte prev_pos = v->pos; // location could be changed in state, so save it before-hand
byte 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);
@ -2059,7 +2055,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, uint8_t i, uint8_t last_terminal)
static bool FreeTerminal(Aircraft *v, byte i, byte last_terminal)
{
assert(last_terminal <= lengthof(_airport_terminal_mapping));
Station *st = Station::Get(v->targetairport);
@ -2259,8 +2255,8 @@ bool Aircraft::Tick()
}
if (HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE)) {
extern uint8_t MapAircraftMovementState(const Aircraft *v);
uint8_t state = MapAircraftMovementState(this);
extern byte MapAircraftMovementState(const Aircraft *v);
byte state = MapAircraftMovementState(this);
if (state != this->acache.image_movement_state) {
this->InvalidateImageCacheOfChain();
this->acache.image_movement_state = state;
@ -2317,7 +2313,7 @@ void UpdateAirplanesOnNewStation(const Station *st)
if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, true);
}
const char *AirportMovementStateToString(uint8_t state)
const char *AirportMovementStateToString(byte state)
{
#define AMS(s) case s: return #s;
switch (state) {

@ -110,12 +110,12 @@ AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Directi
AirportFTAClass::AirportFTAClass(
const AirportMovingData *moving_data_,
const uint8_t *terminals_,
const uint8_t num_helipads_,
const uint8_t *entry_points_,
const byte *terminals_,
const byte num_helipads_,
const byte *entry_points_,
Flags flags_,
const AirportFTAbuildup *apFA,
uint8_t delta_z_
byte 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 uint8_t airport_type)
const AirportFTAClass *GetAirport(const byte airport_type)
{
if (airport_type == AT_DUMMY) return &_airportfta_dummy;
return AirportSpec::Get(airport_type)->fsm;
@ -215,7 +215,7 @@ const AirportFTAClass *GetAirport(const uint8_t 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
*/
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile)
byte 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 uint8_t *terminals,
const uint8_t num_helipads,
const uint8_t *entry_points,
const byte *terminals,
const byte num_helipads,
const byte *entry_points,
Flags flags,
const AirportFTAbuildup *apFA,
uint8_t delta_z
byte 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(uint8_t position) const
const AirportMovingData *MovingData(byte 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 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.
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.
Flags flags; ///< Flags for this airport type.
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
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
};
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
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
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
};
const AirportFTAClass *GetAirport(const uint8_t airport_type);
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile);
const AirportFTAClass *GetAirport(const byte airport_type);
byte GetVehiclePosOnBuild(TileIndex hangar_tile);
#endif /* AIRPORT_H */

@ -22,8 +22,7 @@
#include "station_type.h"
#include "newgrf_airport.h"
#include "newgrf_callbacks.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
#include "widgets/dropdown_type.h"
#include "core/geometry_func.hpp"
#include "hotkeys.h"
#include "vehicle_func.h"
@ -37,11 +36,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 uint8_t _selected_airport_layout; ///< selected airport layout number.
static byte _selected_airport_layout; ///< selected airport layout number.
static void ShowBuildAirportPicker(Window *parent);
SpriteID GetCustomAirportSprite(const AirportSpec *as, uint8_t layout);
SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout);
void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32_t p1, uint32_t p2, uint64_t p3, uint32_t cmd)
{
@ -233,8 +232,8 @@ class BuildAirportWindow : public PickerWindowBase {
{
DropDownList list;
for (const auto &cls : AirportClass::Classes()) {
list.push_back(MakeDropDownListStringItem(cls.name, cls.Index()));
for (uint i = 0; AirportClass::IsClassIDValid((AirportClassID)i); i++) {
list.push_back(std::make_unique<DropDownListStringItem>(AirportClass::Get((AirportClassID)i)->name, i, false));
}
return list;
@ -309,17 +308,17 @@ public:
}
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
switch (widget) {
case WID_AP_CLASS_DROPDOWN: {
Dimension d = {0, 0};
for (const auto &cls : AirportClass::Classes()) {
d = maxdim(d, GetStringBoundingBox(cls.name));
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
d = maxdim(d, GetStringBoundingBox(AirportClass::Get((AirportClassID)i)->name));
}
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -328,11 +327,11 @@ public:
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
size.width = std::max(size.width, GetStringBoundingBox(as->name).width + padding.width);
size->width = std::max(size->width, GetStringBoundingBox(as->name).width + padding.width);
}
this->line_height = GetCharacterHeight(FS_NORMAL) + padding.height;
size.height = 5 * this->line_height;
size->height = 5 * this->line_height;
break;
}
@ -340,13 +339,13 @@ public:
for (int i = 0; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) {
for (byte layout = 0; layout < as->num_table; layout++) {
SpriteID sprite = GetCustomAirportSprite(as, layout);
if (sprite != 0) {
Dimension d = GetSpriteSize(sprite);
d.width += WidgetDimensions::scaled.framerect.Horizontal();
d.height += WidgetDimensions::scaled.framerect.Vertical();
size = maxdim(d, size);
*size = maxdim(d, *size);
}
}
}
@ -356,12 +355,12 @@ public:
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
for (uint8_t layout = 0; layout < as->num_table; layout++) {
for (byte layout = 0; layout < as->num_table; layout++) {
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
if (string == STR_UNDEFINED) continue;
Dimension d = GetStringMultiLineBoundingBox(string, size);
size = maxdim(d, size);
Dimension d = GetStringMultiLineBoundingBox(string, *size);
*size = maxdim(d, *size);
}
}
break;
@ -488,8 +487,8 @@ public:
break;
case WID_AP_AIRPORT_LIST: {
int32_t num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
if (num_clicked == INT32_MAX) break;
int num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
if (num_clicked == INT_MAX) break;
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
break;
@ -538,12 +537,14 @@ public:
if (change_class) {
/* If that fails, select the first available airport
* from the first class where airports are available. */
for (const auto &cls : AirportClass::Classes()) {
for (const auto &as : cls.Specs()) {
for (AirportClassID j = APC_BEGIN; j < APC_MAX; j++) {
AirportClass *apclass = AirportClass::Get(j);
for (uint i = 0; i < apclass->GetSpecCount(); i++) {
const AirportSpec *as = apclass->GetSpec(i);
if (as->IsAvailable()) {
_selected_airport_class = cls.Index();
this->vscroll->SetCount(cls.GetSpecCount());
this->SelectOtherAirport(as->GetIndex());
_selected_airport_class = j;
this->vscroll->SetCount(apclass->GetSpecCount());
this->SelectOtherAirport(i);
return;
}
}

@ -8,7 +8,6 @@
/** @file articulated_vehicles.cpp Implementation of articulated vehicles. */
#include "stdafx.h"
#include "articulated_vehicles.h"
#include "core/bitmath_func.hpp"
#include "core/random_func.hpp"
#include "train.h"
@ -142,23 +141,15 @@ void GetArticulatedPartsEngineIDs(EngineID engine_type, bool purchase_window, st
* Returns the default (non-refitted) capacity of a specific EngineID.
* @param engine the EngineID of interest
* @param cargo_type returns the default cargo type, if needed
* @param attempt_refit cargo ID to attempt to use
* @return capacity
*/
static inline uint16_t GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_type, CargoID attempt_refit = INVALID_CARGO)
static inline uint16_t GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_type)
{
const Engine *e = Engine::Get(engine);
CargoID cargo = INVALID_CARGO;
if (e->CanCarryCargo()) {
if (attempt_refit != INVALID_CARGO && HasBit(e->info.refit_mask, attempt_refit)) {
cargo = attempt_refit;
} else {
cargo = e->GetDefaultCargoType();
}
}
CargoID cargo = (e->CanCarryCargo() ? e->GetDefaultCargoType() : INVALID_CARGO);
if (cargo_type != nullptr) *cargo_type = cargo;
if (cargo == INVALID_CARGO) return 0;
return e->GetDisplayDefaultCapacity(nullptr, cargo);
return e->GetDisplayDefaultCapacity();
}
/**
@ -184,20 +175,16 @@ static inline CargoTypes GetAvailableVehicleCargoTypes(EngineID engine, bool inc
/**
* Get the capacity of the parts of a given engine.
* @param engine The engine to get the capacities from.
* @param attempt_refit Attempt to get capacity when refitting to this cargo.
* @return The cargo capacities.
*/
CargoArray GetCapacityOfArticulatedParts(EngineID engine, CargoID attempt_refit)
CargoArray GetCapacityOfArticulatedParts(EngineID engine)
{
CargoArray capacity{};
const Engine *e = Engine::Get(engine);
auto get_engine_cargo = [&capacity, attempt_refit](EngineID eng) {
CargoID cargo_type;
uint16_t cargo_capacity = GetVehicleDefaultCapacity(eng, &cargo_type, attempt_refit);
if (cargo_type < NUM_CARGO) capacity[cargo_type] += cargo_capacity;
};
get_engine_cargo(engine);
CargoID cargo_type;
uint16_t cargo_capacity = GetVehicleDefaultCapacity(engine, &cargo_type);
if (cargo_type < NUM_CARGO) capacity[cargo_type] = cargo_capacity;
if (!e->IsArticulatedCallbackVehicleType()) return capacity;
@ -207,7 +194,8 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine, CargoID attempt_refit)
EngineID artic_engine = GetNextArticulatedPart(i, engine);
if (artic_engine == INVALID_ENGINE) break;
get_engine_cargo(artic_engine);
cargo_capacity = GetVehicleDefaultCapacity(artic_engine, &cargo_type);
if (cargo_type < NUM_CARGO) capacity[cargo_type] += cargo_capacity;
}
return capacity;

@ -16,7 +16,7 @@
uint CountArticulatedParts(EngineID engine_type, bool purchase_window);
void GetArticulatedPartsEngineIDs(EngineID engine_type, bool purchase_window, std::vector<EngineID> &ids);
CargoArray GetCapacityOfArticulatedParts(EngineID engine, CargoID attempt_refit = INVALID_CARGO);
CargoArray GetCapacityOfArticulatedParts(EngineID engine);
CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine);
void AddArticulatedParts(Vehicle *first);
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask);

@ -343,7 +343,7 @@ static CommandCost BuildReplacementMultiPartShipSimple(EngineID e, const Vehicle
for (; v != nullptr && old != nullptr; v = v->Next(), old = old->Next()) {
if (old->cargo_type == INVALID_CARGO) continue;
uint8_t subtype = GetBestFittingSubType(old, v, old->cargo_type);
byte subtype = GetBestFittingSubType(old, v, old->cargo_type);
CommandCost refit_cost = DoCommand(0, v->index, old->cargo_type | (subtype << 8) | (1 << 16), DC_EXEC, GetCmdRefitVeh(v));
if (refit_cost.Succeeded()) cost.AddCost(refit_cost);
}
@ -396,7 +396,7 @@ static CommandCost BuildReplacementMultiPartShip(EngineID e, const Vehicle *old_
CargoID c = FindFirstBit(available);
assert(old_cargo_vehs[c] != nullptr);
uint8_t subtype = GetBestFittingSubType(old_cargo_vehs[c], v, c);
byte subtype = GetBestFittingSubType(old_cargo_vehs[c], v, c);
CommandCost refit_cost = DoCommand(0, v->index, c | (subtype << 8) | (1 << 16), DC_EXEC, GetCmdRefitVeh(v));
if (refit_cost.Succeeded()) cost.AddCost(refit_cost);
}
@ -453,7 +453,7 @@ static CommandCost BuildReplacementMultiPartShip(EngineID e, const Vehicle *old_
if (c == INVALID_CARGO) continue;
assert(old_cargo_vehs[c] != nullptr);
uint8_t subtype = GetBestFittingSubType(old_cargo_vehs[c], v, c);
byte subtype = GetBestFittingSubType(old_cargo_vehs[c], v, c);
CommandCost refit_cost = DoCommand(0, v->index, c | (subtype << 8) | (1 << 16), DC_EXEC, GetCmdRefitVeh(v));
if (refit_cost.Succeeded()) cost.AddCost(refit_cost);
}
@ -514,7 +514,7 @@ static CommandCost BuildReplacementVehicle(const Vehicle *old_veh, Vehicle **new
/* Refit the vehicle if needed */
if (refit_cargo != CARGO_NO_REFIT) {
uint8_t subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
cost.AddCost(DoCommand(0, new_veh->index, refit_cargo | (subtype << 8), DC_EXEC, GetCmdRefitVeh(new_veh)));
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
@ -557,9 +557,8 @@ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after,
* @param old_head The old front vehicle (no wagons attached anymore)
* @param new_head The new head of the completely replaced vehicle chain
* @param flags the command flags to use
* @param start_stop_check whether to run the start-stop check
*/
CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoCommandFlag flags, bool start_stop_check)
CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoCommandFlag flags)
{
CommandCost cost = CommandCost();
@ -570,7 +569,7 @@ CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoComma
if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(0, old_head->group_id, new_head->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP));
/* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */
if (start_stop_check && cost.Succeeded()) {
if (cost.Succeeded()) {
/* Start the vehicle, might be denied by certain things */
assert((new_head->vehstatus & VS_STOPPED) != 0);
cost.AddCost(CmdStartStopVehicle(new_head, true));
@ -778,6 +777,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
/* Sell superfluous new vehicles that could not be inserted. */
if (cost.Succeeded() && wagon_removal) {
assert(Train::From(new_head)->gcache.cached_total_length <= _settings_game.vehicle.max_train_length * TILE_SIZE);
for (auto it = std::next(std::begin(replacements)); it != std::end(replacements); ++it) {
Vehicle *wagon = it->new_veh;
if (wagon == nullptr) continue;
@ -797,7 +797,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
}
/* The new vehicle chain is constructed, now take over orders and everything... */
if (cost.Succeeded()) cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags, true));
if (cost.Succeeded()) cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags));
if (cost.Succeeded()) {
/* Success ! */
@ -864,7 +864,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
*nothing_to_do = false;
/* The new vehicle is constructed, now take over orders and everything... */
cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags, true));
cost.AddCost(CopyHeadSpecificThings(old_head, new_head, flags));
if (cost.Succeeded()) {
/* The new vehicle is constructed, now take over cargo */

@ -97,7 +97,7 @@ inline CommandCost RemoveEngineReplacementForCompany(Company *c, EngineID engine
bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company);
CommandCost CopyHeadSpecificThings(Vehicle*, Vehicle*, DoCommandFlag, bool start_stop_check);
CommandCost CopyHeadSpecificThings(Vehicle*, Vehicle*, DoCommandFlag);
bool AutoreplaceMultiPartShipWouldSucceed(EngineID e, const Vehicle *old_veh, CargoTypes all_cargoes);

@ -24,14 +24,15 @@
#include "core/geometry_func.hpp"
#include "rail_gui.h"
#include "road_gui.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
#include "widgets/dropdown_func.h"
#include "widgets/autoreplace_widget.h"
#include "safeguards.h"
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b, const GUIEngineListSortCache &cache)
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);
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
return Engine::Get(a.engine_id)->list_position < Engine::Get(b.engine_id)->list_position;
}
@ -82,7 +83,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).
uint8_t sort_criteria; ///< Criteria of sorting vehicles.
byte 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.
@ -110,6 +111,27 @@ class ReplaceVehicleWindow : public Window {
return true;
}
void AddChildren(const GUIEngineList &source, GUIEngineList &target, EngineID parent, int indent, int side)
{
for (const auto &item : source) {
if (item.variant_id != parent || item.engine_id == parent) continue;
const Engine *e = Engine::Get(item.engine_id);
EngineDisplayFlags flags = item.flags;
if (e->display_last_variant != INVALID_ENGINE) flags &= ~EngineDisplayFlags::Shaded;
target.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent);
/* Add variants if not folded */
if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) {
/* Add this engine again as a child */
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) {
target.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1);
}
AddChildren(source, target, item.engine_id, indent + 1, side);
}
}
}
/**
* Generate an engines list
* @param draw_left true if generating the left list, otherwise false
@ -119,7 +141,7 @@ class ReplaceVehicleWindow : public Window {
std::vector<EngineID> variants;
EngineID selected_engine = INVALID_ENGINE;
VehicleType type = (VehicleType)this->window_number;
uint8_t side = draw_left ? 0 : 1;
byte side = draw_left ? 0 : 1;
GUIEngineList list;
@ -183,7 +205,7 @@ class ReplaceVehicleWindow : public Window {
this->engines[side].clear();
if (side == 1) {
GUIEngineListAddChildren(this->engines[side], list);
AddChildren(list, this->engines[side], INVALID_ENGINE, 0, side);
} else {
this->engines[side].swap(list);
}
@ -293,26 +315,26 @@ public:
this->sel_group = id_g;
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
switch (widget) {
case WID_RV_SORT_ASCENDING_DESCENDING: {
Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
case WID_RV_LEFT_MATRIX:
case WID_RV_RIGHT_MATRIX:
resize.height = GetEngineListHeight((VehicleType)this->window_number);
size.height = (this->window_number <= VEH_ROAD ? 8 : 4) * resize.height;
resize->height = GetEngineListHeight((VehicleType)this->window_number);
size->height = (this->window_number <= VEH_ROAD ? 8 : 4) * resize->height;
break;
case WID_RV_LEFT_DETAILS:
case WID_RV_RIGHT_DETAILS:
size.height = GetCharacterHeight(FS_NORMAL) * this->details_height + padding.height;
size->height = GetCharacterHeight(FS_NORMAL) * this->details_height + padding.height;
break;
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
@ -323,7 +345,7 @@ public:
d = maxdim(d, GetStringBoundingBox(str));
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -332,7 +354,7 @@ public:
d = maxdim(d, GetStringBoundingBox(STR_REPLACE_WAGONS));
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -341,7 +363,7 @@ public:
d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED));
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -352,7 +374,7 @@ public:
}
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -363,7 +385,7 @@ public:
}
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
@ -374,7 +396,7 @@ public:
}
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
}
@ -465,9 +487,11 @@ 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], *this->vscroll[side], this->sel_engine[side], side == 0, this->sel_group);
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
break;
}
}
@ -540,8 +564,8 @@ public:
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
DropDownList list;
list.push_back(MakeDropDownListStringItem(STR_REPLACE_ENGINES, 1));
list.push_back(MakeDropDownListStringItem(STR_REPLACE_WAGONS, 0));
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ENGINES, 1, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_WAGONS, 0, false));
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
break;
}
@ -584,7 +608,7 @@ public:
case WID_RV_LEFT_MATRIX:
case WID_RV_RIGHT_MATRIX: {
uint8_t click_side;
byte click_side;
if (widget == WID_RV_LEFT_MATRIX) {
click_side = 0;
} else {

@ -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);
uint8_t *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
byte *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
uint8_t tracknr; ///< track number of song displayed in UI
byte 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. */
uint8_t num_available;
byte num_available;
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
};

@ -22,15 +22,17 @@
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
extern StationPool _station_pool;
template <typename T>
struct SpecMapping {
const T *spec; ///< Custom spec.
struct StationSpecList {
const StationSpec *spec;
uint32_t grfid; ///< GRF ID of this custom station
uint16_t localidx; ///< Station ID within GRF of station
};
using StationSpecList = SpecMapping<StationSpec>;
using RoadStopSpecList = SpecMapping<RoadStopSpec>;
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
};
struct RoadStopTileData {
TileIndex tile;
@ -80,8 +82,8 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
std::vector<RoadStopSpecList> roadstop_speclist; ///< List of road stop specs of this station
uint16_t random_bits; ///< Random bits assigned to this station
uint8_t waiting_triggers; ///< Waiting triggers (NewGRF) for this station
uint8_t delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station
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 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
@ -119,7 +121,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, uint16_t variable, uint8_t parameter, bool *available) const = 0;
virtual uint32_t GetNewGRFVariable(const struct ResolverObject &object, uint16_t variable, byte parameter, bool *available) const = 0;
/**
* Update the coordinated of the sign (as shown in the viewport).
@ -195,7 +197,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
return (this->facilities & facilities) != 0;
}
inline uint8_t GetRoadStopRandomBits(TileIndex tile) const
inline byte GetRoadStopRandomBits(TileIndex tile) const
{
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
if (tile_data.tile == tile) return tile_data.random_bits;
@ -203,7 +205,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
return 0;
}
inline uint8_t GetRoadStopAnimationFrame(TileIndex tile) const
inline byte GetRoadStopAnimationFrame(TileIndex tile) const
{
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
if (tile_data.tile == tile) return tile_data.animation_frame;
@ -212,11 +214,11 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
}
private:
bool SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation);
bool SetRoadStopTileData(TileIndex tile, byte data, bool animation);
public:
inline void SetRoadStopRandomBits(TileIndex tile, uint8_t random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
inline bool SetRoadStopAnimationFrame(TileIndex tile, uint8_t frame) { return this->SetRoadStopTileData(tile, frame, true); }
inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
inline bool SetRoadStopAnimationFrame(TileIndex tile, byte frame) { return this->SetRoadStopTileData(tile, frame, true); }
void RemoveRoadStopTileData(TileIndex tile);
static void PostDestructor(size_t index);
@ -321,14 +323,4 @@ 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 */

@ -36,14 +36,14 @@ 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 uint8_t *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
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);
}
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 uint8_t *remap = bp->remap; // store so we don't have to access it via bp every time
const byte *remap = bp->remap; // store so we don't have to access it via bp every time
const int width = bp->width;
const int pitch = bp->pitch;
const int anim_pitch = this->anim_buf_pitch;
@ -54,10 +54,10 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
Colour *dst_ln = dst + pitch;
uint16_t *anim_ln = anim + anim_pitch;
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_px++;
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
Colour *dst_end = dst;

@ -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 uint8_t * const remap = bp->remap;
const byte * 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 uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
const Colour *src_rgba_line = (const Colour *) ((const byte *) &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 uint8_t m0 = mvX2;
const byte m0 = mvX2;
if (m0 >= PALETTE_ANIM_START) {
const Colour c0 = (this->LookupColourInPalette(m0).data & 0x00FFFFFF) | (src[0].data & 0xFF000000);
InsertFirstUint32(AdjustBrightneSSE(c0, (uint8_t) (mvX2 >> 8)).data, srcABCD);
InsertFirstUint32(AdjustBrightneSSE(c0, (byte) (mvX2 >> 8)).data, srcABCD);
}
const uint8_t m1 = mvX2 >> 16;
const byte m1 = mvX2 >> 16;
if (m1 >= PALETTE_ANIM_START) {
const Colour c1 = (this->LookupColourInPalette(m1).data & 0x00FFFFFF) | (src[1].data & 0xFF000000);
InsertSecondUint32(AdjustBrightneSSE(c1, (uint8_t) (mvX2 >> 24)).data, srcABCD);
InsertSecondUint32(AdjustBrightneSSE(c1, (byte) (mvX2 >> 24)).data, srcABCD);
}
/* Update anim buffer. */
const uint8_t a0 = src[0].a;
const uint8_t a1 = src[1].a;
const byte a0 = src[0].a;
const byte 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 = (uint8_t) mvX2;
const uint m0 = (byte) mvX2;
const uint r0 = remap[m0];
const uint m1 = (uint8_t) (mvX2 >> 16);
const uint m1 = (byte) (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 = (uint8_t) (m_m); \
const uint m = (byte) (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 uint8_t a0 = src[0].a;
const uint8_t a1 = src[1].a;
const byte a0 = src[0].a;
const byte a1 = src[1].a;
uint32_t anim01 = mvX2 & 0xFF00FF00;
if (a0 == 255) {
anim01 |= r0;
@ -437,7 +437,7 @@ bmcr_alpha_blend_single_brightness:
next_line:
if (mode != BM_TRANSPARENT && mode != BM_TRANSPARENT_REMAP) src_mv_line += si->sprite_width;
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
dst_line += bp->pitch;
anim_line += this->anim_buf_pitch;
}

@ -41,26 +41,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 uint8_t *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
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);
}
/* 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 uint8_t *remap = bp->remap;
const byte *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 uint8_t *)src_px + *(const uint32_t *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)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 uint8_t *)src_n + *(const uint32_t *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
/* we will end this line when we reach this point */
@ -317,9 +317,9 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
ZoomLevel zoom_max;
uint8_t missing_zoom_levels = 0;
if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_MIN;
zoom_max = ZOOM_LVL_MIN;
if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_NORMAL;
zoom_max = ZOOM_LVL_NORMAL;
} else {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = (ZoomLevel) std::min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
@ -459,8 +459,8 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
dst_n_ln = (uint32_t *)dst_n;
}
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];
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];
px_buffer_next = (Colour *)dst_px_ln;
n_buffer_next = (uint16_t *)dst_n_ln;
@ -478,10 +478,10 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
missing_zoom_levels = UINT8_MAX;
}
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dest_sprite->next = nullptr;
dest_sprite->missing_zoom_levels = missing_zoom_levels;

@ -19,7 +19,7 @@ public:
struct SpriteData {
BlitterSpriteFlags flags;
uint32_t offset[ZOOM_LVL_SPR_COUNT][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
uint8_t data[]; ///< Data, all zoomlevels.
byte data[]; ///< Data, all zoomlevels.
};
Blitter_32bppOptimized()

@ -137,19 +137,19 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
Blitter_32bppSimple::Pixel *dst;
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_MIN].height * (size_t)sprite[ZOOM_LVL_MIN].width * sizeof(*dst));
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width * sizeof(*dst));
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dest_sprite->next = nullptr;
dest_sprite->missing_zoom_levels = 0;
dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data;
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_MIN].data;
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_NORMAL].data;
for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) {
for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) {
if (src->m == 0) {
dst[i].r = src->r;
dst[i].g = src->g;

@ -26,10 +26,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
* Second uint32_t of a line = the number of transparent pixels from the right.
* Then all RGBA then all MV.
*/
ZoomLevel zoom_min = ZOOM_LVL_MIN;
ZoomLevel zoom_max = ZOOM_LVL_MIN;
ZoomLevel zoom_min = ZOOM_LVL_NORMAL;
ZoomLevel zoom_max = ZOOM_LVL_NORMAL;
uint8_t missing_zoom_levels = 0;
if (sprite[ZOOM_LVL_MIN].type != SpriteType::Font) {
if (sprite[ZOOM_LVL_NORMAL].type != SpriteType::Font) {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = (ZoomLevel) std::min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
@ -62,10 +62,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
}
Sprite *dst_sprite = (Sprite *) allocator(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size);
dst_sprite->height = sprite[ZOOM_LVL_MIN].height;
dst_sprite->width = sprite[ZOOM_LVL_MIN].width;
dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dst_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dst_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dst_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dst_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dst_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dst_sprite->next = nullptr;
dst_sprite->missing_zoom_levels = missing_zoom_levels;
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
@ -142,7 +142,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*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
dst_rgba_line = (Colour*) ((byte*) dst_rgba_line + sd.infos[z].sprite_line_size);
/* Count the number of transparent pixels from the right. */
dst_rgba = dst_rgba_line - 1;

@ -61,7 +61,7 @@ public:
struct SpriteData {
BlitterSpriteFlags flags;
SpriteInfo infos[ZOOM_LVL_SPR_COUNT];
uint8_t data[]; ///< Data, all zoomlevels.
byte data[]; ///< Data, all zoomlevels.
};
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);

@ -10,17 +10,10 @@
#ifndef BLITTER_32BPP_SSE_FUNC_HPP
#define BLITTER_32BPP_SSE_FUNC_HPP
/* ATTENTION
* This file is compiled multiple times with different defines for SSE_VERSION and MARGIN_NORMAL_THRESHOLD.
* Be careful when declaring things with external linkage.
* Use internal linkage instead, i.e. "static".
*/
#define INTERNAL_LINKAGE static
#ifdef WITH_SSE
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline void InsertFirstUint32(const uint32_t value, __m128i &into)
inline void InsertFirstUint32(const uint32_t value, __m128i &into)
{
#if (SSE_VERSION >= 4)
into = _mm_insert_epi32(into, value, 0);
@ -31,7 +24,7 @@ INTERNAL_LINKAGE inline void InsertFirstUint32(const uint32_t value, __m128i &in
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline void InsertSecondUint32(const uint32_t value, __m128i &into)
inline void InsertSecondUint32(const uint32_t value, __m128i &into)
{
#if (SSE_VERSION >= 4)
into = _mm_insert_epi32(into, value, 1);
@ -42,7 +35,7 @@ INTERNAL_LINKAGE inline void InsertSecondUint32(const uint32_t value, __m128i &i
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline void LoadUint64(const uint64_t value, __m128i &into)
inline void LoadUint64(const uint64_t value, __m128i &into)
{
#ifdef POINTER_IS_64BIT
into = _mm_cvtsi64_si128(value);
@ -57,7 +50,7 @@ INTERNAL_LINKAGE inline void LoadUint64(const uint64_t value, __m128i &into)
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
{
#if (SSE_VERSION == 2)
from = _mm_and_si128(from, mask); // PAND, wipe high bytes to keep low bytes when packing
@ -68,7 +61,7 @@ INTERNAL_LINKAGE inline __m128i PackUnsaturated(__m128i from, const __m128i &mas
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
{
#if (SSE_VERSION == 2)
__m128i alphaAB = _mm_shufflelo_epi16(from, 0x3F); // PSHUFLW, put alpha1 in front of each rgb1
@ -80,7 +73,7 @@ INTERNAL_LINKAGE inline __m128i DistributeAlpha(const __m128i from, const __m128
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask)
inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask)
{
__m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); // PUNPCKLBW, expand each uint8_t into uint16
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
@ -104,7 +97,7 @@ INTERNAL_LINKAGE inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, co
* rgb = rgb * ((256/4) * 4 - (alpha/4)) / ((256/4) * 4)
*/
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base)
inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base)
{
__m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128());
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
@ -118,7 +111,7 @@ INTERNAL_LINKAGE inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const
IGNORE_UNINITIALIZED_WARNING_START
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness)
static Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness)
{
uint64_t c16 = colour.b | (uint64_t) colour.g << 16 | (uint64_t) colour.r << 32;
c16 *= brightness;
@ -152,7 +145,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP
/** ReallyAdjustBrightness() is not called that often.
* Inlining this function implies a far jump, which has a huge latency.
*/
INTERNAL_LINKAGE inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness. */
if (likely(brightness == Blitter_32bppBase::DEFAULT_BRIGHTNESS)) return colour;
@ -161,7 +154,7 @@ INTERNAL_LINKAGE inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightne
}
GNU_TARGET(SSE_TARGET)
INTERNAL_LINKAGE inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m128i from, [[maybe_unused]] uint32_t brightness)
inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m128i from, [[maybe_unused]] uint32_t brightness)
{
#if (SSE_VERSION < 3)
NOT_REACHED();
@ -221,7 +214,7 @@ inline void Blitter_32bppSSSE3::Draw(const Blitter::BlitterParams *bp, ZoomLevel
inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
#endif
{
const uint8_t * const remap = bp->remap;
const byte * const remap = bp->remap;
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
int effective_width = bp->width;
@ -229,7 +222,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 uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
const Colour *src_rgba_line = (const Colour *) ((const byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
uint32_t bm_normal_brightness = 0;
if (mode == BM_NORMAL_WITH_BRIGHTNESS) {
@ -320,7 +313,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 = (uint8_t) (m_m); \
const uint m = (byte) (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; \
@ -503,7 +496,7 @@ bmcr_alpha_blend_single_brightness:
next_line:
if (mode == BM_COLOUR_REMAP || mode == BM_CRASH_REMAP || mode == BM_COLOUR_REMAP_WITH_BRIGHTNESS) src_mv_line += si->sprite_width;
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
dst_line += bp->pitch;
}
}

@ -10,12 +10,6 @@
#ifndef BLITTER_32BPP_SSE_TYPE_H
#define BLITTER_32BPP_SSE_TYPE_H
/* ATTENTION
* This file is compiled multiple times with different defines for SSE_VERSION.
* Be careful when declaring things with external linkage.
* Use internal linkage instead, i.e. "static".
*/
#ifdef WITH_SSE
#include "32bpp_simple.hpp"
@ -28,7 +22,7 @@
#endif
#define META_LENGTH 2 ///< Number of uint32_t inserted before each line of pixels in a sprite.
#define MARGIN_NORMAL_THRESHOLD (zoom == ZOOM_LVL_OUT_8X ? 8 : 4) ///< Minimum width to use margins with BM_NORMAL.
#define MARGIN_NORMAL_THRESHOLD (zoom == ZOOM_LVL_OUT_32X ? 8 : 4) ///< Minimum width to use margins with BM_NORMAL.
#define MARGIN_REMAP_THRESHOLD 4 ///< Minimum width to use margins with BM_COLOUR_REMAP.
#undef ALIGN

@ -167,8 +167,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 uint8_t *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
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);
}
/* skip lines in dst */
@ -177,7 +177,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 uint8_t *remap = bp->remap;
const byte *remap = bp->remap;
for (int y = 0; y < bp->height; y++) {
/* next dst line begins here */
@ -185,11 +185,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 uint8_t *)src_px + *(const uint32_t *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)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 uint8_t *)src_n + *(const uint32_t *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
/* we will end this line when we reach this point */

@ -129,9 +129,9 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
ZoomLevel zoom_min;
ZoomLevel zoom_max;
if (sprite[ZOOM_LVL_MIN].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_MIN;
zoom_max = ZOOM_LVL_MIN;
if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_NORMAL;
zoom_max = ZOOM_LVL_NORMAL;
} else {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = (ZoomLevel) std::min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
@ -148,10 +148,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<uint8_t> temp_buffer;
static ReusableBuffer<byte> temp_buffer;
SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
memset(temp_dst, 0, sizeof(*temp_dst));
uint8_t *dst = temp_dst->data;
byte *dst = temp_dst->data;
/* Make the sprites per zoom-level */
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
@ -167,7 +167,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
uint trans = 0;
uint pixels = 0;
uint last_colour = 0;
uint8_t *count_dst = nullptr;
byte *count_dst = nullptr;
/* Store the scaled image */
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
@ -214,7 +214,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
}
}
uint size = dst - (uint8_t *)temp_dst;
uint size = dst - (byte *)temp_dst;
/* Safety check, to make sure we guessed the size correctly */
assert(size < memory);
@ -222,10 +222,10 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
/* Allocate the exact amount of memory we need */
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size);
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dest_sprite->next = nullptr;
dest_sprite->missing_zoom_levels = 0;
memcpy(dest_sprite->data, temp_dst, size);

@ -19,7 +19,7 @@ public:
/** Data stored about a (single) sprite. */
struct SpriteData {
uint32_t offset[ZOOM_LVL_SPR_COUNT]; ///< Offsets (from .data) to streams for different zoom levels.
uint8_t data[]; ///< Data, all zoomlevels.
byte data[]; ///< Data, all zoomlevels.
};
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;

@ -65,18 +65,18 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
Sprite *dest_sprite;
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_MIN].height * (size_t)sprite[ZOOM_LVL_MIN].width);
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width);
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dest_sprite->next = nullptr;
dest_sprite->missing_zoom_levels = 0;
/* Copy over only the 'remap' channel, as that is what we care about in 8bpp */
for (int i = 0; i < sprite[ZOOM_LVL_MIN].height * sprite[ZOOM_LVL_MIN].width; i++) {
dest_sprite->data[i] = sprite[ZOOM_LVL_MIN].data[i].m;
for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) {
dest_sprite->data[i] = sprite[ZOOM_LVL_NORMAL].data[i].m;
}
return dest_sprite;

@ -58,7 +58,7 @@ public:
/** Parameters related to blitting. */
struct BlitterParams {
const void *sprite; ///< Pointer to the sprite how ever the encoder stored it
const uint8_t *remap; ///< XXX -- Temporary storage for remap array
const byte *remap; ///< XXX -- Temporary storage for remap array
int brightness_adjust; ///< Brightness adjustment
int skip_left; ///< How much pixels of the source to skip on the left (based on zoom of dst)

@ -94,7 +94,7 @@ public:
* @param name the blitter to select.
* @post Sets the blitter so GetCurrentBlitter() returns it too.
*/
static Blitter *SelectBlitter(const std::string_view name)
static Blitter *SelectBlitter(const std::string &name)
{
BlitterFactory *b = GetBlitterFactory(name);
if (b == nullptr) return nullptr;
@ -112,17 +112,17 @@ public:
* @param name the blitter factory to select.
* @return The blitter factory, or nullptr when there isn't one with the wanted name.
*/
static BlitterFactory *GetBlitterFactory(const std::string_view name)
static BlitterFactory *GetBlitterFactory(const std::string &name)
{
#if defined(DEDICATED)
const std::string_view default_blitter = "null";
const char *default_blitter = "null";
#elif defined(WITH_COCOA)
const std::string_view default_blitter = "32bpp-anim";
const char *default_blitter = "32bpp-anim";
#else
const std::string_view default_blitter = "8bpp-optimized";
const char *default_blitter = "8bpp-optimized";
#endif
if (GetBlitters().empty()) return nullptr;
const std::string_view bname = name.empty() ? default_blitter : name;
const char *bname = name.empty() ? default_blitter : name.c_str();
for (auto &it : GetBlitters()) {
BlitterFactory *b = it.second;

@ -20,10 +20,10 @@ Sprite *Blitter_Null::Encode(const SpriteLoader::SpriteCollection &sprite, Alloc
Sprite *dest_sprite;
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite));
dest_sprite->height = sprite[ZOOM_LVL_MIN].height;
dest_sprite->width = sprite[ZOOM_LVL_MIN].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dest_sprite->next = nullptr;
dest_sprite->missing_zoom_levels = 0;

@ -39,7 +39,7 @@ static inline bool EndOfBuffer(BmpBuffer *buffer)
return buffer->pos == buffer->read;
}
static inline uint8_t ReadByte(BmpBuffer *buffer)
static inline byte 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;
uint8_t pad = GB(4 - info->width / 8, 0, 2);
uint8_t *pixel_row;
uint8_t b;
byte pad = GB(4 - info->width / 8, 0, 2);
byte *pixel_row;
byte 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;
uint8_t pad = GB(4 - info->width / 2, 0, 2);
uint8_t *pixel_row;
uint8_t b;
byte pad = GB(4 - info->width / 2, 0, 2);
byte *pixel_row;
byte 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;
uint8_t *pixel = &data->bitmap[y * info->width];
byte *pixel = &data->bitmap[y * info->width];
while (y != 0 || x < info->width) {
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
uint8_t n = ReadByte(buffer);
uint8_t c = ReadByte(buffer);
byte n = ReadByte(buffer);
byte 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;
uint8_t dx = ReadByte(buffer);
uint8_t dy = ReadByte(buffer);
byte dx = ReadByte(buffer);
byte 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;
uint8_t b = ReadByte(buffer);
byte 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;
uint8_t pad = GB(4 - info->width, 0, 2);
uint8_t *pixel;
byte pad = GB(4 - info->width, 0, 2);
byte *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;
uint8_t *pixel = &data->bitmap[y * info->width];
byte *pixel = &data->bitmap[y * info->width];
while (y != 0 || x < info->width) {
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
uint8_t n = ReadByte(buffer);
uint8_t c = ReadByte(buffer);
byte n = ReadByte(buffer);
byte 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;
uint8_t dx = ReadByte(buffer);
uint8_t dy = ReadByte(buffer);
byte dx = ReadByte(buffer);
byte 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;
uint8_t pad = GB(4 - info->width * 3, 0, 2);
uint8_t *pixel_row;
byte pad = GB(4 - info->width * 3, 0, 2);
byte *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<uint8_t>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
data->bitmap = CallocT<byte>(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;
uint8_t *bitmap;
byte *bitmap;
};
#define BMP_BUFFER_SIZE 1024
struct BmpBuffer {
uint8_t data[BMP_BUFFER_SIZE];
byte data[BMP_BUFFER_SIZE];
int pos;
int read;
FILE *file;

@ -96,12 +96,12 @@ public:
this->Window::Close();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
if (widget == WID_BEM_MESSAGE) {
size = GetStringBoundingBox(STR_MISSING_GRAPHICS_ERROR);
size.width += WidgetDimensions::scaled.frametext.Horizontal();
size.height += WidgetDimensions::scaled.frametext.Vertical();
*size = GetStringBoundingBox(STR_MISSING_GRAPHICS_ERROR);
size->width += WidgetDimensions::scaled.frametext.Horizontal();
size->height += WidgetDimensions::scaled.frametext.Vertical();
}
}
@ -210,7 +210,7 @@ public:
this->Window::Close();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
/* We cache the button size. This is safe as no reinit can happen here. */
if (this->button_size.width == 0) {
@ -222,13 +222,13 @@ public:
switch (widget) {
case WID_BAFD_QUESTION:
/* The question is twice as wide as the buttons, and determine the height based on the width. */
size.width = this->button_size.width * 2;
size.height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size.width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical();
size->width = this->button_size.width * 2;
size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical();
break;
case WID_BAFD_YES:
case WID_BAFD_NO:
size = this->button_size;
*size = this->button_size;
break;
}
}
@ -384,9 +384,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 (Colours i = COLOUR_BEGIN; i != COLOUR_END; i++) {
for (ColourShade j = SHADE_BEGIN; j < SHADE_END; j++) {
SetColourGradient(i, j, offsets[i] + j);
for (uint i = 0; i != 16; i++) {
for (int j = 0; j < 8; j++) {
_colour_gradient[i][j] = offsets[i] + j;
}
}

@ -63,7 +63,7 @@ enum BridgeSpecCtrlFlags {
*/
struct BridgeSpec {
CalTime::Year avail_year; ///< the year where it becomes available
uint8_t min_length; ///< the minimum length (not counting start and end tile)
byte 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)
@ -72,9 +72,9 @@ 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
uint8_t flags; ///< bit 0 set: disable drawing of far pillars.
uint8_t ctrl_flags; ///< control flags
uint8_t pillar_flags[12]; ///< bridge pillar flags: 6 x pairs of x and y flags
byte flags; ///< bit 0 set: disable drawing of far pillars.
byte ctrl_flags; ///< control flags
byte pillar_flags[12]; ///< bridge pillar flags: 6 x pairs of x and y flags
};
extern BridgeSpec _bridge[MAX_BRIDGES];

@ -18,7 +18,7 @@
#include "gfx_func.h"
#include "tunnelbridge.h"
#include "sortlist_type.h"
#include "dropdown_func.h"
#include "widgets/dropdown_func.h"
#include "core/geometry_func.hpp"
#include "cmd_helper.h"
#include "tunnelbridge_map.h"
@ -189,14 +189,14 @@ public:
this->Window::Close();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
switch (widget) {
case WID_BBS_DROPDOWN_ORDER: {
Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
case WID_BBS_DROPDOWN_CRITERIA: {
@ -206,7 +206,7 @@ public:
}
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
*size = maxdim(*size, d);
break;
}
case WID_BBS_BRIDGE_LIST: {
@ -216,11 +216,11 @@ public:
sprite_dim = maxdim(sprite_dim, GetScaledSpriteSize(bridge_data.spec->sprite));
text_dim = maxdim(text_dim, GetStringBoundingBox(GetBridgeSelectString(bridge_data)));
}
resize.height = std::max(sprite_dim.height, text_dim.height) + padding.height; // Max of both sizes + account for matrix edges.
resize->height = std::max(sprite_dim.height, text_dim.height) + padding.height; // Max of both sizes + account for matrix edges.
this->icon_width = sprite_dim.width; // Width of bridge icon.
size.width = this->icon_width + WidgetDimensions::scaled.hsep_normal + text_dim.width + padding.width;
size.height = 4 * resize.height; // Smallest bridge gui is 4 entries high in the matrix.
size->width = this->icon_width + WidgetDimensions::scaled.hsep_normal + text_dim.width + padding.width;
size->height = 4 * resize->height; // Smallest bridge gui is 4 entries high in the matrix.
break;
}
}
@ -246,11 +246,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;
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->bridges);
for (auto it = first; it != last; ++it) {
const BridgeSpec *b = it->spec;
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;
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(*it));
DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(bridge_data));
tr = tr.Translate(0, this->resize.step_height);
}
break;
@ -373,7 +373,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, uint8_t road_rail_type)
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
{
CloseWindowByClass(WC_BUILD_BRIDGE);

@ -72,14 +72,15 @@ TileIndex GetOtherBridgeEnd(TileIndex tile)
*/
int GetBridgeHeight(TileIndex t)
{
auto [tileh, h] = GetTileSlopeZ(t);
int h;
Slope tileh = GetTileSlope(t, &h);
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);
}
robin_hood::unordered_flat_map<TileIndex, LongBridgeSignalStorage> _long_bridge_signal_sim_map;
std::unordered_map<TileIndex, LongBridgeSignalStorage> _long_bridge_signal_sim_map;
SignalState GetBridgeEntranceSimulatedSignalStateExtended(TileIndex t, uint16_t signal)
{

@ -360,7 +360,7 @@ inline bool IsCustomBridgeHeadTile(TileIndex t)
inline TrackBits GetBridgeReservationTrackBits(TileIndex t)
{
assert_tile(IsRailBridgeHeadTile(t), t);
uint8_t track_b = GB(_m[t].m2, 0, 3);
byte track_b = GB(_m[t].m2, 0, 3);
Track track = (Track)(track_b - 1); // map array saves Track+1
if (track_b == 0) return TRACK_BIT_NONE;
return (TrackBits)(TrackToTrackBits(track) | (HasBit(_m[t].m2, 3) ? TrackToTrackBits(TrackToOppositeTrack(track)) : 0));
@ -378,7 +378,7 @@ inline void SetBridgeReservationTrackBits(TileIndex t, TrackBits b)
assert(!TracksOverlap(b));
Track track = RemoveFirstTrack(&b);
SB(_m[t].m2, 0, 3, track == INVALID_TRACK ? 0 : track + 1);
SB(_m[t].m2, 3, 1, (uint8_t)(b != TRACK_BIT_NONE));
SB(_m[t].m2, 3, 1, (byte)(b != TRACK_BIT_NONE));
}

@ -15,21 +15,15 @@
#include "signal_type.h"
#include "core/bitmath_func.hpp"
#include "3rdparty/cpp-btree/btree_set.h"
#include "3rdparty/robin_hood/robin_hood.h"
#include <vector>
#include <unordered_map>
struct LongBridgeSignalStorage {
std::vector<uint64_t> signal_red_bits;
LongBridgeSignalStorage() = default;
LongBridgeSignalStorage(const LongBridgeSignalStorage &other) = delete;
LongBridgeSignalStorage(LongBridgeSignalStorage &&other) = default;
LongBridgeSignalStorage& operator=(const LongBridgeSignalStorage &other) = delete;
LongBridgeSignalStorage& operator=(LongBridgeSignalStorage &&other) = default;
};
extern robin_hood::unordered_flat_map<TileIndex, LongBridgeSignalStorage> _long_bridge_signal_sim_map;
extern std::unordered_map<TileIndex, LongBridgeSignalStorage> _long_bridge_signal_sim_map;
extern btree::btree_set<uint32_t> _bridge_signal_style_map;

File diff suppressed because it is too large Load Diff

@ -22,7 +22,7 @@ using CargoLabel = StrongType::Typedef<uint32_t, struct CargoLabelTag, StrongTyp
/**
* Cargo slots to indicate a cargo type within a game.
*/
using CargoID = uint8_t;
using CargoID = byte;
/**
* Available types of cargo
@ -50,7 +50,7 @@ static constexpr CargoLabel CT_FOOD = CargoLabel{'FOOD'};
/* Tropic */
static constexpr CargoLabel CT_RUBBER = CargoLabel{'RUBR'};
static constexpr CargoLabel CT_FRUIT = CargoLabel{'FRUT'};
static constexpr CargoLabel CT_FRUIT = CargoLabel{'FRUI'};
static constexpr CargoLabel CT_MAIZE = CargoLabel{'MAIZ'};
static constexpr CargoLabel CT_COPPER_ORE = CargoLabel{'CORE'};
static constexpr CargoLabel CT_WATER = CargoLabel{'WATR'};
@ -149,7 +149,7 @@ struct CargoArray : std::array<uint, NUM_CARGO> {
/** Types of cargo source and destination */
enum class SourceType : uint8_t {
enum class SourceType : byte {
Industry, ///< Source/destination is an industry
Town, ///< Source/destination is a town
Headquarters, ///< Source/destination are company headquarters

@ -102,7 +102,7 @@ void BuildCargoLabelMap()
_cargo_label_map.clear();
for (const CargoSpec &cs : CargoSpec::array) {
/* During initialization, CargoSpec can be marked valid before the label has been set. */
if (!cs.IsValid() || cs.label == CargoLabel{0} || cs.label == CT_INVALID) continue;
if (!cs.IsValid() || cs.label == CargoLabel{0}) continue;
/* Label already exists, don't add again. */
if (_cargo_label_map.count(cs.label) != 0) continue;

@ -19,7 +19,7 @@
#include <vector>
/** Town growth effect when delivering cargo. */
enum TownAcceptanceEffect : uint8_t {
enum TownAcceptanceEffect : byte {
TAE_BEGIN = 0,
TAE_NONE = TAE_BEGIN, ///< Cargo has no effect.
TAE_PASSENGERS, ///< Cargo behaves passenger-like.
@ -32,7 +32,7 @@ enum TownAcceptanceEffect : uint8_t {
};
/** Town effect when producing cargo. */
enum TownProductionEffect : uint8_t {
enum TownProductionEffect : byte {
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.
@ -61,7 +61,7 @@ enum CargoClass {
CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
};
static const uint8_t INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
static const uint TOWN_PRODUCTION_DIVISOR = 256;

@ -58,7 +58,7 @@ static int32_t _money_cheat_amount = 10000000;
*/
static int32_t ClickMoneyCheat(int32_t p1, int32_t p2)
{
DoCommandPEx(0, 0, 0, (uint64_t)(p2 * _money_cheat_amount), IsNetworkSettingsAdmin() ? CMD_MONEY_CHEAT_ADMIN : CMD_MONEY_CHEAT);
DoCommandPEx(0, 0, 0, (uint64_t)(p2 * _money_cheat_amount), _network_server || _network_settings_access ? CMD_MONEY_CHEAT_ADMIN : CMD_MONEY_CHEAT);
return _money_cheat_amount;
}
@ -120,7 +120,6 @@ static int32_t ClickChangeDateCheat(int32_t p1, int32_t p2)
/* Shift cached dates. */
LinkGraphSchedule::instance.ShiftDates(new_econ_date - EconTime::CurDate());
ShiftVehicleDates(new_econ_date - EconTime::CurDate());
EconTime::Detail::period_display_offset -= (p1 - EconTime::CurYear().base());
EconTime::Detail::SetDate(new_econ_date, new_econ_date_fract);
UpdateOrderUIOnDateChange();
@ -212,13 +211,13 @@ static bool IsCheatAllowed(CheatNetworkMode mode)
{
switch (mode) {
case CNM_ALL:
return !IsNonAdminNetworkClient();
return !_networking || _network_server || _network_settings_access;
case CNM_LOCAL_ONLY:
return !_networking;
case CNM_MONEY:
return !IsNonAdminNetworkClient() || _settings_game.difficulty.money_cheat_in_multiplayer;
return !_networking || _network_server || _network_settings_access || _settings_game.difficulty.money_cheat_in_multiplayer;
}
return false;
}
@ -330,44 +329,45 @@ struct CheatWindow : Window {
}
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
{
if (widget != WID_C_PANEL) return;
uint width = 0;
uint lines = 0;
for (const CheatEntry &ce : _cheats_ui) {
if (!IsCheatAllowed(ce.mode)) continue;
for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i];
if (!IsCheatAllowed(ce->mode)) continue;
lines++;
switch (ce.type) {
switch (ce->type) {
case SLF_ALLOW_CONTROL:
/* Change inflation factors */
break;
case SLE_BOOL:
SetDParam(0, STR_CONFIG_SETTING_ON);
width = std::max(width, GetStringBoundingBox(ce.str).width);
width = std::max(width, GetStringBoundingBox(ce->str).width);
SetDParam(0, STR_CONFIG_SETTING_OFF);
width = std::max(width, GetStringBoundingBox(ce.str).width);
width = std::max(width, GetStringBoundingBox(ce->str).width);
break;
default:
switch (ce.str) {
switch (ce->str) {
/* Display date for change date cheat */
case STR_CHEAT_CHANGE_DATE:
SetDParam(0, CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 11, 31));
width = std::max(width, GetStringBoundingBox(ce.str).width);
width = std::max(width, GetStringBoundingBox(ce->str).width);
break;
/* Draw coloured flag for change company cheat */
case STR_CHEAT_CHANGE_COMPANY:
SetDParamMaxValue(0, MAX_COMPANIES);
width = std::max(width, GetStringBoundingBox(ce.str).width + WidgetDimensions::scaled.hsep_wide * 4);
width = std::max(width, GetStringBoundingBox(ce->str).width + WidgetDimensions::scaled.hsep_wide * 4);
break;
default:
SetDParam(0, INT64_MAX);
width = std::max(width, GetStringBoundingBox(ce.str).width);
width = std::max(width, GetStringBoundingBox(ce->str).width);
break;
}
break;
@ -378,8 +378,8 @@ struct CheatWindow : Window {
this->line_height = std::max<uint>(this->line_height, SETTING_BUTTON_HEIGHT);
this->line_height = std::max<uint>(this->line_height, GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.framerect.Vertical();
size.width = width + WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH /* stuff on the left */ + WidgetDimensions::scaled.hsep_wide * 2 /* extra spacing on right */;
size.height = WidgetDimensions::scaled.framerect.Vertical() + this->line_height * lines;
size->width = width + WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH /* stuff on the left */ + WidgetDimensions::scaled.hsep_wide * 2 /* extra spacing on right */;
size->height = WidgetDimensions::scaled.framerect.Vertical() + this->line_height * lines;
}
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
@ -506,7 +506,7 @@ struct CheatWindow : Window {
}
if (ce->mode == CNM_MONEY) {
if (!_networking) *ce->been_used = true;
DoCommandPEx(0, 0, 0, (std::strtoll(str, nullptr, 10) / GetCurrency().rate), IsNetworkSettingsAdmin() ? CMD_MONEY_CHEAT_ADMIN : CMD_MONEY_CHEAT);
DoCommandPEx(0, 0, 0, (std::strtoll(str, nullptr, 10) / _currency->rate), _network_server || _network_settings_access ? CMD_MONEY_CHEAT_ADMIN : CMD_MONEY_CHEAT);
return;
}
@ -531,7 +531,7 @@ static WindowDesc _cheats_desc(__FILE__, __LINE__,
bool CheatWindowMayBeShown()
{
return _game_mode != GM_EDITOR && (!IsNonAdminNetworkClient() || _settings_game.difficulty.money_cheat_in_multiplayer);
return _game_mode != GM_EDITOR && (!_networking || _network_server || _network_settings_access || _settings_game.difficulty.money_cheat_in_multiplayer);
}
/** Open cheat window. */

@ -46,12 +46,12 @@ static CommandCost ClearTile_Clear(TileIndex tile, DoCommandFlag flags)
return price;
}
SpriteID GetSpriteIDForClearLand(const Slope slope, uint8_t set)
SpriteID GetSpriteIDForClearLand(const Slope slope, byte set)
{
return SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(slope) + set * 19;
}
void DrawClearLandTile(const TileInfo *ti, uint8_t set)
void DrawClearLandTile(const TileInfo *ti, byte set)
{
DrawGroundSprite(GetSpriteIDForClearLand(ti->tileh, set), PAL_NONE);
}
@ -173,7 +173,7 @@ static void DrawTile_Clear(TileInfo *ti, DrawTileProcParams params)
break;
case CLEAR_FIELDS:
if (params.min_visible_height <= (4 * ZOOM_BASE)) {
if (params.min_visible_height <= 4 * ZOOM_LVL_BASE) {
DrawGroundSprite(GetSpriteIDForFields(ti->tileh, GetFieldType(ti->tile)), PAL_NONE);
DrawClearLandFence(ti);
}
@ -199,7 +199,8 @@ static void DrawTile_Clear(TileInfo *ti, DrawTileProcParams params)
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool)
{
auto [tileh, z] = GetTilePixelSlope(tile);
int z;
Slope tileh = GetTilePixelSlope(tile, &z);
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
}
@ -214,25 +215,25 @@ static void UpdateFences(TileIndex tile)
assert_tile(IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS), tile);
bool dirty = false;
bool neighbour = (IsTileType(TileAddXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, 1, 0), CLEAR_FIELDS));
bool neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
if (!neighbour && GetFence(tile, DIAGDIR_SW) == 0) {
SetFence(tile, DIAGDIR_SW, 3);
dirty = true;
}
neighbour = (IsTileType(TileAddXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, 1), CLEAR_FIELDS));
neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
if (!neighbour && GetFence(tile, DIAGDIR_SE) == 0) {
SetFence(tile, DIAGDIR_SE, 3);
dirty = true;
}
neighbour = (IsTileType(TileAddXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, -1, 0), CLEAR_FIELDS));
neighbour = (IsTileType(TILE_ADDXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, -1, 0), CLEAR_FIELDS));
if (!neighbour && GetFence(tile, DIAGDIR_NE) == 0) {
SetFence(tile, DIAGDIR_NE, 3);
dirty = true;
}
neighbour = (IsTileType(TileAddXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, -1), CLEAR_FIELDS));
neighbour = (IsTileType(TILE_ADDXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, -1), CLEAR_FIELDS));
if (!neighbour && GetFence(tile, DIAGDIR_NW) == 0) {
SetFence(tile, DIAGDIR_NW, 3);
dirty = true;

@ -13,9 +13,9 @@
#include "tile_cmd.h"
void DrawHillyLandTile(const TileInfo *ti);
void DrawClearLandTile(const TileInfo *ti, uint8_t set);
void DrawClearLandTile(const TileInfo *ti, byte set);
SpriteID GetSpriteIDForClearLand(const Slope slope, uint8_t set);
SpriteID GetSpriteIDForClearLand(const Slope slope, byte set);
SpriteID GetSpriteIDForHillyLand(const Slope slope, const uint rough_index);
SpriteID GetSpriteIDForRocks(const Slope slope, const uint tile_hash);
SpriteID GetSpriteIDForFields(const Slope slope, const uint field_type);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save