Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -14,3 +14,7 @@ notifications:
|
|||||||
pull-request:
|
pull-request:
|
||||||
issue:
|
issue:
|
||||||
tag-created:
|
tag-created:
|
||||||
|
workflow-run:
|
||||||
|
only:
|
||||||
|
- .github/workflows/release.yml
|
||||||
|
- .github/workflows/ci-nightly.yml
|
||||||
|
|||||||
390
.github/workflows/ci-build.yml
vendored
390
.github/workflows/ci-build.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: CI
|
name: CI - Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -17,79 +17,22 @@ jobs:
|
|||||||
emscripten:
|
emscripten:
|
||||||
name: Emscripten
|
name: Emscripten
|
||||||
|
|
||||||
runs-on: ubuntu-20.04
|
uses: ./.github/workflows/ci-emscripten.yml
|
||||||
container:
|
secrets: inherit
|
||||||
# If you change this version, change the number in the cache step too.
|
|
||||||
image: emscripten/emsdk:3.1.42
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: /emsdk/upstream/emscripten/cache
|
|
||||||
key: 3.1.42-${{ runner.os }}
|
|
||||||
|
|
||||||
- name: Patch Emscripten to support LZMA
|
|
||||||
run: |
|
|
||||||
cd /emsdk/upstream/emscripten
|
|
||||||
patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch
|
|
||||||
|
|
||||||
- name: Build (host tools)
|
|
||||||
run: |
|
|
||||||
mkdir build-host
|
|
||||||
cd build-host
|
|
||||||
|
|
||||||
echo "::group::CMake"
|
|
||||||
cmake .. -DOPTION_TOOLS_ONLY=ON
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Build"
|
|
||||||
echo "Running on $(nproc) cores"
|
|
||||||
cmake --build . -j $(nproc) --target tools
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
|
||||||
uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
|
|
||||||
echo "::group::CMake"
|
|
||||||
emcmake cmake .. -DHOST_BINARY_DIR=../build-host
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Build"
|
|
||||||
echo "Running on $(nproc) cores"
|
|
||||||
cmake --build . -j $(nproc) --target openttd
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: Clang - Debug
|
- name: Clang
|
||||||
compiler: clang-15
|
compiler: clang-15
|
||||||
cxxcompiler: clang++-15
|
cxxcompiler: clang++-15
|
||||||
libraries: libsdl2-dev
|
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
|
- name: GCC - SDL2
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
cxxcompiler: g++
|
cxxcompiler: g++
|
||||||
libraries: libsdl2-dev
|
libraries: libsdl2-dev
|
||||||
- name: GCC - SDL1.2
|
|
||||||
compiler: gcc
|
|
||||||
cxxcompiler: g++
|
|
||||||
libraries: libsdl1.2-dev
|
|
||||||
- name: GCC - Dedicated
|
- name: GCC - Dedicated
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
cxxcompiler: g++
|
cxxcompiler: g++
|
||||||
@@ -99,317 +42,57 @@ jobs:
|
|||||||
|
|
||||||
name: Linux (${{ matrix.name }})
|
name: Linux (${{ matrix.name }})
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
uses: ./.github/workflows/ci-linux.yml
|
||||||
env:
|
secrets: inherit
|
||||||
CC: ${{ matrix.compiler }}
|
|
||||||
CXX: ${{ matrix.cxxcompiler }}
|
|
||||||
|
|
||||||
steps:
|
with:
|
||||||
- name: Checkout
|
compiler: ${{ matrix.compiler }}
|
||||||
uses: actions/checkout@v4
|
cxxcompiler: ${{ matrix.cxxcompiler }}
|
||||||
|
libraries: ${{ matrix.libraries }}
|
||||||
- name: Setup vcpkg caching
|
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
|
||||||
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 \
|
|
||||||
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 .. -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake ${{ matrix.extra-cmake-parameters }}
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Build"
|
|
||||||
echo "Running on $(nproc) cores"
|
|
||||||
cmake --build . -j $(nproc)
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
(
|
|
||||||
cd build
|
|
||||||
ctest -j $(nproc) --timeout 120
|
|
||||||
)
|
|
||||||
|
|
||||||
# Re-enable vcpkg.
|
|
||||||
mv vcpkg-disabled.json vcpkg.json
|
|
||||||
|
|
||||||
# Check no tracked files have been modified.
|
|
||||||
git diff --exit-code
|
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: x64
|
- name: arm64 - Debug
|
||||||
full_arch: x86_64
|
arch: arm64
|
||||||
|
full_arch: arm64
|
||||||
|
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
- name: arm64 - Release
|
||||||
|
arch: arm64
|
||||||
|
full_arch: arm64
|
||||||
|
extra-cmake-parameters: -DCMAKE_BUILD_TYPE=RelWithDebInfo -DOPTION_USE_ASSERTS=OFF
|
||||||
|
|
||||||
name: Mac OS (${{ matrix.arch }})
|
name: Mac OS (${{ matrix.name }})
|
||||||
|
|
||||||
runs-on: macos-latest
|
uses: ./.github/workflows/ci-macos.yml
|
||||||
env:
|
secrets: inherit
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
|
||||||
|
|
||||||
steps:
|
with:
|
||||||
- name: Checkout
|
arch: ${{ matrix.arch }}
|
||||||
uses: actions/checkout@v4
|
full_arch: ${{ matrix.full_arch }}
|
||||||
|
extra-cmake-parameters: ${{ matrix.extra-cmake-parameters }}
|
||||||
- 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::"
|
|
||||||
|
|
||||||
rm -f opengfx-all.zip
|
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
|
||||||
uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
|
|
||||||
echo "::group::CMake"
|
|
||||||
cmake .. \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.full_arch }} \
|
|
||||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-osx \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=/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)
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120
|
|
||||||
|
|
||||||
windows:
|
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
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install OpenGFX
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
|
||||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
|
||||||
|
|
||||||
echo "::group::Download OpenGFX"
|
|
||||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Unpack OpenGFX"
|
|
||||||
unzip opengfx-all.zip
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
rm -f opengfx-all.zip
|
|
||||||
|
|
||||||
- name: Install MSVC problem matcher
|
|
||||||
uses: ammaraskar/msvc-problem-matcher@master
|
|
||||||
|
|
||||||
- name: Configure developer command prompt for ${{ matrix.arch }}
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
with:
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
|
|
||||||
echo "::group::CMake"
|
|
||||||
cmake .. \
|
|
||||||
-GNinja \
|
|
||||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
|
||||||
# EOF
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Build"
|
|
||||||
cmake --build .
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
ctest --timeout 120
|
|
||||||
|
|
||||||
|
|
||||||
msys2:
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- msystem: MINGW64
|
- os: windows-latest
|
||||||
arch: x86_64
|
arch: x86
|
||||||
- msystem: MINGW32
|
- os: windows-latest
|
||||||
arch: i686
|
arch: x64
|
||||||
|
|
||||||
name: MinGW (${{ matrix.arch }})
|
name: Windows (${{ matrix.arch }})
|
||||||
|
|
||||||
runs-on: windows-latest
|
uses: ./.github/workflows/ci-windows.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
steps:
|
with:
|
||||||
- name: Checkout
|
os: ${{ matrix.os }}
|
||||||
uses: actions/checkout@v4
|
arch: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Setup MSYS2
|
|
||||||
uses: msys2/setup-msys2@v2
|
|
||||||
with:
|
|
||||||
msystem: ${{ matrix.msystem }}
|
|
||||||
release: false
|
|
||||||
install: >-
|
|
||||||
git
|
|
||||||
make
|
|
||||||
mingw-w64-${{ matrix.arch }}-cmake
|
|
||||||
mingw-w64-${{ matrix.arch }}-gcc
|
|
||||||
mingw-w64-${{ matrix.arch }}-lzo2
|
|
||||||
mingw-w64-${{ matrix.arch }}-libpng
|
|
||||||
mingw-w64-${{ matrix.arch }}-lld
|
|
||||||
mingw-w64-${{ matrix.arch }}-ninja
|
|
||||||
|
|
||||||
- name: Install OpenGFX
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
|
||||||
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
|
||||||
|
|
||||||
echo "::group::Download OpenGFX"
|
|
||||||
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Unpack OpenGFX"
|
|
||||||
unzip opengfx-all.zip
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
rm -f opengfx-all.zip
|
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
|
||||||
uses: ammaraskar/gcc-problem-matcher@master
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: msys2 {0}
|
|
||||||
env:
|
|
||||||
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
|
||||||
run: |
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
|
|
||||||
echo "::group::CMake"
|
|
||||||
cmake .. \
|
|
||||||
-GNinja \
|
|
||||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
|
||||||
# EOF
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
echo "::group::Build"
|
|
||||||
cmake --build .
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
shell: msys2 {0}
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
ctest --timeout 120
|
|
||||||
|
|
||||||
check_annotations:
|
check_annotations:
|
||||||
name: Check Annotations
|
name: Check Annotations
|
||||||
@@ -418,7 +101,6 @@ jobs:
|
|||||||
- linux
|
- linux
|
||||||
- macos
|
- macos
|
||||||
- windows
|
- windows
|
||||||
- msys2
|
|
||||||
|
|
||||||
if: always() && github.event_name == 'pull_request'
|
if: always() && github.event_name == 'pull_request'
|
||||||
|
|
||||||
|
|||||||
62
.github/workflows/ci-emscripten.yml
vendored
Normal file
62
.github/workflows/ci-emscripten.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
name: CI (Emscripten)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
emscripten:
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
# If you change this version, change the number in the cache step too.
|
||||||
|
image: emscripten/emsdk:3.1.42
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: /emsdk/upstream/emscripten/cache
|
||||||
|
key: 3.1.42-${{ runner.os }}
|
||||||
|
|
||||||
|
- name: Patch Emscripten to support LZMA
|
||||||
|
run: |
|
||||||
|
cd /emsdk/upstream/emscripten
|
||||||
|
patch -p1 < ${GITHUB_WORKSPACE}/os/emscripten/emsdk-liblzma.patch
|
||||||
|
|
||||||
|
- name: Build (host tools)
|
||||||
|
run: |
|
||||||
|
mkdir build-host
|
||||||
|
cd build-host
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. -DOPTION_TOOLS_ONLY=ON
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(nproc) cores"
|
||||||
|
cmake --build . -j $(nproc) --target tools
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Install GCC problem matcher
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
emcmake cmake .. -DHOST_BINARY_DIR=../build-host
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(nproc) cores"
|
||||||
|
cmake --build . -j $(nproc) --target openttd
|
||||||
|
echo "::endgroup::"
|
||||||
123
.github/workflows/ci-linux.yml
vendored
Normal file
123
.github/workflows/ci-linux.yml
vendored
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
name: CI (Linux)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
compiler:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
cxxcompiler:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
libraries:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
extra-cmake-parameters:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CC: ${{ inputs.compiler }}
|
||||||
|
CXX: ${{ inputs.cxxcompiler }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup vcpkg caching
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||||
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
|
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||||
|
|
||||||
|
- name: Install vcpkg
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||||
|
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
echo "::group::Update apt"
|
||||||
|
sudo apt-get update
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Install dependencies"
|
||||||
|
sudo apt-get install -y --no-install-recommends \
|
||||||
|
liballegro4-dev \
|
||||||
|
libcurl4-openssl-dev \
|
||||||
|
libfontconfig-dev \
|
||||||
|
libharfbuzz-dev \
|
||||||
|
libicu-dev \
|
||||||
|
liblzma-dev \
|
||||||
|
liblzo2-dev \
|
||||||
|
${{ inputs.libraries }} \
|
||||||
|
zlib1g-dev \
|
||||||
|
# EOF
|
||||||
|
|
||||||
|
echo "::group::Install vcpkg dependencies"
|
||||||
|
|
||||||
|
# Disable vcpkg integration, as we mostly use system libraries.
|
||||||
|
mv vcpkg.json vcpkg-disabled.json
|
||||||
|
|
||||||
|
# We only use breakpad from vcpkg, as its CMake files
|
||||||
|
# are a bit special. So the Ubuntu's variant doesn't work.
|
||||||
|
${{ runner.temp }}/vcpkg/vcpkg install breakpad
|
||||||
|
|
||||||
|
echo "::endgroup::"
|
||||||
|
env:
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
|
||||||
|
- name: Get OpenGFX
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.local/share/openttd/baseset
|
||||||
|
cd ~/.local/share/openttd/baseset
|
||||||
|
|
||||||
|
echo "::group::Download OpenGFX"
|
||||||
|
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Unpack OpenGFX"
|
||||||
|
unzip opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
rm -f opengfx-all.zip
|
||||||
|
|
||||||
|
- name: Install GCC problem matcher
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake ${{ inputs.extra-cmake-parameters }}
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(nproc) cores"
|
||||||
|
cmake --build . -j $(nproc)
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
(
|
||||||
|
cd build
|
||||||
|
ctest -j $(nproc) --timeout 120
|
||||||
|
)
|
||||||
|
|
||||||
|
# Re-enable vcpkg.
|
||||||
|
mv vcpkg-disabled.json vcpkg.json
|
||||||
|
|
||||||
|
# Check no tracked files have been modified.
|
||||||
|
git diff --exit-code
|
||||||
90
.github/workflows/ci-macos.yml
vendored
Normal file
90
.github/workflows/ci-macos.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
name: CI (MacOS)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
arch:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
full_arch:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
extra-cmake-parameters:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
macos:
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
runs-on: macos-14
|
||||||
|
env:
|
||||||
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Setup Xcode version
|
||||||
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
with:
|
||||||
|
xcode-version: latest-stable
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup vcpkg caching
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||||
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
|
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||||
|
|
||||||
|
- name: Install vcpkg
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||||
|
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||||
|
|
||||||
|
- name: Install OpenGFX
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/Documents/OpenTTD/baseset
|
||||||
|
cd ~/Documents/OpenTTD/baseset
|
||||||
|
|
||||||
|
echo "::group::Download OpenGFX"
|
||||||
|
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Unpack OpenGFX"
|
||||||
|
unzip opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
rm -f opengfx-all.zip
|
||||||
|
|
||||||
|
- name: Install GCC problem matcher
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${{ inputs.full_arch }} \
|
||||||
|
-DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-osx \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||||
|
${{ inputs.extra-cmake-parameters }} \
|
||||||
|
# EOF
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(sysctl -n hw.logicalcpu) cores"
|
||||||
|
cmake --build . -j $(sysctl -n hw.logicalcpu)
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
ctest -j $(sysctl -n hw.logicalcpu) --timeout 120
|
||||||
83
.github/workflows/ci-mingw.yml
vendored
Normal file
83
.github/workflows/ci-mingw.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
name: CI (MinGW)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
arch:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
msystem:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
mingw:
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup MSYS2
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: ${{ inputs.msystem }}
|
||||||
|
release: false
|
||||||
|
install: >-
|
||||||
|
git
|
||||||
|
make
|
||||||
|
mingw-w64-${{ inputs.arch }}-cmake
|
||||||
|
mingw-w64-${{ inputs.arch }}-gcc
|
||||||
|
mingw-w64-${{ inputs.arch }}-lzo2
|
||||||
|
mingw-w64-${{ inputs.arch }}-libpng
|
||||||
|
mingw-w64-${{ inputs.arch }}-lld
|
||||||
|
mingw-w64-${{ inputs.arch }}-ninja
|
||||||
|
|
||||||
|
- name: Install OpenGFX
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
|
||||||
|
echo "::group::Download OpenGFX"
|
||||||
|
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Unpack OpenGFX"
|
||||||
|
unzip opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
rm -f opengfx-all.zip
|
||||||
|
|
||||||
|
- name: Install GCC problem matcher
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: msys2 {0}
|
||||||
|
env:
|
||||||
|
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. \
|
||||||
|
-GNinja \
|
||||||
|
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||||
|
# EOF
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
cmake --build .
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
shell: msys2 {0}
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
ctest --timeout 120
|
||||||
82
.github/workflows/ci-nightly.yml
vendored
Normal file
82
.github/workflows/ci-nightly.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
name: CI - Nightly
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: GCC - SDL1.2
|
||||||
|
compiler: gcc
|
||||||
|
cxxcompiler: g++
|
||||||
|
libraries: libsdl1.2-dev
|
||||||
|
|
||||||
|
name: Linux (${{ matrix.name }})
|
||||||
|
|
||||||
|
uses: ./.github/workflows/ci-linux.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
with:
|
||||||
|
compiler: ${{ matrix.compiler }}
|
||||||
|
cxxcompiler: ${{ matrix.cxxcompiler }}
|
||||||
|
libraries: ${{ matrix.libraries }}
|
||||||
|
extra-cmake-parameters:
|
||||||
|
|
||||||
|
macos:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x64
|
||||||
|
full_arch: x86_64
|
||||||
|
|
||||||
|
name: Mac OS (${{ matrix.arch }})
|
||||||
|
|
||||||
|
uses: ./.github/workflows/ci-macos.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
with:
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
full_arch: ${{ matrix.full_arch }}
|
||||||
|
|
||||||
|
mingw:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- msystem: MINGW64
|
||||||
|
arch: x86_64
|
||||||
|
- msystem: MINGW32
|
||||||
|
arch: i686
|
||||||
|
|
||||||
|
name: MinGW (${{ matrix.arch }})
|
||||||
|
|
||||||
|
uses: ./.github/workflows/ci-mingw.yml
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
with:
|
||||||
|
msystem: ${{ matrix.msystem }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
|
||||||
|
check_annotations:
|
||||||
|
name: Check Annotations
|
||||||
|
needs:
|
||||||
|
- linux
|
||||||
|
- macos
|
||||||
|
- mingw
|
||||||
|
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check annotations
|
||||||
|
uses: OpenTTD/actions/annotation-check@v5
|
||||||
87
.github/workflows/ci-windows.yml
vendored
Normal file
87
.github/workflows/ci-windows.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
name: CI (Windows)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
arch:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
os:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
CTEST_OUTPUT_ON_FAILURE: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
windows:
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
runs-on: ${{ inputs.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup vcpkg caching
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||||
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
|
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||||
|
|
||||||
|
- name: Install vcpkg
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}\vcpkg
|
||||||
|
${{ runner.temp }}\vcpkg\bootstrap-vcpkg.bat -disableMetrics
|
||||||
|
|
||||||
|
- name: Install OpenGFX
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
|
||||||
|
echo "::group::Download OpenGFX"
|
||||||
|
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Unpack OpenGFX"
|
||||||
|
unzip opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
rm -f opengfx-all.zip
|
||||||
|
|
||||||
|
- name: Install MSVC problem matcher
|
||||||
|
uses: ammaraskar/msvc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Configure developer command prompt for ${{ inputs.arch }}
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: ${{ inputs.arch }}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
NINJA_STATUS: "[%f/%t -- %e] " # [finished_edges/total_edges -- elapsed_time], default value is "[%f/%t] "
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. \
|
||||||
|
-GNinja \
|
||||||
|
-DVCPKG_TARGET_TRIPLET=${{ inputs.arch }}-windows-static \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
||||||
|
# EOF
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
cmake --build .
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
ctest --timeout 120
|
||||||
42
.github/workflows/codeql.yml
vendored
42
.github/workflows/codeql.yml
vendored
@@ -26,6 +26,19 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup vcpkg caching
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||||
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
|
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
||||||
|
|
||||||
|
- name: Install vcpkg
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
||||||
|
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
echo "::group::Update apt"
|
echo "::group::Update apt"
|
||||||
@@ -44,13 +57,28 @@ jobs:
|
|||||||
libsdl2-dev \
|
libsdl2-dev \
|
||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
# EOF
|
# 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::"
|
echo "::endgroup::"
|
||||||
env:
|
env:
|
||||||
DEBIAN_FRONTEND: noninteractive
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
|
||||||
- name: Set number of make jobs
|
- name: Prepare build
|
||||||
run: |
|
run: |
|
||||||
echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v3
|
||||||
@@ -58,8 +86,14 @@ jobs:
|
|||||||
languages: cpp
|
languages: cpp
|
||||||
config-file: ./.github/codeql/codeql-config.yml
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
|
|
||||||
- name: Autobuild
|
- name: Build
|
||||||
uses: github/codeql-action/autobuild@v3
|
run: |
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(nproc) cores"
|
||||||
|
cmake --build . -j $(nproc)
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v3
|
||||||
|
|||||||
1
.github/workflows/preview.yml
vendored
1
.github/workflows/preview.yml
vendored
@@ -7,6 +7,7 @@ on:
|
|||||||
- synchronize
|
- synchronize
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- release/**
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||||
|
|||||||
2
.github/workflows/release-linux.yml
vendored
2
.github/workflows/release-linux.yml
vendored
@@ -124,7 +124,7 @@ jobs:
|
|||||||
)
|
)
|
||||||
|
|
||||||
echo "::group::Install breakpad dependencies"
|
echo "::group::Install breakpad dependencies"
|
||||||
cargo install dump_syms
|
cargo install --locked dump_syms
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
- name: Install GCC problem matcher
|
||||||
|
|||||||
18
.github/workflows/release-macos.yml
vendored
18
.github/workflows/release-macos.yml
vendored
@@ -12,11 +12,16 @@ jobs:
|
|||||||
macos:
|
macos:
|
||||||
name: MacOS
|
name: MacOS
|
||||||
|
|
||||||
runs-on: macos-latest
|
runs-on: macos-14
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Setup Xcode version
|
||||||
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
with:
|
||||||
|
xcode-version: latest-stable
|
||||||
|
|
||||||
- name: Download source
|
- name: Download source
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -40,6 +45,11 @@ jobs:
|
|||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
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
|
- name: Install dependencies
|
||||||
env:
|
env:
|
||||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
@@ -52,7 +62,7 @@ jobs:
|
|||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Install breakpad dependencies"
|
echo "::group::Install breakpad dependencies"
|
||||||
cargo install dump_syms
|
cargo install --locked dump_syms
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
- name: Install GCC problem matcher
|
||||||
@@ -94,7 +104,7 @@ jobs:
|
|||||||
cmake ${GITHUB_WORKSPACE} \
|
cmake ${GITHUB_WORKSPACE} \
|
||||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||||
-DVCPKG_TARGET_TRIPLET=arm64-osx \
|
-DVCPKG_TARGET_TRIPLET=arm64-osx \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||||
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
||||||
@@ -115,7 +125,7 @@ jobs:
|
|||||||
cmake ${GITHUB_WORKSPACE} \
|
cmake ${GITHUB_WORKSPACE} \
|
||||||
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||||
-DVCPKG_TARGET_TRIPLET=x64-osx \
|
-DVCPKG_TARGET_TRIPLET=x64-osx \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
-DCMAKE_TOOLCHAIN_FILE=${{ runner.temp }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||||
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
||||||
|
|||||||
54
.github/workflows/release-windows.yml
vendored
54
.github/workflows/release-windows.yml
vendored
@@ -53,6 +53,11 @@ jobs:
|
|||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
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
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -61,7 +66,7 @@ jobs:
|
|||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Install breakpad dependencies"
|
echo "::group::Install breakpad dependencies"
|
||||||
cargo install dump_syms
|
cargo install --locked dump_syms
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
- name: Install MSVC problem matcher
|
- name: Install MSVC problem matcher
|
||||||
@@ -95,21 +100,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
arch: ${{ matrix.host }}
|
arch: ${{ matrix.host }}
|
||||||
|
|
||||||
- name: Import code signing certificate
|
|
||||||
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)
|
- name: Build (with installer)
|
||||||
if: inputs.is_tag == 'true'
|
if: inputs.is_tag == 'true'
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -121,12 +111,11 @@ jobs:
|
|||||||
cmake ${GITHUB_WORKSPACE} \
|
cmake ${GITHUB_WORKSPACE} \
|
||||||
-GNinja \
|
-GNinja \
|
||||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
||||||
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
||||||
-DOPTION_USE_NSIS=ON \
|
-DOPTION_USE_NSIS=ON \
|
||||||
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
||||||
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
|
|
||||||
# EOF
|
# EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
@@ -134,7 +123,12 @@ jobs:
|
|||||||
cmake --build . --target openttd
|
cmake --build . --target openttd
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
env:
|
env:
|
||||||
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
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 }}
|
||||||
|
|
||||||
- name: Build (without installer)
|
- name: Build (without installer)
|
||||||
if: inputs.is_tag != 'true'
|
if: inputs.is_tag != 'true'
|
||||||
@@ -147,11 +141,10 @@ jobs:
|
|||||||
cmake ${GITHUB_WORKSPACE} \
|
cmake ${GITHUB_WORKSPACE} \
|
||||||
-GNinja \
|
-GNinja \
|
||||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \
|
||||||
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
-DCMAKE_TOOLCHAIN_FILE="${{ runner.temp }}\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
||||||
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
-DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
-DOPTION_SURVEY_KEY=${{ inputs.survey_key }} \
|
||||||
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
|
|
||||||
# EOF
|
# EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
@@ -159,7 +152,12 @@ jobs:
|
|||||||
cmake --build . --target openttd
|
cmake --build . --target openttd
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
env:
|
env:
|
||||||
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
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 }}
|
||||||
|
|
||||||
- name: Create breakpad symbols
|
- name: Create breakpad symbols
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -193,13 +191,15 @@ jobs:
|
|||||||
- name: Sign installer
|
- name: Sign installer
|
||||||
if: inputs.is_tag == 'true'
|
if: inputs.is_tag == 'true'
|
||||||
shell: bash
|
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: |
|
run: |
|
||||||
cd ${GITHUB_WORKSPACE}/build/bundles
|
${GITHUB_WORKSPACE}/os/windows/sign.bat "${GITHUB_WORKSPACE}/build/bundles"
|
||||||
../../os/windows/sign.bat *.exe "${WINDOWS_CERTIFICATE_COMMON_NAME}"
|
|
||||||
env:
|
env:
|
||||||
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
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 }}
|
||||||
|
|
||||||
- name: Store bundles
|
- name: Store bundles
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ if(NOT BINARY_NAME)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(${BINARY_NAME}
|
project(${BINARY_NAME}
|
||||||
VERSION 14.0
|
VERSION 15.0
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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**).
|
* 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**).
|
* 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.
|
* When only a single statement is contained, the brackets can be omitted. In this case, put the single statement on the same line as the preceding keyword (**if**, **while**, etc.). Note that this is only allowed for if statements without an **else** clause.
|
||||||
* All fall throughs must be documented, using a **FALLTHROUGH** define/macro.
|
* Non-trivial fall throughs must be documented, using a `[[fallthrough]]` attribute.
|
||||||
* The NOT_REACHED() macro can be used in default constructs that should never be reached.
|
* The NOT_REACHED() macro can be used in default constructs that should never be reached.
|
||||||
* Unconditional loops are written with **`for (;;) {`**
|
* Unconditional loops are written with **`for (;;) {`**
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ switch (a) {
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
DoSomething();
|
DoSomething();
|
||||||
FALLTHROUGH;
|
[[fallthrough]];
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
DoMore();
|
DoMore();
|
||||||
@@ -191,7 +191,7 @@ switch (a) {
|
|||||||
int r = 2;
|
int r = 2;
|
||||||
|
|
||||||
DoEvenMore(a);
|
DoEvenMore(a);
|
||||||
FALLTHROUGH;
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4: {
|
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.
|
* 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".
|
* 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++
|
```c++
|
||||||
template <typename T, typename Tsomething, int N, byte Tnumber_of_something>
|
template <typename T, typename Tsomething, int N, uint8_t Tnumber_of_something>
|
||||||
int Func();
|
int Func();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -110,9 +110,6 @@ builds.
|
|||||||
- `-DOPTION_USE_ASSERTS=OFF`: disable asserts. Use with care, as assert
|
- `-DOPTION_USE_ASSERTS=OFF`: disable asserts. Use with care, as assert
|
||||||
statements capture early signs of trouble. Release builds have them
|
statements capture early signs of trouble. Release builds have them
|
||||||
disabled by default.
|
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
|
- `-DOPTION_TOOLS_ONLY=ON`: only build tools like `strgen`. Does not build
|
||||||
the game itself. Useful for cross-compiling.
|
the game itself. Useful for cross-compiling.
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,15 @@
|
|||||||
- Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3)
|
- Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3)
|
||||||
- Christoph Elsenhans (frosch) - General coding (since 0.6)
|
- Christoph Elsenhans (frosch) - General coding (since 0.6)
|
||||||
- Loïc Guilloux (glx) - General / Windows Expert (since 0.4.5)
|
- 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)
|
- Charles Pigott (LordAro) - General / Correctness police (since 1.9)
|
||||||
- Michael Lutz (michi_cc) - General / Path based signals (since 0.7)
|
- Michael Lutz (michi_cc) - General / Path based signals (since 0.7)
|
||||||
- Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)
|
- Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)
|
||||||
- Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)
|
- 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)
|
- Remko Bijker (Rubidium) - Coder and way more (since 0.4.5)
|
||||||
- Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op
|
- Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op
|
||||||
- Tyler Trahan (2TallTyler) - General coding (since 13)
|
- Tyler Trahan (2TallTyler) - General / Time Lord (since 13)
|
||||||
|
|
||||||
### Inactive Developers:
|
### Inactive Developers:
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ set(AI_COMPAT_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_15.nut
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(AI_COMPAT_SOURCE_FILE IN LISTS AI_COMPAT_SOURCE_FILES)
|
foreach(AI_COMPAT_SOURCE_FILE IN LISTS AI_COMPAT_SOURCE_FILES)
|
||||||
|
|||||||
@@ -4,3 +4,5 @@
|
|||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
* 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/>.
|
* 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.");
|
||||||
|
|||||||
@@ -4,15 +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.
|
* 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/>.
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file dropdown_func.h Functions related to the drop down widget. */
|
|
||||||
|
|
||||||
#ifndef WIDGETS_DROPDOWN_FUNC_H
|
|
||||||
#define WIDGETS_DROPDOWN_FUNC_H
|
|
||||||
|
|
||||||
#include "../window_gui.h"
|
|
||||||
|
|
||||||
/* Show drop down menu containing a fixed list of strings */
|
|
||||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width = 0);
|
|
||||||
|
|
||||||
#endif /* WIDGETS_DROPDOWN_FUNC_H */
|
|
||||||
@@ -12,6 +12,7 @@ set(GS_COMPAT_SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/compat_15.nut
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(GS_COMPAT_SOURCE_FILE IN LISTS GS_COMPAT_SOURCE_FILES)
|
foreach(GS_COMPAT_SOURCE_FILE IN LISTS GS_COMPAT_SOURCE_FILES)
|
||||||
|
|||||||
@@ -4,3 +4,5 @@
|
|||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
* 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/>.
|
* 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.");
|
||||||
|
|||||||
@@ -4,26 +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.
|
* 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/>.
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file script_timemode.cpp Implementation of ScriptTimeMode. */
|
|
||||||
|
|
||||||
#include "../../stdafx.h"
|
|
||||||
#include "script_timemode.hpp"
|
|
||||||
|
|
||||||
#include "../../safeguards.h"
|
|
||||||
|
|
||||||
ScriptTimeMode::ScriptTimeMode(bool calendar)
|
|
||||||
{
|
|
||||||
this->last_time_mode = ScriptObject::IsCalendarTimeMode();
|
|
||||||
ScriptObject::SetTimeMode(calendar);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptTimeMode::~ScriptTimeMode()
|
|
||||||
{
|
|
||||||
ScriptObject::SetTimeMode(this->last_time_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ bool ScriptTimeMode::IsCalendarMode()
|
|
||||||
{
|
|
||||||
return ScriptObject::IsCalendarTimeMode();
|
|
||||||
}
|
|
||||||
@@ -74,12 +74,6 @@ macro(compile_flags)
|
|||||||
|
|
||||||
# We use 'ABCD' multichar for SaveLoad chunks identifiers
|
# We use 'ABCD' multichar for SaveLoad chunks identifiers
|
||||||
-Wno-multichar
|
-Wno-multichar
|
||||||
|
|
||||||
# Compilers complains about that we break strict-aliasing.
|
|
||||||
# On most places we don't see how to fix it, and it doesn't
|
|
||||||
# break anything. So disable strict-aliasing to make the
|
|
||||||
# compiler all happy.
|
|
||||||
-fno-strict-aliasing
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ninja processes the output so the output from the compiler
|
# Ninja processes the output so the output from the compiler
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ function(set_options)
|
|||||||
|
|
||||||
option(OPTION_DEDICATED "Build dedicated server only (no GUI)" OFF)
|
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_INSTALL_FHS "Install with Filesystem Hierarchy Standard folders" ${DEFAULT_OPTION_INSTALL_FHS})
|
||||||
option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" OFF)
|
option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" ON)
|
||||||
option(OPTION_USE_NSIS "Use NSIS to create windows installer; enable only for stable releases" OFF)
|
option(OPTION_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_TOOLS_ONLY "Build only tools target" OFF)
|
||||||
option(OPTION_DOCS_ONLY "Build only docs target" OFF)
|
option(OPTION_DOCS_ONLY "Build only docs target" OFF)
|
||||||
|
|||||||
@@ -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:
|
The best tool to use is `minidump-stackwalk` as published in the Rust's cargo index:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo install minidump-stackwalk
|
cargo install --locked minidump-stackwalk
|
||||||
```
|
```
|
||||||
|
|
||||||
For how to install Rust, please see [here](https://doc.rust-lang.org/cargo/getting-started/installation.html).
|
For how to install Rust, please see [here](https://doc.rust-lang.org/cargo/getting-started/installation.html).
|
||||||
|
|||||||
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).
|
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.
|
It is licensed under GPL-2.0.
|
||||||
|
|
||||||
The currently included files correspond to release v0.5.
|
The currently included files correspond to release v0.6.
|
||||||
|
|||||||
@@ -1,18 +1,2 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM Signing script
|
pwsh -File "%~dp0sign_azure.ps1" %1
|
||||||
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
|
|
||||||
|
|||||||
40
os/windows/sign_azure.ps1
Normal file
40
os/windows/sign_azure.ps1
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# 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 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 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 GetVersion() { return 1; }
|
||||||
function GetAPIVersion() { return "14"; }
|
function GetAPIVersion() { return "15"; }
|
||||||
function GetDate() { return "2007-03-18"; }
|
function GetDate() { return "2007-03-18"; }
|
||||||
function CreateInstance() { return "Regression"; }
|
function CreateInstance() { return "Regression"; }
|
||||||
function UseAsRandomAI() { return false; }
|
function UseAsRandomAI() { return false; }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class StationList extends AIInfo {
|
|||||||
function GetShortName() { return "REGS"; }
|
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 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 GetVersion() { return 1; }
|
||||||
function GetAPIVersion() { return "14"; }
|
function GetAPIVersion() { return "15"; }
|
||||||
function GetDate() { return "2007-03-18"; }
|
function GetDate() { return "2007-03-18"; }
|
||||||
function CreateInstance() { return "StationList"; }
|
function CreateInstance() { return "StationList"; }
|
||||||
function UseAsRandomAI() { return false; }
|
function UseAsRandomAI() { return false; }
|
||||||
|
|||||||
4
src/3rdparty/md5/md5.h
vendored
4
src/3rdparty/md5/md5.h
vendored
@@ -57,8 +57,8 @@
|
|||||||
static const size_t MD5_HASH_BYTES = 16;
|
static const size_t MD5_HASH_BYTES = 16;
|
||||||
|
|
||||||
/** Container for storing a MD5 hash/checksum/digest. */
|
/** Container for storing a MD5 hash/checksum/digest. */
|
||||||
struct MD5Hash : std::array<byte, MD5_HASH_BYTES> {
|
struct MD5Hash : std::array<uint8_t, MD5_HASH_BYTES> {
|
||||||
MD5Hash() : std::array<byte, MD5_HASH_BYTES>{} {}
|
MD5Hash() : std::array<uint8_t, MD5_HASH_BYTES>{} {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exclusively-or the given hash into this hash.
|
* Exclusively-or the given hash into this hash.
|
||||||
|
|||||||
@@ -650,8 +650,7 @@ public:
|
|||||||
_fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
|
_fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
|
||||||
}
|
}
|
||||||
else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
|
else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
|
||||||
SQFloat f = _float(constval);
|
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref, std::bit_cast<SQInt32>(_float(constval)));
|
||||||
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
|
_fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
|
||||||
@@ -697,7 +696,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
case TK_FLOAT:
|
case TK_FLOAT:
|
||||||
if(sizeof(SQFloat) == sizeof(SQInt32)) {
|
if(sizeof(SQFloat) == sizeof(SQInt32)) {
|
||||||
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
|
_fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(), std::bit_cast<SQInt32>(_lex._fvalue));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
|
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
|
||||||
|
|||||||
19
src/3rdparty/squirrel/squirrel/sqfuncstate.cpp
vendored
19
src/3rdparty/squirrel/squirrel/sqfuncstate.cpp
vendored
@@ -199,7 +199,7 @@ void SQFuncState::Dump(SQFunctionProto *func)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(inst.op==_OP_LOADFLOAT) {
|
else if(inst.op==_OP_LOADFLOAT) {
|
||||||
printf("[%03d] %15s %d %f %d %d\n",n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
|
printf("[%03d] %15s %d %f %d %d\n",n,g_InstrDesc[inst.op].name,inst._arg0,std::bit_cast<SQFloat>(inst._arg1),inst._arg2,inst._arg3);
|
||||||
}
|
}
|
||||||
else if(inst.op==_OP_ARITH){
|
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);
|
printf("[%03d] %15s %d %d %d %c\n",n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
|
||||||
@@ -242,19 +242,20 @@ SQInteger SQFuncState::GetConstant(const SQObject &cons)
|
|||||||
|
|
||||||
void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
|
void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
|
||||||
{
|
{
|
||||||
_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
|
_instructions[pos]._arg0 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg0);
|
||||||
_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
|
_instructions[pos]._arg1 = (SQInt32)std::bit_cast<SQUnsignedInteger>(arg1);
|
||||||
_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
|
_instructions[pos]._arg2 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg2);
|
||||||
_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
|
_instructions[pos]._arg3 = (unsigned char)std::bit_cast<SQUnsignedInteger>(arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
|
void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
|
||||||
{
|
{
|
||||||
switch(arg){
|
switch(arg){
|
||||||
case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
case 0: _instructions[pos]._arg0 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||||
case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
|
case 1:
|
||||||
case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
case 4: _instructions[pos]._arg1 = (SQInt32)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||||
case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
|
case 2: _instructions[pos]._arg2 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||||
|
case 3: _instructions[pos]._arg3 = (unsigned char)std::bit_cast<SQUnsignedInteger>(val); break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
8
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -51,7 +51,7 @@ bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,con
|
|||||||
case BW_XOR: res = i1 ^ i2; break;
|
case BW_XOR: res = i1 ^ i2; break;
|
||||||
case BW_SHIFTL: res = i1 << i2; break;
|
case BW_SHIFTL: res = i1 << i2; break;
|
||||||
case BW_SHIFTR: res = i1 >> i2; break;
|
case BW_SHIFTR: res = i1 >> i2; break;
|
||||||
case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
|
case BW_USHIFTR:res = (SQInteger)(std::bit_cast<SQUnsignedInteger>(i1) >> i2); break;
|
||||||
default: { Raise_Error("internal vm error bitwise op failed"); return false; }
|
default: { Raise_Error("internal vm error bitwise op failed"); return false; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -472,10 +472,10 @@ bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjec
|
|||||||
|
|
||||||
#define arg0 (_i_._arg0)
|
#define arg0 (_i_._arg0)
|
||||||
#define arg1 (_i_._arg1)
|
#define arg1 (_i_._arg1)
|
||||||
#define sarg1 (*(const_cast<SQInt32 *>(&_i_._arg1)))
|
#define sarg1 (std::bit_cast<SQInt32>(_i_._arg1))
|
||||||
#define arg2 (_i_._arg2)
|
#define arg2 (_i_._arg2)
|
||||||
#define arg3 (_i_._arg3)
|
#define arg3 (_i_._arg3)
|
||||||
#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3))
|
#define sarg3 ((SQInteger)std::bit_cast<char>(_i_._arg3))
|
||||||
|
|
||||||
SQRESULT SQVM::Suspend()
|
SQRESULT SQVM::Suspend()
|
||||||
{
|
{
|
||||||
@@ -764,7 +764,7 @@ exception_restore:
|
|||||||
continue;
|
continue;
|
||||||
case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
|
case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
|
||||||
case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
|
case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
|
||||||
case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue;
|
case _OP_LOADFLOAT: TARGET = std::bit_cast<SQFloat>(arg1); continue;
|
||||||
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
|
case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
|
||||||
case _OP_TAILCALL:
|
case _OP_TAILCALL:
|
||||||
temp_reg = STK(arg1);
|
temp_reg = STK(arg1);
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ add_files(
|
|||||||
animated_tile_func.h
|
animated_tile_func.h
|
||||||
articulated_vehicles.cpp
|
articulated_vehicles.cpp
|
||||||
articulated_vehicles.h
|
articulated_vehicles.h
|
||||||
|
autocompletion.cpp
|
||||||
|
autocompletion.h
|
||||||
autoreplace.cpp
|
autoreplace.cpp
|
||||||
autoreplace_base.h
|
autoreplace_base.h
|
||||||
autoreplace_cmd.cpp
|
autoreplace_cmd.cpp
|
||||||
@@ -138,6 +140,10 @@ add_files(
|
|||||||
dock_gui.cpp
|
dock_gui.cpp
|
||||||
driver.cpp
|
driver.cpp
|
||||||
driver.h
|
driver.h
|
||||||
|
dropdown.cpp
|
||||||
|
dropdown_common_type.h
|
||||||
|
dropdown_func.h
|
||||||
|
dropdown_type.h
|
||||||
economy.cpp
|
economy.cpp
|
||||||
economy_base.h
|
economy_base.h
|
||||||
economy_cmd.h
|
economy_cmd.h
|
||||||
@@ -393,6 +399,8 @@ add_files(
|
|||||||
signs_func.h
|
signs_func.h
|
||||||
signs_gui.cpp
|
signs_gui.cpp
|
||||||
signs_type.h
|
signs_type.h
|
||||||
|
slider.cpp
|
||||||
|
slider_func.h
|
||||||
slope_func.h
|
slope_func.h
|
||||||
slope_type.h
|
slope_type.h
|
||||||
smallmap_gui.cpp
|
smallmap_gui.cpp
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Start a new AI company.
|
* Start a new AI company.
|
||||||
* @param company At which slot the AI company should start.
|
* @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, bool deviate = true);
|
static void StartNew(CompanyID company);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called every game-tick to let AIs do something.
|
* Called every game-tick to let AIs do something.
|
||||||
|
|||||||
@@ -33,14 +33,14 @@
|
|||||||
return !_networking || (_network_server && _settings_game.ai.ai_in_multiplayer);
|
return !_networking || (_network_server && _settings_game.ai.ai_in_multiplayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void AI::StartNew(CompanyID company, bool deviate)
|
/* static */ void AI::StartNew(CompanyID company)
|
||||||
{
|
{
|
||||||
assert(Company::IsValidID(company));
|
assert(Company::IsValidID(company));
|
||||||
|
|
||||||
/* Clients shouldn't start AIs */
|
/* Clients shouldn't start AIs */
|
||||||
if (_networking && !_network_server) return;
|
if (_networking && !_network_server) return;
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
Company *c = Company::Get(company);
|
Company *c = Company::Get(company);
|
||||||
|
|
||||||
AIConfig *config = c->ai_config.get();
|
AIConfig *config = c->ai_config.get();
|
||||||
@@ -56,7 +56,6 @@
|
|||||||
/* Load default data and store the name in the settings */
|
/* Load default data and store the name in the settings */
|
||||||
config->Change(info->GetName(), -1, false);
|
config->Change(info->GetName(), -1, false);
|
||||||
}
|
}
|
||||||
if (deviate) config->AddRandomDeviation(company);
|
|
||||||
config->AnchorUnchangeableSettings();
|
config->AnchorUnchangeableSettings();
|
||||||
|
|
||||||
c->ai_info = info;
|
c->ai_info = info;
|
||||||
@@ -82,7 +81,7 @@
|
|||||||
assert(_settings_game.difficulty.competitor_speed <= 4);
|
assert(_settings_game.difficulty.competitor_speed <= 4);
|
||||||
if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
|
if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company);
|
||||||
for (const Company *c : Company::Iterate()) {
|
for (const Company *c : Company::Iterate()) {
|
||||||
if (c->is_ai) {
|
if (c->is_ai) {
|
||||||
PerformanceMeasurer framerate((PerformanceElement)(PFE_AI0 + c->index));
|
PerformanceMeasurer framerate((PerformanceElement)(PFE_AI0 + c->index));
|
||||||
@@ -110,7 +109,7 @@
|
|||||||
if (_networking && !_network_server) return;
|
if (_networking && !_network_server) return;
|
||||||
PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + company));
|
PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + company));
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
Company *c = Company::Get(company);
|
Company *c = Company::Get(company);
|
||||||
|
|
||||||
delete c->ai_instance;
|
delete c->ai_instance;
|
||||||
@@ -130,7 +129,7 @@
|
|||||||
* for the server owner to unpause the script again. */
|
* for the server owner to unpause the script again. */
|
||||||
if (_network_dedicated) return;
|
if (_network_dedicated) return;
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
Company::Get(company)->ai_instance->Pause();
|
Company::Get(company)->ai_instance->Pause();
|
||||||
|
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
@@ -138,7 +137,7 @@
|
|||||||
|
|
||||||
/* static */ void AI::Unpause(CompanyID company)
|
/* static */ void AI::Unpause(CompanyID company)
|
||||||
{
|
{
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
Company::Get(company)->ai_instance->Unpause();
|
Company::Get(company)->ai_instance->Unpause();
|
||||||
|
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
@@ -146,7 +145,7 @@
|
|||||||
|
|
||||||
/* static */ bool AI::IsPaused(CompanyID company)
|
/* static */ bool AI::IsPaused(CompanyID company)
|
||||||
{
|
{
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
bool paused = Company::Get(company)->ai_instance->IsPaused();
|
bool paused = Company::Get(company)->ai_instance->IsPaused();
|
||||||
|
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
@@ -215,25 +214,30 @@
|
|||||||
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
|
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
|
||||||
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
|
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
|
||||||
_settings_game.ai_config[c]->Change(std::nullopt);
|
_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] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
|
||||||
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
|
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
|
||||||
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
|
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
|
||||||
_settings_newgame.ai_config[c]->Change(std::nullopt);
|
_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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +259,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Queue the event */
|
/* Queue the event */
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
Company::Get(_current_company)->ai_instance->InsertEvent(event);
|
Company::Get(_current_company)->ai_instance->InsertEvent(event);
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
|
|
||||||
@@ -285,14 +289,18 @@
|
|||||||
{
|
{
|
||||||
if (!_networking || _network_server) {
|
if (!_networking || _network_server) {
|
||||||
Company *c = Company::GetIfValid(company);
|
Company *c = Company::GetIfValid(company);
|
||||||
assert(c != nullptr && c->ai_instance != nullptr);
|
assert(c != nullptr);
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
/* When doing emergency saving, an AI can be not fully initialised. */
|
||||||
c->ai_instance->Save();
|
if (c->ai_instance != nullptr) {
|
||||||
cur_company.Restore();
|
Backup<CompanyID> cur_company(_current_company, company);
|
||||||
} else {
|
c->ai_instance->Save();
|
||||||
AIInstance::SaveEmpty();
|
cur_company.Restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AIInstance::SaveEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void AI::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
|
/* static */ void AI::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ static constexpr NWidgetPart _nested_ai_config_widgets[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Window definition for the configure AI window. */
|
/** Window definition for the configure AI window. */
|
||||||
static WindowDesc _ai_config_desc(__FILE__, __LINE__,
|
static WindowDesc _ai_config_desc(
|
||||||
WDP_CENTER, nullptr, 0, 0,
|
WDP_CENTER, nullptr, 0, 0,
|
||||||
WC_GAME_OPTIONS, WC_NONE,
|
WC_GAME_OPTIONS, WC_NONE,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
static bool CheckAPIVersion(const std::string &api_version)
|
static bool CheckAPIVersion(const std::string &api_version)
|
||||||
{
|
{
|
||||||
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14" };
|
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14", "15" };
|
||||||
return versions.find(api_version) != versions.end();
|
return versions.find(api_version) != versions.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ void AIInstance::Died()
|
|||||||
/* Intro is not supposed to use AI, but it may have 'dummy' AI which instant dies. */
|
/* Intro is not supposed to use AI, but it may have 'dummy' AI which instant dies. */
|
||||||
if (_game_mode == GM_MENU) return;
|
if (_game_mode == GM_MENU) return;
|
||||||
|
|
||||||
|
/* Don't show errors while loading savegame. They will be shown at end of loading anyway. */
|
||||||
|
if (_switch_mode != SM_NONE) return;
|
||||||
|
|
||||||
ShowScriptDebugWindow(_current_company);
|
ShowScriptDebugWindow(_current_company);
|
||||||
|
|
||||||
const AIInfo *info = AIConfig::GetConfig(_current_company)->GetInfo();
|
const AIInfo *info = AIConfig::GetConfig(_current_company)->GetInfo();
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ struct AircraftCache {
|
|||||||
*/
|
*/
|
||||||
struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
|
struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
|
||||||
uint16_t crashed_counter; ///< Timer for handling crash animations.
|
uint16_t crashed_counter; ///< Timer for handling crash animations.
|
||||||
byte pos; ///< Next desired position of the aircraft.
|
uint8_t pos; ///< Next desired position of the aircraft.
|
||||||
byte previous_pos; ///< Previous desired position of the aircraft.
|
uint8_t previous_pos; ///< Previous desired position of the aircraft.
|
||||||
StationID targetairport; ///< Airport to go to next.
|
StationID targetairport; ///< Airport to go to next.
|
||||||
byte state; ///< State of the airport. @see AirportMovementStates
|
uint8_t state; ///< State of the airport. @see AirportMovementStates
|
||||||
Direction last_direction;
|
Direction last_direction;
|
||||||
byte number_consecutive_turns; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point.
|
uint8_t 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.
|
uint8_t turn_counter; ///< Ticks between each turn to prevent > 45 degree turns.
|
||||||
byte flags; ///< Aircraft flags. @see AirVehicleFlags
|
uint8_t flags; ///< Aircraft flags. @see AirVehicleFlags
|
||||||
|
|
||||||
AircraftCache acache;
|
AircraftCache acache;
|
||||||
|
|
||||||
@@ -111,6 +111,7 @@ struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
|
|||||||
void OnNewEconomyDay() override;
|
void OnNewEconomyDay() override;
|
||||||
uint Crash(bool flooded = false) override;
|
uint Crash(bool flooded = false) override;
|
||||||
TileIndex GetOrderStationLocation(StationID station) override;
|
TileIndex GetOrderStationLocation(StationID station) override;
|
||||||
|
TileIndex GetCargoTile() const override { return this->First()->tile; }
|
||||||
ClosestDepot FindClosestDepot() override;
|
ClosestDepot FindClosestDepot() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ static StationID FindNearestHangar(const Aircraft *v)
|
|||||||
const Station *next_dest = nullptr;
|
const Station *next_dest = nullptr;
|
||||||
if (max_range != 0) {
|
if (max_range != 0) {
|
||||||
if (v->current_order.IsType(OT_GOTO_STATION) ||
|
if (v->current_order.IsType(OT_GOTO_STATION) ||
|
||||||
(v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT)) {
|
(v->current_order.IsType(OT_GOTO_DEPOT) && (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) == 0)) {
|
||||||
last_dest = Station::GetIfValid(v->last_station_visited);
|
last_dest = Station::GetIfValid(v->last_station_visited);
|
||||||
next_dest = Station::GetIfValid(v->current_order.GetDestination());
|
next_dest = Station::GetIfValid(v->current_order.GetDestination());
|
||||||
} else {
|
} else {
|
||||||
@@ -456,6 +456,7 @@ void Aircraft::OnNewCalendarDay()
|
|||||||
void Aircraft::OnNewEconomyDay()
|
void Aircraft::OnNewEconomyDay()
|
||||||
{
|
{
|
||||||
if (!this->IsNormalAircraft()) return;
|
if (!this->IsNormalAircraft()) return;
|
||||||
|
EconomyAgeVehicle(this);
|
||||||
|
|
||||||
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
|
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
|
||||||
|
|
||||||
@@ -654,7 +655,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
|||||||
* ~ acceleration * 77 (km-ish/h / 256)
|
* ~ acceleration * 77 (km-ish/h / 256)
|
||||||
*/
|
*/
|
||||||
uint spd = v->acceleration * 77;
|
uint spd = v->acceleration * 77;
|
||||||
byte t;
|
uint8_t t;
|
||||||
|
|
||||||
/* Adjust speed limits by plane speed factor to prevent taxiing
|
/* Adjust speed limits by plane speed factor to prevent taxiing
|
||||||
* and take-off speeds being too low. */
|
* and take-off speeds being too low. */
|
||||||
@@ -671,7 +672,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
|||||||
speed_limit = v->vcache.cached_max_speed;
|
speed_limit = v->vcache.cached_max_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->subspeed = (t = v->subspeed) + (byte)spd;
|
v->subspeed = (t = v->subspeed) + (uint8_t)spd;
|
||||||
|
|
||||||
/* Aircraft's current speed is used twice so that very fast planes are
|
/* 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
|
* forced to slow down rapidly in the short distance needed. The magic
|
||||||
@@ -698,7 +699,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE,
|
|||||||
spd = v->GetOldAdvanceSpeed(spd);
|
spd = v->GetOldAdvanceSpeed(spd);
|
||||||
|
|
||||||
spd += v->progress;
|
spd += v->progress;
|
||||||
v->progress = (byte)spd;
|
v->progress = (uint8_t)spd;
|
||||||
return spd >> 8;
|
return spd >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,7 +825,7 @@ template int GetAircraftFlightLevel(Aircraft *v, bool takeoff);
|
|||||||
* @param rotation The rotation of the airport.
|
* @param rotation The rotation of the airport.
|
||||||
* @return The index of the entry point
|
* @return The index of the entry point
|
||||||
*/
|
*/
|
||||||
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
static uint8_t AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
||||||
{
|
{
|
||||||
assert(v != nullptr);
|
assert(v != nullptr);
|
||||||
assert(apc != nullptr);
|
assert(apc != nullptr);
|
||||||
@@ -1284,7 +1285,7 @@ void HandleMissingAircraftOrders(Aircraft *v)
|
|||||||
*/
|
*/
|
||||||
const Station *st = GetTargetAirportIfValid(v);
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
if (st == nullptr) {
|
if (st == nullptr) {
|
||||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||||
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::None, {});
|
CommandCost ret = Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::None, {});
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
|
|
||||||
@@ -1650,7 +1651,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass
|
|||||||
|
|
||||||
/* Send the helicopter to a hangar if needed for replacement */
|
/* Send the helicopter to a hangar if needed for replacement */
|
||||||
if (v->NeedsAutomaticServicing()) {
|
if (v->NeedsAutomaticServicing()) {
|
||||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||||
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service | DepotCommand::LocateHangar, {});
|
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service | DepotCommand::LocateHangar, {});
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
}
|
}
|
||||||
@@ -1665,7 +1666,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc)
|
|||||||
/* {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
|
/* {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
|
||||||
* if it is an airplane, look for LANDING, for helicopter HELILANDING
|
* 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 */
|
* it is possible to choose from multiple landing runways, so loop until a free one is found */
|
||||||
byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
|
uint8_t landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING;
|
||||||
const AirportFTA *current = apc->layout[v->pos].next;
|
const AirportFTA *current = apc->layout[v->pos].next;
|
||||||
while (current != nullptr) {
|
while (current != nullptr) {
|
||||||
if (current->heading == landingtype) {
|
if (current->heading == landingtype) {
|
||||||
@@ -1701,7 +1702,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *)
|
|||||||
|
|
||||||
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
|
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
|
||||||
if (v->NeedsAutomaticServicing()) {
|
if (v->NeedsAutomaticServicing()) {
|
||||||
Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, v->owner);
|
||||||
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service, {});
|
Command<CMD_SEND_VEHICLE_TO_DEPOT>::Do(DC_EXEC, v->index, DepotCommand::Service, {});
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
}
|
}
|
||||||
@@ -1812,8 +1813,8 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
|||||||
const AirportFTA *current = &apc->layout[v->pos];
|
const AirportFTA *current = &apc->layout[v->pos];
|
||||||
/* we have arrived in an important state (eg terminal, hangar, etc.) */
|
/* we have arrived in an important state (eg terminal, hangar, etc.) */
|
||||||
if (current->heading == v->state) {
|
if (current->heading == v->state) {
|
||||||
byte prev_pos = v->pos; // location could be changed in state, so save it before-hand
|
uint8_t prev_pos = v->pos; // location could be changed in state, so save it before-hand
|
||||||
byte prev_state = v->state;
|
uint8_t prev_state = v->state;
|
||||||
_aircraft_state_handlers[v->state](v, apc);
|
_aircraft_state_handlers[v->state](v, apc);
|
||||||
if (v->state != FLYING) v->previous_pos = prev_pos;
|
if (v->state != FLYING) v->previous_pos = prev_pos;
|
||||||
if (v->state != prev_state || v->pos != prev_pos) UpdateAircraftCache(v);
|
if (v->state != prev_state || v->pos != prev_pos) UpdateAircraftCache(v);
|
||||||
@@ -1949,7 +1950,7 @@ static const MovementTerminalMapping _airport_terminal_mapping[] = {
|
|||||||
* @param last_terminal Terminal number to stop examining.
|
* @param last_terminal Terminal number to stop examining.
|
||||||
* @return A terminal or helipad has been found, and has been assigned to the aircraft.
|
* @return A terminal or helipad has been found, and has been assigned to the aircraft.
|
||||||
*/
|
*/
|
||||||
static bool FreeTerminal(Aircraft *v, byte i, byte last_terminal)
|
static bool FreeTerminal(Aircraft *v, uint8_t i, uint8_t last_terminal)
|
||||||
{
|
{
|
||||||
assert(last_terminal <= lengthof(_airport_terminal_mapping));
|
assert(last_terminal <= lengthof(_airport_terminal_mapping));
|
||||||
Station *st = Station::Get(v->targetairport);
|
Station *st = Station::Get(v->targetairport);
|
||||||
|
|||||||
@@ -110,12 +110,12 @@ AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Directi
|
|||||||
|
|
||||||
AirportFTAClass::AirportFTAClass(
|
AirportFTAClass::AirportFTAClass(
|
||||||
const AirportMovingData *moving_data_,
|
const AirportMovingData *moving_data_,
|
||||||
const byte *terminals_,
|
const uint8_t *terminals_,
|
||||||
const byte num_helipads_,
|
const uint8_t num_helipads_,
|
||||||
const byte *entry_points_,
|
const uint8_t *entry_points_,
|
||||||
Flags flags_,
|
Flags flags_,
|
||||||
const AirportFTAbuildup *apFA,
|
const AirportFTAbuildup *apFA,
|
||||||
byte delta_z_
|
uint8_t delta_z_
|
||||||
) :
|
) :
|
||||||
moving_data(moving_data_),
|
moving_data(moving_data_),
|
||||||
terminals(terminals_),
|
terminals(terminals_),
|
||||||
@@ -204,7 +204,7 @@ static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildu
|
|||||||
* @param airport_type %Airport type to query FTA from. @see AirportTypes
|
* @param airport_type %Airport type to query FTA from. @see AirportTypes
|
||||||
* @return Finite state machine of the airport.
|
* @return Finite state machine of the airport.
|
||||||
*/
|
*/
|
||||||
const AirportFTAClass *GetAirport(const byte airport_type)
|
const AirportFTAClass *GetAirport(const uint8_t airport_type)
|
||||||
{
|
{
|
||||||
if (airport_type == AT_DUMMY) return &_airportfta_dummy;
|
if (airport_type == AT_DUMMY) return &_airportfta_dummy;
|
||||||
return AirportSpec::Get(airport_type)->fsm;
|
return AirportSpec::Get(airport_type)->fsm;
|
||||||
@@ -215,7 +215,7 @@ const AirportFTAClass *GetAirport(const byte airport_type)
|
|||||||
* @param hangar_tile The tile on which the vehicle is build
|
* @param hangar_tile The tile on which the vehicle is build
|
||||||
* @return The position (index in airport node array) where the aircraft ends up
|
* @return The position (index in airport node array) where the aircraft ends up
|
||||||
*/
|
*/
|
||||||
byte GetVehiclePosOnBuild(TileIndex hangar_tile)
|
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile)
|
||||||
{
|
{
|
||||||
const Station *st = Station::GetByTile(hangar_tile);
|
const Station *st = Station::GetByTile(hangar_tile);
|
||||||
const AirportFTAClass *apc = st->airport.GetFTA();
|
const AirportFTAClass *apc = st->airport.GetFTA();
|
||||||
|
|||||||
@@ -152,12 +152,12 @@ public:
|
|||||||
|
|
||||||
AirportFTAClass(
|
AirportFTAClass(
|
||||||
const AirportMovingData *moving_data,
|
const AirportMovingData *moving_data,
|
||||||
const byte *terminals,
|
const uint8_t *terminals,
|
||||||
const byte num_helipads,
|
const uint8_t num_helipads,
|
||||||
const byte *entry_points,
|
const uint8_t *entry_points,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
const AirportFTAbuildup *apFA,
|
const AirportFTAbuildup *apFA,
|
||||||
byte delta_z
|
uint8_t delta_z
|
||||||
);
|
);
|
||||||
|
|
||||||
~AirportFTAClass();
|
~AirportFTAClass();
|
||||||
@@ -167,7 +167,7 @@ public:
|
|||||||
* @param position Element number to get movement data about.
|
* @param position Element number to get movement data about.
|
||||||
* @return Pointer to the movement data.
|
* @return Pointer to the movement data.
|
||||||
*/
|
*/
|
||||||
const AirportMovingData *MovingData(byte position) const
|
const AirportMovingData *MovingData(uint8_t position) const
|
||||||
{
|
{
|
||||||
assert(position < nofelements);
|
assert(position < nofelements);
|
||||||
return &moving_data[position];
|
return &moving_data[position];
|
||||||
@@ -175,12 +175,12 @@ public:
|
|||||||
|
|
||||||
const AirportMovingData *moving_data; ///< Movement data.
|
const AirportMovingData *moving_data; ///< Movement data.
|
||||||
struct AirportFTA *layout; ///< state machine for airport
|
struct AirportFTA *layout; ///< state machine for airport
|
||||||
const byte *terminals; ///< %Array with the number of terminal groups, followed by the number of terminals in each group.
|
const uint8_t *terminals; ///< %Array with the number of terminal groups, followed by the number of terminals in each group.
|
||||||
const byte num_helipads; ///< Number of helipads on this airport. When 0 helicopters will go to normal terminals.
|
const uint8_t num_helipads; ///< Number of helipads on this airport. When 0 helicopters will go to normal terminals.
|
||||||
Flags flags; ///< Flags for this airport type.
|
Flags flags; ///< Flags for this airport type.
|
||||||
byte nofelements; ///< number of positions the airport consists of
|
uint8_t 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
|
const uint8_t *entry_points; ///< when an airplane arrives at this airport, enter it at position entry_point, index depends on direction
|
||||||
byte delta_z; ///< Z adjustment for helicopter pads
|
uint8_t delta_z; ///< Z adjustment for helicopter pads
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags)
|
DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags)
|
||||||
@@ -190,12 +190,12 @@ DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags)
|
|||||||
struct AirportFTA {
|
struct AirportFTA {
|
||||||
AirportFTA *next; ///< possible extra movement choices from this position
|
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
|
uint64_t block; ///< 64 bit blocks (st->airport.flags), should be enough for the most complex airports
|
||||||
byte position; ///< the position that an airplane is at
|
uint8_t position; ///< the position that an airplane is at
|
||||||
byte next_position; ///< next position from this position
|
uint8_t next_position; ///< next position from this position
|
||||||
byte heading; ///< heading (current orders), guiding an airplane to its target on an airport
|
uint8_t heading; ///< heading (current orders), guiding an airplane to its target on an airport
|
||||||
};
|
};
|
||||||
|
|
||||||
const AirportFTAClass *GetAirport(const byte airport_type);
|
const AirportFTAClass *GetAirport(const uint8_t airport_type);
|
||||||
byte GetVehiclePosOnBuild(TileIndex hangar_tile);
|
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile);
|
||||||
|
|
||||||
#endif /* AIRPORT_H */
|
#endif /* AIRPORT_H */
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
#include "station_type.h"
|
#include "station_type.h"
|
||||||
#include "newgrf_airport.h"
|
#include "newgrf_airport.h"
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
#include "widgets/dropdown_type.h"
|
#include "dropdown_type.h"
|
||||||
|
#include "dropdown_func.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
#include "hotkeys.h"
|
#include "hotkeys.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
@@ -42,11 +43,11 @@
|
|||||||
|
|
||||||
static AirportClassID _selected_airport_class; ///< the currently visible airport class
|
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 int _selected_airport_index; ///< the index of the selected airport in the current class or -1
|
||||||
static byte _selected_airport_layout; ///< selected airport layout number.
|
static uint8_t _selected_airport_layout; ///< selected airport layout number.
|
||||||
|
|
||||||
static void ShowBuildAirportPicker(Window *parent);
|
static void ShowBuildAirportPicker(Window *parent);
|
||||||
|
|
||||||
SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout);
|
SpriteID GetCustomAirportSprite(const AirportSpec *as, uint8_t layout);
|
||||||
|
|
||||||
void CcBuildAirport(Commands, const CommandCost &result, TileIndex tile)
|
void CcBuildAirport(Commands, const CommandCost &result, TileIndex tile)
|
||||||
{
|
{
|
||||||
@@ -64,8 +65,8 @@ static void PlaceAirport(TileIndex tile)
|
|||||||
{
|
{
|
||||||
if (_selected_airport_index == -1) return;
|
if (_selected_airport_index == -1) return;
|
||||||
|
|
||||||
byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
uint8_t airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||||
byte layout = _selected_airport_layout;
|
uint8_t layout = _selected_airport_layout;
|
||||||
bool adjacent = _ctrl_pressed;
|
bool adjacent = _ctrl_pressed;
|
||||||
|
|
||||||
auto proc = [=](bool test, StationID to_join) -> bool {
|
auto proc = [=](bool test, StationID to_join) -> bool {
|
||||||
@@ -223,7 +224,7 @@ static constexpr NWidgetPart _nested_air_toolbar_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _air_toolbar_desc(__FILE__, __LINE__,
|
static WindowDesc _air_toolbar_desc(
|
||||||
WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0,
|
WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0,
|
||||||
WC_BUILD_TOOLBAR, WC_NONE,
|
WC_BUILD_TOOLBAR, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
@@ -257,7 +258,7 @@ class BuildAirportWindow : public PickerWindowBase {
|
|||||||
DropDownList list;
|
DropDownList list;
|
||||||
|
|
||||||
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
|
for (uint i = 0; i < AirportClass::GetClassCount(); i++) {
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(AirportClass::Get((AirportClassID)i)->name, i, false));
|
list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@@ -364,7 +365,7 @@ public:
|
|||||||
for (int i = 0; i < NUM_AIRPORTS; i++) {
|
for (int i = 0; i < NUM_AIRPORTS; i++) {
|
||||||
const AirportSpec *as = AirportSpec::Get(i);
|
const AirportSpec *as = AirportSpec::Get(i);
|
||||||
if (!as->enabled) continue;
|
if (!as->enabled) continue;
|
||||||
for (byte layout = 0; layout < as->num_table; layout++) {
|
for (uint8_t layout = 0; layout < as->num_table; layout++) {
|
||||||
SpriteID sprite = GetCustomAirportSprite(as, layout);
|
SpriteID sprite = GetCustomAirportSprite(as, layout);
|
||||||
if (sprite != 0) {
|
if (sprite != 0) {
|
||||||
Dimension d = GetSpriteSize(sprite);
|
Dimension d = GetSpriteSize(sprite);
|
||||||
@@ -380,7 +381,7 @@ public:
|
|||||||
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
|
for (int i = NEW_AIRPORT_OFFSET; i < NUM_AIRPORTS; i++) {
|
||||||
const AirportSpec *as = AirportSpec::Get(i);
|
const AirportSpec *as = AirportSpec::Get(i);
|
||||||
if (!as->enabled) continue;
|
if (!as->enabled) continue;
|
||||||
for (byte layout = 0; layout < as->num_table; layout++) {
|
for (uint8_t layout = 0; layout < as->num_table; layout++) {
|
||||||
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
|
StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT);
|
||||||
if (string == STR_UNDEFINED) continue;
|
if (string == STR_UNDEFINED) continue;
|
||||||
|
|
||||||
@@ -512,8 +513,8 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_AP_AIRPORT_LIST: {
|
case WID_AP_AIRPORT_LIST: {
|
||||||
int num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
|
int32_t num_clicked = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
|
||||||
if (num_clicked == INT_MAX) break;
|
if (num_clicked == INT32_MAX) break;
|
||||||
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
|
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
|
||||||
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
|
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
|
||||||
break;
|
break;
|
||||||
@@ -635,7 +636,7 @@ static constexpr NWidgetPart _nested_build_airport_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _build_airport_desc(__FILE__, __LINE__,
|
static WindowDesc _build_airport_desc(
|
||||||
WDP_AUTO, nullptr, 0, 0,
|
WDP_AUTO, nullptr, 0, 0,
|
||||||
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
|
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
|
|||||||
66
src/autocompletion.cpp
Normal file
66
src/autocompletion.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file autocompletion.cpp Generic auto-completion engine. */
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "autocompletion.h"
|
||||||
|
|
||||||
|
#include "console_internal.h"
|
||||||
|
#include "town.h"
|
||||||
|
#include "network/network_base.h"
|
||||||
|
|
||||||
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
bool AutoCompletion::AutoComplete()
|
||||||
|
{
|
||||||
|
// We are pressing TAB for the first time after reset.
|
||||||
|
if (this->suggestions.empty()) {
|
||||||
|
this->InitSuggestions(this->textbuf->buf);
|
||||||
|
if (this->suggestions.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->ApplySuggestion(prefix, suggestions[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are pressing TAB again on the same text.
|
||||||
|
if (this->current_suggestion_index + 1 < this->suggestions.size()) {
|
||||||
|
this->ApplySuggestion(prefix, this->suggestions[++this->current_suggestion_index]);
|
||||||
|
} else {
|
||||||
|
// We are out of options, restore original text.
|
||||||
|
this->textbuf->Assign(initial_buf);
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoCompletion::Reset()
|
||||||
|
{
|
||||||
|
this->prefix = "";
|
||||||
|
this->query = "";
|
||||||
|
this->initial_buf.clear();
|
||||||
|
this->suggestions.clear();
|
||||||
|
this->current_suggestion_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoCompletion::InitSuggestions(std::string_view text)
|
||||||
|
{
|
||||||
|
this->initial_buf = text;
|
||||||
|
size_t space_pos = this->initial_buf.find_last_of(' ');
|
||||||
|
this->query = this->initial_buf;
|
||||||
|
if (space_pos == std::string::npos) {
|
||||||
|
this->prefix = "";
|
||||||
|
} else {
|
||||||
|
this->prefix = this->query.substr(0, space_pos + 1);
|
||||||
|
this->query.remove_prefix(space_pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->suggestions = this->GetSuggestions(prefix, query);
|
||||||
|
this->current_suggestion_index = 0;
|
||||||
|
}
|
||||||
46
src/autocompletion.h
Normal file
46
src/autocompletion.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file autocompletion.h Generic auto-completion engine. */
|
||||||
|
|
||||||
|
#ifndef AUTOCOMPLETION_H
|
||||||
|
#define AUTOCOMPLETION_H
|
||||||
|
|
||||||
|
#include "textbuf_type.h"
|
||||||
|
|
||||||
|
class AutoCompletion {
|
||||||
|
protected:
|
||||||
|
Textbuf *textbuf;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string initial_buf; ///< Value of text buffer when we started current suggestion session.
|
||||||
|
|
||||||
|
std::string_view prefix; ///< Prefix of the text before the last space.
|
||||||
|
std::string_view query; ///< Last token of the text. This is used to based the suggestions on.
|
||||||
|
|
||||||
|
std::vector<std::string> suggestions;
|
||||||
|
size_t current_suggestion_index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoCompletion(Textbuf *textbuf) : textbuf(textbuf)
|
||||||
|
{
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
virtual ~AutoCompletion() = default;
|
||||||
|
|
||||||
|
// Returns true the textbuf was updated.
|
||||||
|
bool AutoComplete();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitSuggestions(std::string_view text);
|
||||||
|
|
||||||
|
virtual std::vector<std::string> GetSuggestions(std::string_view prefix, std::string_view query) = 0;
|
||||||
|
virtual void ApplySuggestion(std::string_view prefix, std::string_view suggestion) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* AUTOCOMPLETION_H */
|
||||||
@@ -362,7 +362,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
|
|||||||
|
|
||||||
/* Refit the vehicle if needed */
|
/* Refit the vehicle if needed */
|
||||||
if (refit_cargo != CARGO_NO_REFIT) {
|
if (refit_cargo != CARGO_NO_REFIT) {
|
||||||
byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
|
uint8_t subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
|
||||||
|
|
||||||
cost.AddCost(std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0)));
|
cost.AddCost(std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0)));
|
||||||
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
|
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
#include "rail_gui.h"
|
#include "rail_gui.h"
|
||||||
#include "road_gui.h"
|
#include "road_gui.h"
|
||||||
#include "widgets/dropdown_func.h"
|
#include "dropdown_type.h"
|
||||||
|
#include "dropdown_func.h"
|
||||||
#include "autoreplace_cmd.h"
|
#include "autoreplace_cmd.h"
|
||||||
#include "group_cmd.h"
|
#include "group_cmd.h"
|
||||||
#include "settings_cmd.h"
|
#include "settings_cmd.h"
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16_t min, uint16_t max, EngineID selected_id, bool show_count, GroupID selected_group);
|
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, const Scrollbar &sb, EngineID selected_id, bool show_count, GroupID selected_group);
|
||||||
|
|
||||||
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
|
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
|
||||||
{
|
{
|
||||||
@@ -86,7 +87,7 @@ class ReplaceVehicleWindow : public Window {
|
|||||||
bool reset_sel_engine; ///< Also reset #sel_engine while updating left and/or right and no valid engine selected.
|
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.
|
GroupID sel_group; ///< Group selected to replace.
|
||||||
int details_height; ///< Minimal needed height of the details panels, in text lines (found so far).
|
int details_height; ///< Minimal needed height of the details panels, in text lines (found so far).
|
||||||
byte sort_criteria; ///< Criteria of sorting vehicles.
|
uint8_t sort_criteria; ///< Criteria of sorting vehicles.
|
||||||
bool descending_sort_order; ///< Order of sorting vehicles.
|
bool descending_sort_order; ///< Order of sorting vehicles.
|
||||||
bool show_hidden_engines; ///< Whether to show the hidden engines.
|
bool show_hidden_engines; ///< Whether to show the hidden engines.
|
||||||
RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all.
|
RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all.
|
||||||
@@ -144,7 +145,7 @@ class ReplaceVehicleWindow : public Window {
|
|||||||
std::vector<EngineID> variants;
|
std::vector<EngineID> variants;
|
||||||
EngineID selected_engine = INVALID_ENGINE;
|
EngineID selected_engine = INVALID_ENGINE;
|
||||||
VehicleType type = (VehicleType)this->window_number;
|
VehicleType type = (VehicleType)this->window_number;
|
||||||
byte side = draw_left ? 0 : 1;
|
uint8_t side = draw_left ? 0 : 1;
|
||||||
|
|
||||||
GUIEngineList list;
|
GUIEngineList list;
|
||||||
|
|
||||||
@@ -490,11 +491,9 @@ public:
|
|||||||
case WID_RV_LEFT_MATRIX:
|
case WID_RV_LEFT_MATRIX:
|
||||||
case WID_RV_RIGHT_MATRIX: {
|
case WID_RV_RIGHT_MATRIX: {
|
||||||
int side = (widget == WID_RV_LEFT_MATRIX) ? 0 : 1;
|
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 */
|
/* Do the actual drawing */
|
||||||
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
|
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], *this->vscroll[side], this->sel_engine[side], side == 0, this->sel_group);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,8 +567,8 @@ public:
|
|||||||
|
|
||||||
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: {
|
||||||
DropDownList list;
|
DropDownList list;
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_ENGINES, 1, false));
|
list.push_back(MakeDropDownListStringItem(STR_REPLACE_ENGINES, 1));
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_REPLACE_WAGONS, 0, false));
|
list.push_back(MakeDropDownListStringItem(STR_REPLACE_WAGONS, 0));
|
||||||
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -612,7 +611,7 @@ public:
|
|||||||
|
|
||||||
case WID_RV_LEFT_MATRIX:
|
case WID_RV_LEFT_MATRIX:
|
||||||
case WID_RV_RIGHT_MATRIX: {
|
case WID_RV_RIGHT_MATRIX: {
|
||||||
byte click_side;
|
uint8_t click_side;
|
||||||
if (widget == WID_RV_LEFT_MATRIX) {
|
if (widget == WID_RV_LEFT_MATRIX) {
|
||||||
click_side = 0;
|
click_side = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -788,7 +787,7 @@ static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _replace_rail_vehicle_desc(__FILE__, __LINE__,
|
static WindowDesc _replace_rail_vehicle_desc(
|
||||||
WDP_AUTO, "replace_vehicle_train", 500, 140,
|
WDP_AUTO, "replace_vehicle_train", 500, 140,
|
||||||
WC_REPLACE_VEHICLE, WC_NONE,
|
WC_REPLACE_VEHICLE, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
@@ -846,7 +845,7 @@ static constexpr NWidgetPart _nested_replace_road_vehicle_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _replace_road_vehicle_desc(__FILE__, __LINE__,
|
static WindowDesc _replace_road_vehicle_desc(
|
||||||
WDP_AUTO, "replace_vehicle_road", 500, 140,
|
WDP_AUTO, "replace_vehicle_road", 500, 140,
|
||||||
WC_REPLACE_VEHICLE, WC_NONE,
|
WC_REPLACE_VEHICLE, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
@@ -898,7 +897,7 @@ static constexpr NWidgetPart _nested_replace_vehicle_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _replace_vehicle_desc(__FILE__, __LINE__,
|
static WindowDesc _replace_vehicle_desc(
|
||||||
WDP_AUTO, "replace_vehicle", 456, 118,
|
WDP_AUTO, "replace_vehicle", 456, 118,
|
||||||
WC_REPLACE_VEHICLE, WC_NONE,
|
WC_REPLACE_VEHICLE, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ static const uint NUM_SONGS_PLAYLIST = 32;
|
|||||||
|
|
||||||
/* Functions to read DOS music CAT files, similar to but not quite the same as sound effect CAT files */
|
/* 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);
|
char *GetMusicCatEntryName(const std::string &filename, size_t entrynum);
|
||||||
byte *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
|
uint8_t *GetMusicCatEntryData(const std::string &filename, size_t entrynum, size_t &entrylen);
|
||||||
|
|
||||||
enum MusicTrackType {
|
enum MusicTrackType {
|
||||||
MTT_STANDARDMIDI, ///< Standard MIDI file
|
MTT_STANDARDMIDI, ///< Standard MIDI file
|
||||||
@@ -324,7 +324,7 @@ enum MusicTrackType {
|
|||||||
/** Metadata about a music track. */
|
/** Metadata about a music track. */
|
||||||
struct MusicSongInfo {
|
struct MusicSongInfo {
|
||||||
std::string songname; ///< name of song displayed in UI
|
std::string songname; ///< name of song displayed in UI
|
||||||
byte tracknr; ///< track number of song displayed in UI
|
uint8_t tracknr; ///< track number of song displayed in UI
|
||||||
std::string filename; ///< file on disk containing song (when used in MusicSet class)
|
std::string filename; ///< file on disk containing song (when used in MusicSet class)
|
||||||
MusicTrackType filetype; ///< decoder required for song file
|
MusicTrackType filetype; ///< decoder required for song file
|
||||||
int cat_index; ///< entry index in CAT file, for filetype==MTT_MPSMIDI
|
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. */
|
/** Data about individual songs in set. */
|
||||||
MusicSongInfo songinfo[NUM_SONGS_AVAILABLE];
|
MusicSongInfo songinfo[NUM_SONGS_AVAILABLE];
|
||||||
/** Number of valid songs in set. */
|
/** Number of valid songs in set. */
|
||||||
byte num_available;
|
uint8_t num_available;
|
||||||
|
|
||||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,16 +19,11 @@
|
|||||||
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
|
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
|
||||||
extern StationPool _station_pool;
|
extern StationPool _station_pool;
|
||||||
|
|
||||||
struct StationSpecList {
|
template <typename T>
|
||||||
const StationSpec *spec;
|
struct SpecMapping {
|
||||||
uint32_t grfid; ///< GRF ID of this custom station
|
const T *spec; ///< Custom spec.
|
||||||
uint16_t localidx; ///< Station ID within GRF of station
|
uint32_t grfid; ///< GRF ID of this custom spec.
|
||||||
};
|
uint16_t localidx; ///< Local ID within GRF of this custom spec.
|
||||||
|
|
||||||
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 {
|
struct RoadStopTileData {
|
||||||
@@ -64,7 +59,7 @@ struct StationRect : public Rect {
|
|||||||
struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||||
TileIndex xy; ///< Base tile of the station
|
TileIndex xy; ///< Base tile of the station
|
||||||
TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign
|
TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign
|
||||||
byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
|
uint8_t delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
|
||||||
|
|
||||||
std::string name; ///< Custom name
|
std::string name; ///< Custom name
|
||||||
StringID string_id; ///< Default name (town area) of station
|
StringID string_id; ///< Default name (town area) of station
|
||||||
@@ -74,13 +69,13 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
Owner owner; ///< The owner of this station
|
Owner owner; ///< The owner of this station
|
||||||
StationFacility facilities; ///< The facilities that this station has
|
StationFacility facilities; ///< The facilities that this station has
|
||||||
|
|
||||||
std::vector<StationSpecList> speclist; ///< List of rail station specs of this station.
|
std::vector<SpecMapping<StationSpec>> speclist; ///< List of rail station specs of this station.
|
||||||
std::vector<RoadStopSpecList> roadstop_speclist; ///< List of road stop specs of this station
|
std::vector<SpecMapping<RoadStopSpec>> roadstop_speclist; ///< List of road stop specs of this station
|
||||||
|
|
||||||
TimerGameCalendar::Date build_date; ///< Date of construction
|
TimerGameCalendar::Date build_date; ///< Date of construction
|
||||||
|
|
||||||
uint16_t random_bits; ///< Random bits assigned to this station
|
uint16_t random_bits; ///< Random bits assigned to this station
|
||||||
byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station
|
uint8_t waiting_triggers; ///< Waiting triggers (NewGRF) for this station
|
||||||
uint8_t cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen.
|
uint8_t cached_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.
|
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
|
CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask
|
||||||
@@ -118,7 +113,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
* @param available will return false if ever the variable asked for does not exist
|
* @param available will return false if ever the variable asked for does not exist
|
||||||
* @return the value stored in the corresponding variable
|
* @return the value stored in the corresponding variable
|
||||||
*/
|
*/
|
||||||
virtual uint32_t GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const = 0;
|
virtual uint32_t GetNewGRFVariable(const struct ResolverObject &object, uint8_t variable, uint8_t parameter, bool *available) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the coordinated of the sign (as shown in the viewport).
|
* Update the coordinated of the sign (as shown in the viewport).
|
||||||
@@ -184,7 +179,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
return (this->facilities & ~FACIL_WAYPOINT) != 0;
|
return (this->facilities & ~FACIL_WAYPOINT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline byte GetRoadStopRandomBits(TileIndex tile) const
|
inline uint8_t GetRoadStopRandomBits(TileIndex tile) const
|
||||||
{
|
{
|
||||||
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
if (tile_data.tile == tile) return tile_data.random_bits;
|
if (tile_data.tile == tile) return tile_data.random_bits;
|
||||||
@@ -192,7 +187,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline byte GetRoadStopAnimationFrame(TileIndex tile) const
|
inline uint8_t GetRoadStopAnimationFrame(TileIndex tile) const
|
||||||
{
|
{
|
||||||
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
if (tile_data.tile == tile) return tile_data.animation_frame;
|
if (tile_data.tile == tile) return tile_data.animation_frame;
|
||||||
@@ -201,11 +196,11 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetRoadStopTileData(TileIndex tile, byte data, bool animation);
|
void SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
|
inline void SetRoadStopRandomBits(TileIndex tile, uint8_t random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
|
||||||
inline void SetRoadStopAnimationFrame(TileIndex tile, byte frame) { this->SetRoadStopTileData(tile, frame, true); }
|
inline void SetRoadStopAnimationFrame(TileIndex tile, uint8_t frame) { this->SetRoadStopTileData(tile, frame, true); }
|
||||||
void RemoveRoadStopTileData(TileIndex tile);
|
void RemoveRoadStopTileData(TileIndex tile);
|
||||||
|
|
||||||
static void PostDestructor(size_t index);
|
static void PostDestructor(size_t index);
|
||||||
@@ -310,4 +305,14 @@ struct SpecializedStation : public BaseStation {
|
|||||||
static Pool::IterateWrapper<T> Iterate(size_t from = 0) { return Pool::IterateWrapper<T>(from); }
|
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 */
|
#endif /* BASE_STATION_BASE_H */
|
||||||
|
|||||||
@@ -34,23 +34,23 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
|
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
|
||||||
|
|
||||||
for (uint i = bp->skip_top; i != 0; i--) {
|
for (uint i = bp->skip_top; i != 0; i--) {
|
||||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
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;
|
uint16_t *anim = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
|
||||||
|
|
||||||
const byte *remap = bp->remap; // store so we don't have to access it via bp every time
|
const uint8_t *remap = bp->remap; // store so we don't have to access it via bp every time
|
||||||
|
|
||||||
for (int y = 0; y < bp->height; y++) {
|
for (int y = 0; y < bp->height; y++) {
|
||||||
Colour *dst_ln = dst + bp->pitch;
|
Colour *dst_ln = dst + bp->pitch;
|
||||||
uint16_t *anim_ln = anim + this->anim_buf_pitch;
|
uint16_t *anim_ln = anim + this->anim_buf_pitch;
|
||||||
|
|
||||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_px++;
|
src_px++;
|
||||||
|
|
||||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
src_n += 2;
|
src_n += 2;
|
||||||
|
|
||||||
Colour *dst_end = dst + bp->skip_left;
|
Colour *dst_end = dst + bp->skip_left;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ template <BlitterMode mode, Blitter_32bppSSE2::ReadMode read_mode, Blitter_32bpp
|
|||||||
GNU_TARGET("sse4.1")
|
GNU_TARGET("sse4.1")
|
||||||
inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom)
|
inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom)
|
||||||
{
|
{
|
||||||
const byte * const remap = bp->remap;
|
const uint8_t * const remap = bp->remap;
|
||||||
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
|
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;
|
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;
|
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 Blitter_32bppSSE_Base::SpriteData * const sd = (const Blitter_32bppSSE_Base::SpriteData *) bp->sprite;
|
||||||
const SpriteInfo * const si = &sd->infos[zoom];
|
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 MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
|
||||||
const Colour *src_rgba_line = (const Colour *) ((const byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||||
|
|
||||||
if (read_mode != RM_WITH_MARGIN) {
|
if (read_mode != RM_WITH_MARGIN) {
|
||||||
src_rgba_line += bp->skip_left;
|
src_rgba_line += bp->skip_left;
|
||||||
@@ -104,20 +104,20 @@ inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom
|
|||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
/* Remap colours. */
|
/* Remap colours. */
|
||||||
const byte m0 = mvX2;
|
const uint8_t m0 = mvX2;
|
||||||
if (m0 >= PALETTE_ANIM_START) {
|
if (m0 >= PALETTE_ANIM_START) {
|
||||||
const Colour c0 = (this->LookupColourInPalette(m0).data & 0x00FFFFFF) | (src[0].data & 0xFF000000);
|
const Colour c0 = (this->LookupColourInPalette(m0).data & 0x00FFFFFF) | (src[0].data & 0xFF000000);
|
||||||
InsertFirstUint32(AdjustBrightneSSE(c0, (byte) (mvX2 >> 8)).data, srcABCD);
|
InsertFirstUint32(AdjustBrightneSSE(c0, (uint8_t) (mvX2 >> 8)).data, srcABCD);
|
||||||
}
|
}
|
||||||
const byte m1 = mvX2 >> 16;
|
const uint8_t m1 = mvX2 >> 16;
|
||||||
if (m1 >= PALETTE_ANIM_START) {
|
if (m1 >= PALETTE_ANIM_START) {
|
||||||
const Colour c1 = (this->LookupColourInPalette(m1).data & 0x00FFFFFF) | (src[1].data & 0xFF000000);
|
const Colour c1 = (this->LookupColourInPalette(m1).data & 0x00FFFFFF) | (src[1].data & 0xFF000000);
|
||||||
InsertSecondUint32(AdjustBrightneSSE(c1, (byte) (mvX2 >> 24)).data, srcABCD);
|
InsertSecondUint32(AdjustBrightneSSE(c1, (uint8_t) (mvX2 >> 24)).data, srcABCD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update anim buffer. */
|
/* Update anim buffer. */
|
||||||
const byte a0 = src[0].a;
|
const uint8_t a0 = src[0].a;
|
||||||
const byte a1 = src[1].a;
|
const uint8_t a1 = src[1].a;
|
||||||
uint32_t anim01 = 0;
|
uint32_t anim01 = 0;
|
||||||
if (a0 == 255) {
|
if (a0 == 255) {
|
||||||
if (a1 == 255) {
|
if (a1 == 255) {
|
||||||
@@ -185,9 +185,9 @@ bmno_full_transparency:
|
|||||||
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
|
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
|
||||||
|
|
||||||
/* Remap colours. */
|
/* Remap colours. */
|
||||||
const uint m0 = (byte) mvX2;
|
const uint m0 = (uint8_t) mvX2;
|
||||||
const uint r0 = remap[m0];
|
const uint r0 = remap[m0];
|
||||||
const uint m1 = (byte) (mvX2 >> 16);
|
const uint m1 = (uint8_t) (mvX2 >> 16);
|
||||||
const uint r1 = remap[m1];
|
const uint r1 = remap[m1];
|
||||||
if (mvX2 & 0x00FF00FF) {
|
if (mvX2 & 0x00FF00FF) {
|
||||||
#define CMOV_REMAP(m_colour, m_colour_init, m_src, m_m) \
|
#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; \
|
Colour m_colour = m_colour_init; \
|
||||||
{ \
|
{ \
|
||||||
const Colour srcm = (Colour) (m_src); \
|
const Colour srcm = (Colour) (m_src); \
|
||||||
const uint m = (byte) (m_m); \
|
const uint m = (uint8_t) (m_m); \
|
||||||
const uint r = remap[m]; \
|
const uint r = remap[m]; \
|
||||||
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
||||||
m_colour = r == 0 ? m_colour : cmap; \
|
m_colour = r == 0 ? m_colour : cmap; \
|
||||||
@@ -225,8 +225,8 @@ bmno_full_transparency:
|
|||||||
|
|
||||||
/* Update anim buffer. */
|
/* Update anim buffer. */
|
||||||
if (animated) {
|
if (animated) {
|
||||||
const byte a0 = src[0].a;
|
const uint8_t a0 = src[0].a;
|
||||||
const byte a1 = src[1].a;
|
const uint8_t a1 = src[1].a;
|
||||||
uint32_t anim01 = mvX2 & 0xFF00FF00;
|
uint32_t anim01 = mvX2 & 0xFF00FF00;
|
||||||
if (a0 == 255) {
|
if (a0 == 255) {
|
||||||
anim01 |= r0;
|
anim01 |= r0;
|
||||||
@@ -368,7 +368,7 @@ bmcr_alpha_blend_single:
|
|||||||
|
|
||||||
next_line:
|
next_line:
|
||||||
if (mode != BM_TRANSPARENT && mode != BM_TRANSPARENT_REMAP) src_mv_line += si->sprite_width;
|
if (mode != BM_TRANSPARENT && mode != BM_TRANSPARENT_REMAP) src_mv_line += si->sprite_width;
|
||||||
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
|
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
|
||||||
dst_line += bp->pitch;
|
dst_line += bp->pitch;
|
||||||
anim_line += this->anim_buf_pitch;
|
anim_line += this->anim_buf_pitch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,26 +40,26 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
|
|||||||
|
|
||||||
/* skip upper lines in src_px and src_n */
|
/* skip upper lines in src_px and src_n */
|
||||||
for (uint i = bp->skip_top; i != 0; i--) {
|
for (uint i = bp->skip_top; i != 0; i--) {
|
||||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip lines in dst */
|
/* skip lines in dst */
|
||||||
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
|
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) */
|
/* store so we don't have to access it via bp every time (compiler assumes pointer aliasing) */
|
||||||
const byte *remap = bp->remap;
|
const uint8_t *remap = bp->remap;
|
||||||
|
|
||||||
for (int y = 0; y < bp->height; y++) {
|
for (int y = 0; y < bp->height; y++) {
|
||||||
/* next dst line begins here */
|
/* next dst line begins here */
|
||||||
Colour *dst_ln = dst + bp->pitch;
|
Colour *dst_ln = dst + bp->pitch;
|
||||||
|
|
||||||
/* next src line begins here */
|
/* next src line begins here */
|
||||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_px++;
|
src_px++;
|
||||||
|
|
||||||
/* next src_n line begins here */
|
/* next src_n line begins here */
|
||||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
src_n += 2;
|
src_n += 2;
|
||||||
|
|
||||||
/* we will end this line when we reach this point */
|
/* we will end this line when we reach this point */
|
||||||
@@ -405,8 +405,8 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
|||||||
dst_n_ln = (uint32_t *)dst_n;
|
dst_n_ln = (uint32_t *)dst_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary
|
lengths[z][0] = (uint8_t *)dst_px_ln - (uint8_t *)dst_px_orig[z]; // all are aligned to 4B boundary
|
||||||
lengths[z][1] = (byte *)dst_n_ln - (byte *)dst_n_orig[z];
|
lengths[z][1] = (uint8_t *)dst_n_ln - (uint8_t *)dst_n_orig[z];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint len = 0; // total length of data
|
uint len = 0; // total length of data
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
/** Data stored about a (single) sprite. */
|
/** Data stored about a (single) sprite. */
|
||||||
struct SpriteData {
|
struct SpriteData {
|
||||||
uint32_t offset[ZOOM_LVL_END][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
|
uint32_t offset[ZOOM_LVL_END][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
|
||||||
byte data[]; ///< Data, all zoomlevels.
|
uint8_t data[]; ///< Data, all zoomlevels.
|
||||||
};
|
};
|
||||||
|
|
||||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
|
|||||||
(*dst_rgba_line).data = nb_pix_transp;
|
(*dst_rgba_line).data = nb_pix_transp;
|
||||||
|
|
||||||
Colour *nb_right = dst_rgba_line + 1;
|
Colour *nb_right = dst_rgba_line + 1;
|
||||||
dst_rgba_line = (Colour*) ((byte*) dst_rgba_line + sd.infos[z].sprite_line_size);
|
dst_rgba_line = (Colour*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
|
||||||
|
|
||||||
/* Count the number of transparent pixels from the right. */
|
/* Count the number of transparent pixels from the right. */
|
||||||
dst_rgba = dst_rgba_line - 1;
|
dst_rgba = dst_rgba_line - 1;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
struct SpriteData {
|
struct SpriteData {
|
||||||
SpriteFlags flags;
|
SpriteFlags flags;
|
||||||
SpriteInfo infos[ZOOM_LVL_END];
|
SpriteInfo infos[ZOOM_LVL_END];
|
||||||
byte data[]; ///< Data, all zoomlevels.
|
uint8_t data[]; ///< Data, all zoomlevels.
|
||||||
};
|
};
|
||||||
|
|
||||||
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
|
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
|
||||||
|
|||||||
@@ -10,10 +10,17 @@
|
|||||||
#ifndef BLITTER_32BPP_SSE_FUNC_HPP
|
#ifndef BLITTER_32BPP_SSE_FUNC_HPP
|
||||||
#define 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
|
#ifdef WITH_SSE
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline void InsertFirstUint32(const uint32_t value, __m128i &into)
|
INTERNAL_LINKAGE inline void InsertFirstUint32(const uint32_t value, __m128i &into)
|
||||||
{
|
{
|
||||||
#if (SSE_VERSION >= 4)
|
#if (SSE_VERSION >= 4)
|
||||||
into = _mm_insert_epi32(into, value, 0);
|
into = _mm_insert_epi32(into, value, 0);
|
||||||
@@ -24,7 +31,7 @@ inline void InsertFirstUint32(const uint32_t value, __m128i &into)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline void InsertSecondUint32(const uint32_t value, __m128i &into)
|
INTERNAL_LINKAGE inline void InsertSecondUint32(const uint32_t value, __m128i &into)
|
||||||
{
|
{
|
||||||
#if (SSE_VERSION >= 4)
|
#if (SSE_VERSION >= 4)
|
||||||
into = _mm_insert_epi32(into, value, 1);
|
into = _mm_insert_epi32(into, value, 1);
|
||||||
@@ -35,7 +42,7 @@ inline void InsertSecondUint32(const uint32_t value, __m128i &into)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline void LoadUint64(const uint64_t value, __m128i &into)
|
INTERNAL_LINKAGE inline void LoadUint64(const uint64_t value, __m128i &into)
|
||||||
{
|
{
|
||||||
#ifdef POINTER_IS_64BIT
|
#ifdef POINTER_IS_64BIT
|
||||||
into = _mm_cvtsi64_si128(value);
|
into = _mm_cvtsi64_si128(value);
|
||||||
@@ -50,7 +57,7 @@ inline void LoadUint64(const uint64_t value, __m128i &into)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
|
INTERNAL_LINKAGE inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
|
||||||
{
|
{
|
||||||
#if (SSE_VERSION == 2)
|
#if (SSE_VERSION == 2)
|
||||||
from = _mm_and_si128(from, mask); // PAND, wipe high bytes to keep low bytes when packing
|
from = _mm_and_si128(from, mask); // PAND, wipe high bytes to keep low bytes when packing
|
||||||
@@ -61,7 +68,7 @@ inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
|
INTERNAL_LINKAGE inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
|
||||||
{
|
{
|
||||||
#if (SSE_VERSION == 2)
|
#if (SSE_VERSION == 2)
|
||||||
__m128i alphaAB = _mm_shufflelo_epi16(from, 0x3F); // PSHUFLW, put alpha1 in front of each rgb1
|
__m128i alphaAB = _mm_shufflelo_epi16(from, 0x3F); // PSHUFLW, put alpha1 in front of each rgb1
|
||||||
@@ -73,7 +80,7 @@ inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask)
|
INTERNAL_LINKAGE 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 srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); // PUNPCKLBW, expand each uint8_t into uint16
|
||||||
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
|
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
|
||||||
@@ -97,7 +104,7 @@ inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &dist
|
|||||||
* rgb = rgb * ((256/4) * 4 - (alpha/4)) / ((256/4) * 4)
|
* rgb = rgb * ((256/4) * 4 - (alpha/4)) / ((256/4) * 4)
|
||||||
*/
|
*/
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base)
|
INTERNAL_LINKAGE 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 srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128());
|
||||||
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
|
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
|
||||||
@@ -111,7 +118,7 @@ inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribu
|
|||||||
|
|
||||||
IGNORE_UNINITIALIZED_WARNING_START
|
IGNORE_UNINITIALIZED_WARNING_START
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
static Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness)
|
INTERNAL_LINKAGE Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness)
|
||||||
{
|
{
|
||||||
uint64_t c16 = colour.b | (uint64_t) colour.g << 16 | (uint64_t) colour.r << 32;
|
uint64_t c16 = colour.b | (uint64_t) colour.g << 16 | (uint64_t) colour.r << 32;
|
||||||
c16 *= brightness;
|
c16 *= brightness;
|
||||||
@@ -145,7 +152,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP
|
|||||||
/** ReallyAdjustBrightness() is not called that often.
|
/** ReallyAdjustBrightness() is not called that often.
|
||||||
* Inlining this function implies a far jump, which has a huge latency.
|
* Inlining this function implies a far jump, which has a huge latency.
|
||||||
*/
|
*/
|
||||||
inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
|
INTERNAL_LINKAGE inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
|
||||||
{
|
{
|
||||||
/* Shortcut for normal brightness. */
|
/* Shortcut for normal brightness. */
|
||||||
if (brightness == Blitter_32bppBase::DEFAULT_BRIGHTNESS) return colour;
|
if (brightness == Blitter_32bppBase::DEFAULT_BRIGHTNESS) return colour;
|
||||||
@@ -154,7 +161,7 @@ inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GNU_TARGET(SSE_TARGET)
|
GNU_TARGET(SSE_TARGET)
|
||||||
inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m128i from, [[maybe_unused]] uint32_t brightness)
|
INTERNAL_LINKAGE inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m128i from, [[maybe_unused]] uint32_t brightness)
|
||||||
{
|
{
|
||||||
#if (SSE_VERSION < 3)
|
#if (SSE_VERSION < 3)
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
@@ -214,7 +221,7 @@ inline void Blitter_32bppSSSE3::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
|
inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const byte * const remap = bp->remap;
|
const uint8_t * const remap = bp->remap;
|
||||||
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
|
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
|
||||||
int effective_width = bp->width;
|
int effective_width = bp->width;
|
||||||
|
|
||||||
@@ -222,7 +229,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
const SpriteData * const sd = (const SpriteData *) bp->sprite;
|
const SpriteData * const sd = (const SpriteData *) bp->sprite;
|
||||||
const SpriteInfo * const si = &sd->infos[zoom];
|
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 MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
|
||||||
const Colour *src_rgba_line = (const Colour *) ((const byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
|
||||||
|
|
||||||
if (read_mode != RM_WITH_MARGIN) {
|
if (read_mode != RM_WITH_MARGIN) {
|
||||||
src_rgba_line += bp->skip_left;
|
src_rgba_line += bp->skip_left;
|
||||||
@@ -307,7 +314,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
Colour m_colour = m_colour_init; \
|
Colour m_colour = m_colour_init; \
|
||||||
{ \
|
{ \
|
||||||
const Colour srcm = (Colour) (m_src); \
|
const Colour srcm = (Colour) (m_src); \
|
||||||
const uint m = (byte) (m_m); \
|
const uint m = (uint8_t) (m_m); \
|
||||||
const uint r = remap[m]; \
|
const uint r = remap[m]; \
|
||||||
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \
|
||||||
m_colour = r == 0 ? m_colour : cmap; \
|
m_colour = r == 0 ? m_colour : cmap; \
|
||||||
@@ -435,7 +442,7 @@ bmcr_alpha_blend_single:
|
|||||||
|
|
||||||
next_line:
|
next_line:
|
||||||
if (mode == BM_COLOUR_REMAP || mode == BM_CRASH_REMAP) src_mv_line += si->sprite_width;
|
if (mode == BM_COLOUR_REMAP || mode == BM_CRASH_REMAP) src_mv_line += si->sprite_width;
|
||||||
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
|
src_rgba_line = (const Colour*) ((const uint8_t*) src_rgba_line + si->sprite_line_size);
|
||||||
dst_line += bp->pitch;
|
dst_line += bp->pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
#ifndef BLITTER_32BPP_SSE_TYPE_H
|
#ifndef BLITTER_32BPP_SSE_TYPE_H
|
||||||
#define 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
|
#ifdef WITH_SSE
|
||||||
|
|
||||||
#include "32bpp_simple.hpp"
|
#include "32bpp_simple.hpp"
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
|
|
||||||
/* skip upper lines in src_px and src_n */
|
/* skip upper lines in src_px and src_n */
|
||||||
for (uint i = bp->skip_top; i != 0; i--) {
|
for (uint i = bp->skip_top; i != 0; i--) {
|
||||||
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
src_px = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
src_n = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip lines in dst */
|
/* skip lines in dst */
|
||||||
@@ -114,7 +114,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
uint8_t *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32_t *)bp->dst - (uint32_t *)_screen.dst_ptr) + bp->top * bp->pitch + bp->left;
|
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) */
|
/* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */
|
||||||
const byte *remap = bp->remap;
|
const uint8_t *remap = bp->remap;
|
||||||
|
|
||||||
for (int y = 0; y < bp->height; y++) {
|
for (int y = 0; y < bp->height; y++) {
|
||||||
/* next dst line begins here */
|
/* next dst line begins here */
|
||||||
@@ -122,11 +122,11 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
uint8_t *anim_ln = anim + bp->pitch;
|
uint8_t *anim_ln = anim + bp->pitch;
|
||||||
|
|
||||||
/* next src line begins here */
|
/* next src line begins here */
|
||||||
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
|
const Colour *src_px_ln = (const Colour *)((const uint8_t *)src_px + *(const uint32_t *)src_px);
|
||||||
src_px++;
|
src_px++;
|
||||||
|
|
||||||
/* next src_n line begins here */
|
/* next src_n line begins here */
|
||||||
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
|
const uint16_t *src_n_ln = (const uint16_t *)((const uint8_t *)src_n + *(const uint32_t *)src_n);
|
||||||
src_n += 2;
|
src_n += 2;
|
||||||
|
|
||||||
/* we will end this line when we reach this point */
|
/* we will end this line when we reach this point */
|
||||||
|
|||||||
@@ -147,10 +147,10 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
|||||||
/* Don't allocate memory each time, but just keep some
|
/* Don't allocate memory each time, but just keep some
|
||||||
* memory around as this function is called quite often
|
* memory around as this function is called quite often
|
||||||
* and the memory usage is quite low. */
|
* and the memory usage is quite low. */
|
||||||
static ReusableBuffer<byte> temp_buffer;
|
static ReusableBuffer<uint8_t> temp_buffer;
|
||||||
SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
|
SpriteData *temp_dst = (SpriteData *)temp_buffer.Allocate(memory);
|
||||||
memset(temp_dst, 0, sizeof(*temp_dst));
|
memset(temp_dst, 0, sizeof(*temp_dst));
|
||||||
byte *dst = temp_dst->data;
|
uint8_t *dst = temp_dst->data;
|
||||||
|
|
||||||
/* Make the sprites per zoom-level */
|
/* Make the sprites per zoom-level */
|
||||||
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
|
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {
|
||||||
@@ -166,7 +166,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
|||||||
uint trans = 0;
|
uint trans = 0;
|
||||||
uint pixels = 0;
|
uint pixels = 0;
|
||||||
uint last_colour = 0;
|
uint last_colour = 0;
|
||||||
byte *count_dst = nullptr;
|
uint8_t *count_dst = nullptr;
|
||||||
|
|
||||||
/* Store the scaled image */
|
/* Store the scaled image */
|
||||||
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
|
const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width];
|
||||||
@@ -213,7 +213,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &spri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint size = dst - (byte *)temp_dst;
|
uint size = dst - (uint8_t *)temp_dst;
|
||||||
|
|
||||||
/* Safety check, to make sure we guessed the size correctly */
|
/* Safety check, to make sure we guessed the size correctly */
|
||||||
assert(size < memory);
|
assert(size < memory);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
/** Data stored about a (single) sprite. */
|
/** Data stored about a (single) sprite. */
|
||||||
struct SpriteData {
|
struct SpriteData {
|
||||||
uint32_t offset[ZOOM_LVL_END]; ///< Offsets (from .data) to streams for different zoom levels.
|
uint32_t offset[ZOOM_LVL_END]; ///< Offsets (from .data) to streams for different zoom levels.
|
||||||
byte data[]; ///< Data, all zoomlevels.
|
uint8_t data[]; ///< Data, all zoomlevels.
|
||||||
};
|
};
|
||||||
|
|
||||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
/** Parameters related to blitting. */
|
/** Parameters related to blitting. */
|
||||||
struct BlitterParams {
|
struct BlitterParams {
|
||||||
const void *sprite; ///< Pointer to the sprite how ever the encoder stored it
|
const void *sprite; ///< Pointer to the sprite how ever the encoder stored it
|
||||||
const byte *remap; ///< XXX -- Temporary storage for remap array
|
const uint8_t *remap; ///< XXX -- Temporary storage for remap array
|
||||||
|
|
||||||
int skip_left; ///< How much pixels of the source to skip on the left (based on zoom of dst)
|
int skip_left; ///< How much pixels of the source to skip on the left (based on zoom of dst)
|
||||||
int skip_top; ///< How much pixels of the source to skip on the top (based on zoom of dst)
|
int skip_top; ///< How much pixels of the source to skip on the top (based on zoom of dst)
|
||||||
|
|||||||
46
src/bmp.cpp
46
src/bmp.cpp
@@ -39,7 +39,7 @@ static inline bool EndOfBuffer(BmpBuffer *buffer)
|
|||||||
return buffer->pos == buffer->read;
|
return buffer->pos == buffer->read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline byte ReadByte(BmpBuffer *buffer)
|
static inline uint8_t ReadByte(BmpBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (buffer->read < 0) return 0;
|
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)
|
static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
{
|
{
|
||||||
uint x, y, i;
|
uint x, y, i;
|
||||||
byte pad = GB(4 - info->width / 8, 0, 2);
|
uint8_t pad = GB(4 - info->width / 8, 0, 2);
|
||||||
byte *pixel_row;
|
uint8_t *pixel_row;
|
||||||
byte b;
|
uint8_t b;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info->height; y > 0; y--) {
|
||||||
x = 0;
|
x = 0;
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
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)
|
static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
{
|
{
|
||||||
uint x, y;
|
uint x, y;
|
||||||
byte pad = GB(4 - info->width / 2, 0, 2);
|
uint8_t pad = GB(4 - info->width / 2, 0, 2);
|
||||||
byte *pixel_row;
|
uint8_t *pixel_row;
|
||||||
byte b;
|
uint8_t b;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info->height; y > 0; y--) {
|
||||||
x = 0;
|
x = 0;
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
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 x = 0;
|
||||||
uint y = info->height - 1;
|
uint y = info->height - 1;
|
||||||
byte *pixel = &data->bitmap[y * info->width];
|
uint8_t *pixel = &data->bitmap[y * info->width];
|
||||||
while (y != 0 || x < info->width) {
|
while (y != 0 || x < info->width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
|
|
||||||
byte n = ReadByte(buffer);
|
uint8_t n = ReadByte(buffer);
|
||||||
byte c = ReadByte(buffer);
|
uint8_t c = ReadByte(buffer);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 0: // end of line
|
case 0: // end of line
|
||||||
@@ -159,8 +159,8 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
|||||||
|
|
||||||
case 2: { // delta
|
case 2: { // delta
|
||||||
if (EndOfBuffer(buffer)) return false;
|
if (EndOfBuffer(buffer)) return false;
|
||||||
byte dx = ReadByte(buffer);
|
uint8_t dx = ReadByte(buffer);
|
||||||
byte dy = ReadByte(buffer);
|
uint8_t dy = ReadByte(buffer);
|
||||||
|
|
||||||
/* Check for over- and underflow. */
|
/* Check for over- and underflow. */
|
||||||
if (x + dx >= info->width || x + dx < x || dy > y) return false;
|
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;
|
uint i = 0;
|
||||||
while (i++ < c) {
|
while (i++ < c) {
|
||||||
if (EndOfBuffer(buffer) || x >= info->width) return false;
|
if (EndOfBuffer(buffer) || x >= info->width) return false;
|
||||||
byte b = ReadByte(buffer);
|
uint8_t b = ReadByte(buffer);
|
||||||
*pixel++ = GB(b, 4, 4);
|
*pixel++ = GB(b, 4, 4);
|
||||||
x++;
|
x++;
|
||||||
if (i++ < c) {
|
if (i++ < c) {
|
||||||
@@ -214,8 +214,8 @@ static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
|||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
uint y;
|
uint y;
|
||||||
byte pad = GB(4 - info->width, 0, 2);
|
uint8_t pad = GB(4 - info->width, 0, 2);
|
||||||
byte *pixel;
|
uint8_t *pixel;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info->height; y > 0; y--) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
pixel = &data->bitmap[(y - 1) * info->width];
|
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 x = 0;
|
||||||
uint y = info->height - 1;
|
uint y = info->height - 1;
|
||||||
byte *pixel = &data->bitmap[y * info->width];
|
uint8_t *pixel = &data->bitmap[y * info->width];
|
||||||
while (y != 0 || x < info->width) {
|
while (y != 0 || x < info->width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
|
|
||||||
byte n = ReadByte(buffer);
|
uint8_t n = ReadByte(buffer);
|
||||||
byte c = ReadByte(buffer);
|
uint8_t c = ReadByte(buffer);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 0: // end of line
|
case 0: // end of line
|
||||||
@@ -252,8 +252,8 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
|||||||
|
|
||||||
case 2: { // delta
|
case 2: { // delta
|
||||||
if (EndOfBuffer(buffer)) return false;
|
if (EndOfBuffer(buffer)) return false;
|
||||||
byte dx = ReadByte(buffer);
|
uint8_t dx = ReadByte(buffer);
|
||||||
byte dy = ReadByte(buffer);
|
uint8_t dy = ReadByte(buffer);
|
||||||
|
|
||||||
/* Check for over- and underflow. */
|
/* Check for over- and underflow. */
|
||||||
if (x + dx >= info->width || x + dx < x || dy > y) return false;
|
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)
|
static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
{
|
{
|
||||||
uint x, y;
|
uint x, y;
|
||||||
byte pad = GB(4 - info->width * 3, 0, 2);
|
uint8_t pad = GB(4 - info->width * 3, 0, 2);
|
||||||
byte *pixel_row;
|
uint8_t *pixel_row;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info->height; y > 0; y--) {
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width * 3];
|
pixel_row = &data->bitmap[(y - 1) * info->width * 3];
|
||||||
for (x = 0; x < info->width; x++) {
|
for (x = 0; x < info->width; x++) {
|
||||||
@@ -395,7 +395,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
|||||||
{
|
{
|
||||||
assert(info != nullptr && data != nullptr);
|
assert(info != nullptr && data != nullptr);
|
||||||
|
|
||||||
data->bitmap = CallocT<byte>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
|
data->bitmap = CallocT<uint8_t>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
|
||||||
|
|
||||||
/* Load image */
|
/* Load image */
|
||||||
SetStreamOffset(buffer, info->offset);
|
SetStreamOffset(buffer, info->offset);
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ struct BmpInfo {
|
|||||||
|
|
||||||
struct BmpData {
|
struct BmpData {
|
||||||
Colour *palette;
|
Colour *palette;
|
||||||
byte *bitmap;
|
uint8_t *bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BMP_BUFFER_SIZE 1024
|
#define BMP_BUFFER_SIZE 1024
|
||||||
|
|
||||||
struct BmpBuffer {
|
struct BmpBuffer {
|
||||||
byte data[BMP_BUFFER_SIZE];
|
uint8_t data[BMP_BUFFER_SIZE];
|
||||||
int pos;
|
int pos;
|
||||||
int read;
|
int read;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ static constexpr NWidgetPart _background_widgets[] = {
|
|||||||
/**
|
/**
|
||||||
* Window description for the background window to prevent smearing.
|
* Window description for the background window to prevent smearing.
|
||||||
*/
|
*/
|
||||||
static WindowDesc _background_desc(__FILE__, __LINE__,
|
static WindowDesc _background_desc(
|
||||||
WDP_MANUAL, nullptr, 0, 0,
|
WDP_MANUAL, nullptr, 0, 0,
|
||||||
WC_BOOTSTRAP, WC_NONE,
|
WC_BOOTSTRAP, WC_NONE,
|
||||||
WDF_NO_CLOSE,
|
WDF_NO_CLOSE,
|
||||||
@@ -76,7 +76,7 @@ static constexpr NWidgetPart _nested_bootstrap_errmsg_widgets[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Window description for the error window. */
|
/** Window description for the error window. */
|
||||||
static WindowDesc _bootstrap_errmsg_desc(__FILE__, __LINE__,
|
static WindowDesc _bootstrap_errmsg_desc(
|
||||||
WDP_CENTER, nullptr, 0, 0,
|
WDP_CENTER, nullptr, 0, 0,
|
||||||
WC_BOOTSTRAP, WC_NONE,
|
WC_BOOTSTRAP, WC_NONE,
|
||||||
WDF_MODAL | WDF_NO_CLOSE,
|
WDF_MODAL | WDF_NO_CLOSE,
|
||||||
@@ -133,7 +133,7 @@ static constexpr NWidgetPart _nested_bootstrap_download_status_window_widgets[]
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Window description for the download window */
|
/** Window description for the download window */
|
||||||
static WindowDesc _bootstrap_download_status_window_desc(__FILE__, __LINE__,
|
static WindowDesc _bootstrap_download_status_window_desc(
|
||||||
WDP_CENTER, nullptr, 0, 0,
|
WDP_CENTER, nullptr, 0, 0,
|
||||||
WC_NETWORK_STATUS_WINDOW, WC_NONE,
|
WC_NETWORK_STATUS_WINDOW, WC_NONE,
|
||||||
WDF_MODAL | WDF_NO_CLOSE,
|
WDF_MODAL | WDF_NO_CLOSE,
|
||||||
@@ -185,7 +185,7 @@ static constexpr NWidgetPart _bootstrap_query_widgets[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** The window description for the query. */
|
/** The window description for the query. */
|
||||||
static WindowDesc _bootstrap_query_desc(__FILE__, __LINE__,
|
static WindowDesc _bootstrap_query_desc(
|
||||||
WDP_CENTER, nullptr, 0, 0,
|
WDP_CENTER, nullptr, 0, 0,
|
||||||
WC_CONFIRM_POPUP_QUERY, WC_NONE,
|
WC_CONFIRM_POPUP_QUERY, WC_NONE,
|
||||||
WDF_NO_CLOSE,
|
WDF_NO_CLOSE,
|
||||||
@@ -385,9 +385,9 @@ bool HandleBootstrap()
|
|||||||
* This way the mauve and gray colours work and we can show the user interface. */
|
* This way the mauve and gray colours work and we can show the user interface. */
|
||||||
GfxInitPalettes();
|
GfxInitPalettes();
|
||||||
static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 };
|
static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 };
|
||||||
for (uint i = 0; i != 16; i++) {
|
for (Colours i = COLOUR_BEGIN; i != COLOUR_END; i++) {
|
||||||
for (int j = 0; j < 8; j++) {
|
for (ColourShade j = SHADE_BEGIN; j < SHADE_END; j++) {
|
||||||
_colour_gradient[i][j] = offsets[i] + j;
|
SetColourGradient(i, j, offsets[i] + j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ typedef uint BridgeType; ///< Bridge spec number.
|
|||||||
*/
|
*/
|
||||||
struct BridgeSpec {
|
struct BridgeSpec {
|
||||||
TimerGameCalendar::Year avail_year; ///< the year where it becomes available
|
TimerGameCalendar::Year avail_year; ///< the year where it becomes available
|
||||||
byte min_length; ///< the minimum length (not counting start and end tile)
|
uint8_t min_length; ///< the minimum length (not counting start and end tile)
|
||||||
uint16_t max_length; ///< the maximum length (not counting start and end tile)
|
uint16_t max_length; ///< the maximum length (not counting start and end tile)
|
||||||
uint16_t price; ///< the price multiplier
|
uint16_t price; ///< the price multiplier
|
||||||
uint16_t speed; ///< maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
|
uint16_t speed; ///< maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
|
||||||
@@ -50,7 +50,7 @@ struct BridgeSpec {
|
|||||||
StringID material; ///< the string that contains the bridge description
|
StringID material; ///< the string that contains the bridge description
|
||||||
StringID transport_name[2]; ///< description of the bridge, when built for road or rail
|
StringID transport_name[2]; ///< description of the bridge, when built for road or rail
|
||||||
PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
|
PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
|
||||||
byte flags; ///< bit 0 set: disable drawing of far pillars.
|
uint8_t flags; ///< bit 0 set: disable drawing of far pillars.
|
||||||
};
|
};
|
||||||
|
|
||||||
extern BridgeSpec _bridge[MAX_BRIDGES];
|
extern BridgeSpec _bridge[MAX_BRIDGES];
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
#include "tunnelbridge.h"
|
#include "tunnelbridge.h"
|
||||||
#include "sortlist_type.h"
|
#include "sortlist_type.h"
|
||||||
#include "widgets/dropdown_func.h"
|
#include "dropdown_func.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
#include "tunnelbridge_map.h"
|
#include "tunnelbridge_map.h"
|
||||||
#include "road_gui.h"
|
#include "road_gui.h"
|
||||||
@@ -55,7 +55,7 @@ typedef GUIList<BuildBridgeData> GUIBridgeList; ///< List of bridges, used in #B
|
|||||||
* @param tile_start start tile
|
* @param tile_start start tile
|
||||||
* @param transport_type transport type.
|
* @param transport_type transport type.
|
||||||
*/
|
*/
|
||||||
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, byte)
|
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t)
|
||||||
{
|
{
|
||||||
if (result.Failed()) return;
|
if (result.Failed()) return;
|
||||||
if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile);
|
if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile);
|
||||||
@@ -83,7 +83,7 @@ private:
|
|||||||
TileIndex start_tile;
|
TileIndex start_tile;
|
||||||
TileIndex end_tile;
|
TileIndex end_tile;
|
||||||
TransportType transport_type;
|
TransportType transport_type;
|
||||||
byte road_rail_type;
|
uint8_t road_rail_type;
|
||||||
GUIBridgeList bridges;
|
GUIBridgeList bridges;
|
||||||
int icon_width; ///< Scaled width of the the bridge icon sprite.
|
int icon_width; ///< Scaled width of the the bridge icon sprite.
|
||||||
Scrollbar *vscroll;
|
Scrollbar *vscroll;
|
||||||
@@ -148,7 +148,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, GUIBridgeList &&bl) : Window(desc),
|
BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type, GUIBridgeList &&bl) : Window(desc),
|
||||||
start_tile(start),
|
start_tile(start),
|
||||||
end_tile(end),
|
end_tile(end),
|
||||||
transport_type(transport_type),
|
transport_type(transport_type),
|
||||||
@@ -233,11 +233,11 @@ public:
|
|||||||
case WID_BBS_BRIDGE_LIST: {
|
case WID_BBS_BRIDGE_LIST: {
|
||||||
Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
|
Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
|
||||||
bool rtl = _current_text_dir == TD_RTL;
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges.size(); i++) {
|
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->bridges);
|
||||||
const BuildBridgeData &bridge_data = this->bridges.at(i);
|
for (auto it = first; it != last; ++it) {
|
||||||
const BridgeSpec *b = bridge_data.spec;
|
const BridgeSpec *b = it->spec;
|
||||||
DrawSpriteIgnorePadding(b->sprite, b->pal, tr.WithWidth(this->icon_width, rtl), SA_HOR_CENTER | SA_BOTTOM);
|
DrawSpriteIgnorePadding(b->sprite, b->pal, tr.WithWidth(this->icon_width, rtl), SA_HOR_CENTER | SA_BOTTOM);
|
||||||
DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(bridge_data));
|
DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(*it));
|
||||||
tr = tr.Translate(0, this->resize.step_height);
|
tr = tr.Translate(0, this->resize.step_height);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -343,7 +343,7 @@ static constexpr NWidgetPart _nested_build_bridge_widgets[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Window definition for the rail bridge selection window. */
|
/** Window definition for the rail bridge selection window. */
|
||||||
static WindowDesc _build_bridge_desc(__FILE__, __LINE__,
|
static WindowDesc _build_bridge_desc(
|
||||||
WDP_AUTO, "build_bridge", 200, 114,
|
WDP_AUTO, "build_bridge", 200, 114,
|
||||||
WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
|
WC_BUILD_BRIDGE, WC_BUILD_TOOLBAR,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
@@ -360,7 +360,7 @@ static WindowDesc _build_bridge_desc(__FILE__, __LINE__,
|
|||||||
* @param transport_type The transport type
|
* @param transport_type The transport type
|
||||||
* @param road_rail_type The road/rail type
|
* @param road_rail_type The road/rail type
|
||||||
*/
|
*/
|
||||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
|
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type)
|
||||||
{
|
{
|
||||||
CloseWindowByClass(WC_BUILD_BRIDGE);
|
CloseWindowByClass(WC_BUILD_BRIDGE);
|
||||||
|
|
||||||
|
|||||||
@@ -69,10 +69,9 @@ TileIndex GetOtherBridgeEnd(TileIndex tile)
|
|||||||
*/
|
*/
|
||||||
int GetBridgeHeight(TileIndex t)
|
int GetBridgeHeight(TileIndex t)
|
||||||
{
|
{
|
||||||
int h;
|
auto [tileh, h] = GetTileSlopeZ(t);
|
||||||
Slope tileh = GetTileSlope(t, &h);
|
|
||||||
Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetTunnelBridgeDirection(t)));
|
Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetTunnelBridgeDirection(t)));
|
||||||
|
|
||||||
/* one height level extra for the ramp */
|
/* one height level extra for the ramp */
|
||||||
return h + 1 + ApplyFoundationToSlope(f, &tileh);
|
return h + 1 + ApplyFoundationToSlope(f, tileh);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ static const NWidgetPart _nested_build_info_widgets[] = {
|
|||||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(),
|
NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _build_info_desc(__FILE__, __LINE__,
|
static WindowDesc _build_info_desc(
|
||||||
WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
|
WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used,
|
||||||
WC_TOOLTIPS, WC_NONE,
|
WC_TOOLTIPS, WC_NONE,
|
||||||
WDF_NO_FOCUS,
|
WDF_NO_FOCUS,
|
||||||
std::begin(_nested_build_info_widgets), std::end(_nested_build_info_widgets)
|
std::begin(_nested_build_info_widgets), std::end(_nested_build_info_widgets)
|
||||||
@@ -225,7 +225,7 @@ static const NWidgetPart _nested_build_confirmation_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _build_confirmation_desc(__FILE__, __LINE__,
|
static WindowDesc _build_confirmation_desc(
|
||||||
WDP_MANUAL, "build_confirmation", 0, 0,
|
WDP_MANUAL, "build_confirmation", 0, 0,
|
||||||
WC_BUILD_CONFIRMATION, WC_NONE,
|
WC_BUILD_CONFIRMATION, WC_NONE,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
#include "window_func.h"
|
#include "window_func.h"
|
||||||
#include "timer/timer_game_calendar.h"
|
#include "timer/timer_game_calendar.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "widgets/dropdown_func.h"
|
#include "dropdown_type.h"
|
||||||
|
#include "dropdown_func.h"
|
||||||
#include "engine_gui.h"
|
#include "engine_gui.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
@@ -97,7 +98,7 @@ static constexpr NWidgetPart _nested_build_vehicle_widgets[] = {
|
|||||||
|
|
||||||
|
|
||||||
bool _engine_sort_direction; ///< \c false = descending, \c true = ascending.
|
bool _engine_sort_direction; ///< \c false = descending, \c true = ascending.
|
||||||
byte _engine_sort_last_criteria[] = {0, 0, 0, 0}; ///< Last set sort criteria, for each vehicle type.
|
uint8_t _engine_sort_last_criteria[] = {0, 0, 0, 0}; ///< Last set sort criteria, for each vehicle type.
|
||||||
bool _engine_sort_last_order[] = {false, false, false, false}; ///< Last set direction of the sort order, for each vehicle type.
|
bool _engine_sort_last_order[] = {false, false, false, false}; ///< Last set direction of the sort order, for each vehicle type.
|
||||||
bool _engine_sort_show_hidden_engines[] = {false, false, false, false}; ///< Last set 'show hidden engines' setting for each vehicle type.
|
bool _engine_sort_show_hidden_engines[] = {false, false, false, false}; ///< Last set 'show hidden engines' setting for each vehicle type.
|
||||||
static CargoID _engine_sort_last_cargo_criteria[] = {CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY}; ///< Last set filter criteria, for each vehicle type.
|
static CargoID _engine_sort_last_cargo_criteria[] = {CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY, CargoFilterCriteria::CF_ANY}; ///< Last set filter criteria, for each vehicle type.
|
||||||
@@ -1000,18 +1001,16 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
|
|||||||
* @param type Type of vehicle (VEH_*)
|
* @param type Type of vehicle (VEH_*)
|
||||||
* @param r The Rect of the list
|
* @param r The Rect of the list
|
||||||
* @param eng_list What engines to draw
|
* @param eng_list What engines to draw
|
||||||
* @param min where to start in the list
|
* @param sb Scrollbar of list.
|
||||||
* @param max where in the list to end
|
|
||||||
* @param selected_id what engine to highlight as selected, if any
|
* @param selected_id what engine to highlight as selected, if any
|
||||||
* @param show_count Whether to show the amount of engines or not
|
* @param show_count Whether to show the amount of engines or not
|
||||||
* @param selected_group the group to list the engines of
|
* @param selected_group the group to list the engines of
|
||||||
*/
|
*/
|
||||||
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16_t min, uint16_t max, EngineID selected_id, bool show_count, GroupID selected_group)
|
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, const Scrollbar &sb, EngineID selected_id, bool show_count, GroupID selected_group)
|
||||||
{
|
{
|
||||||
static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
|
static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
|
||||||
|
|
||||||
/* Obligatory sanity checks! */
|
auto [first, last] = sb.GetVisibleRangeIterators(eng_list);
|
||||||
assert(max <= eng_list.size());
|
|
||||||
|
|
||||||
bool rtl = _current_text_dir == TD_RTL;
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
int step_size = GetEngineListHeight(type);
|
int step_size = GetEngineListHeight(type);
|
||||||
@@ -1019,7 +1018,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
|||||||
int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
|
int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
|
||||||
int sprite_width = sprite_left + sprite_right;
|
int sprite_width = sprite_left + sprite_right;
|
||||||
int circle_width = std::max(GetScaledSpriteSize(SPR_CIRCLE_FOLDED).width, GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED).width);
|
int circle_width = std::max(GetScaledSpriteSize(SPR_CIRCLE_FOLDED).width, GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED).width);
|
||||||
int linecolour = _colour_gradient[COLOUR_ORANGE][4];
|
int linecolour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL);
|
||||||
|
|
||||||
Rect ir = r.WithHeight(step_size).Shrink(WidgetDimensions::scaled.matrix);
|
Rect ir = r.WithHeight(step_size).Shrink(WidgetDimensions::scaled.matrix);
|
||||||
int sprite_y_offset = ScaleSpriteTrad(sprite_y_offsets[type]) + ir.Height() / 2;
|
int sprite_y_offset = ScaleSpriteTrad(sprite_y_offsets[type]) + ir.Height() / 2;
|
||||||
@@ -1030,9 +1029,8 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
|||||||
replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE);
|
replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE);
|
||||||
|
|
||||||
uint biggest_num_engines = 0;
|
uint biggest_num_engines = 0;
|
||||||
for (auto i = min; i < max; i++) {
|
for (auto it = first; it != last; ++it) {
|
||||||
const auto &item = eng_list[i];
|
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, it->engine_id);
|
||||||
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, item.engine_id);
|
|
||||||
biggest_num_engines = std::max(biggest_num_engines, num_engines);
|
biggest_num_engines = std::max(biggest_num_engines, num_engines);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,8 +1048,8 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
|||||||
int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2;
|
int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2;
|
||||||
|
|
||||||
int y = ir.top;
|
int y = ir.top;
|
||||||
for (; min < max; min++, y += step_size) {
|
for (auto it = first; it != last; ++it) {
|
||||||
const auto &item = eng_list[min];
|
const auto &item = *it;
|
||||||
uint indent = item.indent * WidgetDimensions::scaled.hsep_indent;
|
uint indent = item.indent * WidgetDimensions::scaled.hsep_indent;
|
||||||
bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None;
|
bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None;
|
||||||
bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None;
|
bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None;
|
||||||
@@ -1087,10 +1085,11 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
|
|||||||
/* Draw tree lines */
|
/* Draw tree lines */
|
||||||
Rect fr = ir.Indent(indent - WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(circle_width, rtl);
|
Rect fr = ir.Indent(indent - WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(circle_width, rtl);
|
||||||
int ycenter = y + normal_text_y_offset + GetCharacterHeight(FS_NORMAL) / 2;
|
int ycenter = y + normal_text_y_offset + GetCharacterHeight(FS_NORMAL) / 2;
|
||||||
bool continues = (min + 1U) < eng_list.size() && eng_list[min + 1].indent == item.indent;
|
bool continues = std::next(it) != std::end(eng_list) && std::next(it)->indent == item.indent;
|
||||||
GfxDrawLine(fr.left + circle_width / 2, y - WidgetDimensions::scaled.matrix.top, fr.left + circle_width / 2, continues ? y - WidgetDimensions::scaled.matrix.top + step_size - 1 : ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
GfxDrawLine(fr.left + circle_width / 2, y - WidgetDimensions::scaled.matrix.top, fr.left + circle_width / 2, continues ? y - WidgetDimensions::scaled.matrix.top + step_size - 1 : ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
||||||
GfxDrawLine(fr.left + circle_width / 2, ycenter, fr.right, ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
GfxDrawLine(fr.left + circle_width / 2, ycenter, fr.right, ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
|
||||||
}
|
}
|
||||||
|
y += step_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1130,7 +1129,7 @@ struct BuildVehicleWindow : Window {
|
|||||||
RoadType roadtype; ///< Road type to show, or #INVALID_ROADTYPE.
|
RoadType roadtype; ///< Road type to show, or #INVALID_ROADTYPE.
|
||||||
} filter; ///< Filter to apply.
|
} filter; ///< Filter to apply.
|
||||||
bool descending_sort_order; ///< Sort direction, @see _engine_sort_direction
|
bool descending_sort_order; ///< Sort direction, @see _engine_sort_direction
|
||||||
byte sort_criteria; ///< Current sort criterium.
|
uint8_t sort_criteria; ///< Current sort criterium.
|
||||||
bool show_hidden_engines; ///< State of the 'show hidden engines' button.
|
bool show_hidden_engines; ///< State of the 'show hidden engines' button.
|
||||||
bool listview_mode; ///< If set, only display the available vehicles and do not show a 'build' button.
|
bool listview_mode; ///< If set, only display the available vehicles and do not show a 'build' button.
|
||||||
EngineID sel_engine; ///< Currently selected engine, or #INVALID_ENGINE
|
EngineID sel_engine; ///< Currently selected engine, or #INVALID_ENGINE
|
||||||
@@ -1569,20 +1568,20 @@ struct BuildVehicleWindow : Window {
|
|||||||
DropDownList list;
|
DropDownList list;
|
||||||
|
|
||||||
/* Add item for disabling filtering. */
|
/* Add item for disabling filtering. */
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY, false));
|
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ANY), CargoFilterCriteria::CF_ANY));
|
||||||
/* Specific filters for trains. */
|
/* Specific filters for trains. */
|
||||||
if (this->vehicle_type == VEH_TRAIN) {
|
if (this->vehicle_type == VEH_TRAIN) {
|
||||||
/* Add item for locomotives only in case of trains. */
|
/* Add item for locomotives only in case of trains. */
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES, false));
|
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_ENGINES), CargoFilterCriteria::CF_ENGINES));
|
||||||
/* Add item for vehicles not carrying anything, e.g. train engines.
|
/* Add item for vehicles not carrying anything, e.g. train engines.
|
||||||
* This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */
|
* This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */
|
||||||
list.push_back(std::make_unique<DropDownListStringItem>(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE, false));
|
list.push_back(MakeDropDownListStringItem(this->GetCargoFilterLabel(CargoFilterCriteria::CF_NONE), CargoFilterCriteria::CF_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add cargos */
|
/* Add cargos */
|
||||||
Dimension d = GetLargestCargoIconSize();
|
Dimension d = GetLargestCargoIconSize();
|
||||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||||
list.push_back(std::make_unique<DropDownListIconItem>(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false));
|
list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@@ -1794,8 +1793,7 @@ struct BuildVehicleWindow : Window {
|
|||||||
this->vehicle_type,
|
this->vehicle_type,
|
||||||
r,
|
r,
|
||||||
this->eng_list,
|
this->eng_list,
|
||||||
this->vscroll->GetPosition(),
|
*this->vscroll,
|
||||||
static_cast<uint16_t>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())),
|
|
||||||
this->sel_engine,
|
this->sel_engine,
|
||||||
false,
|
false,
|
||||||
DEFAULT_GROUP
|
DEFAULT_GROUP
|
||||||
@@ -1824,7 +1822,7 @@ struct BuildVehicleWindow : Window {
|
|||||||
int needed_height = this->details_height;
|
int needed_height = this->details_height;
|
||||||
/* Draw details panels. */
|
/* Draw details panels. */
|
||||||
if (this->sel_engine != INVALID_ENGINE) {
|
if (this->sel_engine != INVALID_ENGINE) {
|
||||||
const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
|
const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
|
||||||
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te);
|
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te);
|
||||||
needed_height = std::max(needed_height, (text_end - r.top) / GetCharacterHeight(FS_NORMAL));
|
needed_height = std::max(needed_height, (text_end - r.top) / GetCharacterHeight(FS_NORMAL));
|
||||||
}
|
}
|
||||||
@@ -1902,7 +1900,7 @@ struct BuildVehicleWindow : Window {
|
|||||||
}};
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _build_vehicle_desc(__FILE__, __LINE__,
|
static WindowDesc _build_vehicle_desc(
|
||||||
WDP_AUTO, "build_vehicle", 240, 268,
|
WDP_AUTO, "build_vehicle", 240, 268,
|
||||||
WC_BUILD_VEHICLE, WC_NONE,
|
WC_BUILD_VEHICLE, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ using CargoLabel = StrongType::Typedef<uint32_t, struct CargoLabelTag, StrongTyp
|
|||||||
/**
|
/**
|
||||||
* Cargo slots to indicate a cargo type within a game.
|
* Cargo slots to indicate a cargo type within a game.
|
||||||
*/
|
*/
|
||||||
using CargoID = byte;
|
using CargoID = uint8_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available types of cargo
|
* Available types of cargo
|
||||||
@@ -47,7 +47,7 @@ static constexpr CargoLabel CT_FOOD = CargoLabel{'FOOD'};
|
|||||||
|
|
||||||
/* Tropic */
|
/* Tropic */
|
||||||
static constexpr CargoLabel CT_RUBBER = CargoLabel{'RUBR'};
|
static constexpr CargoLabel CT_RUBBER = CargoLabel{'RUBR'};
|
||||||
static constexpr CargoLabel CT_FRUIT = CargoLabel{'FRUI'};
|
static constexpr CargoLabel CT_FRUIT = CargoLabel{'FRUT'};
|
||||||
static constexpr CargoLabel CT_MAIZE = CargoLabel{'MAIZ'};
|
static constexpr CargoLabel CT_MAIZE = CargoLabel{'MAIZ'};
|
||||||
static constexpr CargoLabel CT_COPPER_ORE = CargoLabel{'CORE'};
|
static constexpr CargoLabel CT_COPPER_ORE = CargoLabel{'CORE'};
|
||||||
static constexpr CargoLabel CT_WATER = CargoLabel{'WATR'};
|
static constexpr CargoLabel CT_WATER = CargoLabel{'WATR'};
|
||||||
@@ -134,7 +134,7 @@ struct CargoArray : std::array<uint, NUM_CARGO> {
|
|||||||
|
|
||||||
|
|
||||||
/** Types of cargo source and destination */
|
/** Types of cargo source and destination */
|
||||||
enum class SourceType : byte {
|
enum class SourceType : uint8_t {
|
||||||
Industry, ///< Source/destination is an industry
|
Industry, ///< Source/destination is an industry
|
||||||
Town, ///< Source/destination is a town
|
Town, ///< Source/destination is a town
|
||||||
Headquarters, ///< Source/destination are company headquarters
|
Headquarters, ///< Source/destination are company headquarters
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void BuildCargoLabelMap()
|
|||||||
CargoSpec::label_map.clear();
|
CargoSpec::label_map.clear();
|
||||||
for (const CargoSpec &cs : CargoSpec::array) {
|
for (const CargoSpec &cs : CargoSpec::array) {
|
||||||
/* During initialization, CargoSpec can be marked valid before the label has been set. */
|
/* During initialization, CargoSpec can be marked valid before the label has been set. */
|
||||||
if (!cs.IsValid() || cs.label == CargoLabel{0}) continue;
|
if (!cs.IsValid() || cs.label == CargoLabel{0} || cs.label == CT_INVALID) continue;
|
||||||
/* Label already exists, don't addd again. */
|
/* Label already exists, don't addd again. */
|
||||||
if (CargoSpec::label_map.count(cs.label) != 0) continue;
|
if (CargoSpec::label_map.count(cs.label) != 0) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
|
|
||||||
/** Town growth effect when delivering cargo. */
|
/** Town growth effect when delivering cargo. */
|
||||||
enum TownAcceptanceEffect : byte {
|
enum TownAcceptanceEffect : uint8_t {
|
||||||
TAE_BEGIN = 0,
|
TAE_BEGIN = 0,
|
||||||
TAE_NONE = TAE_BEGIN, ///< Cargo has no effect.
|
TAE_NONE = TAE_BEGIN, ///< Cargo has no effect.
|
||||||
TAE_PASSENGERS, ///< Cargo behaves passenger-like.
|
TAE_PASSENGERS, ///< Cargo behaves passenger-like.
|
||||||
@@ -31,7 +31,7 @@ enum TownAcceptanceEffect : byte {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Town effect when producing cargo. */
|
/** Town effect when producing cargo. */
|
||||||
enum TownProductionEffect : byte {
|
enum TownProductionEffect : uint8_t {
|
||||||
TPE_NONE, ///< Town will not produce this cargo type.
|
TPE_NONE, ///< Town will not produce this cargo type.
|
||||||
TPE_PASSENGERS, ///< Cargo behaves passenger-like for production.
|
TPE_PASSENGERS, ///< Cargo behaves passenger-like for production.
|
||||||
TPE_MAIL, ///< Cargo behaves mail-like for production.
|
TPE_MAIL, ///< Cargo behaves mail-like for production.
|
||||||
@@ -60,7 +60,7 @@ enum CargoClass {
|
|||||||
CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
|
CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
|
||||||
};
|
};
|
||||||
|
|
||||||
static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
|
static const uint8_t INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
|
||||||
|
|
||||||
static const uint TOWN_PRODUCTION_DIVISOR = 256;
|
static const uint TOWN_PRODUCTION_DIVISOR = 256;
|
||||||
|
|
||||||
|
|||||||
@@ -107,18 +107,21 @@ static int32_t ClickChangeDateCheat(int32_t new_value, int32_t)
|
|||||||
|
|
||||||
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
|
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
|
||||||
TimerGameCalendar::Date new_calendar_date = TimerGameCalendar::ConvertYMDToDate(new_year, ymd.month, ymd.day);
|
TimerGameCalendar::Date new_calendar_date = TimerGameCalendar::ConvertYMDToDate(new_year, ymd.month, ymd.day);
|
||||||
/* Keep economy and calendar dates synced. */
|
|
||||||
TimerGameEconomy::Date new_economy_date = new_calendar_date.base();
|
|
||||||
|
|
||||||
/* Shift cached dates before we change the date. */
|
|
||||||
for (auto v : Vehicle::Iterate()) v->ShiftDates(new_economy_date - TimerGameEconomy::date);
|
|
||||||
LinkGraphSchedule::instance.ShiftDates(new_economy_date - TimerGameEconomy::date);
|
|
||||||
|
|
||||||
/* Now it's safe to actually change the date. */
|
|
||||||
TimerGameCalendar::SetDate(new_calendar_date, TimerGameCalendar::date_fract);
|
TimerGameCalendar::SetDate(new_calendar_date, TimerGameCalendar::date_fract);
|
||||||
|
|
||||||
/* If not using wallclock units, we keep economy date in sync with calendar date and must change it also. */
|
/* If not using wallclock units, we keep economy date in sync with calendar date and must change it also. */
|
||||||
if (!TimerGameEconomy::UsingWallclockUnits()) TimerGameEconomy::SetDate(new_economy_date, TimerGameEconomy::date_fract);
|
if (!TimerGameEconomy::UsingWallclockUnits()) {
|
||||||
|
/* Keep economy and calendar dates synced. */
|
||||||
|
TimerGameEconomy::Date new_economy_date = new_calendar_date.base();
|
||||||
|
|
||||||
|
/* Shift cached dates before we change the date. */
|
||||||
|
for (auto v : Vehicle::Iterate()) v->ShiftDates(new_economy_date - TimerGameEconomy::date);
|
||||||
|
LinkGraphSchedule::instance.ShiftDates(new_economy_date - TimerGameEconomy::date);
|
||||||
|
|
||||||
|
/* Now it's safe to actually change the date. */
|
||||||
|
TimerGameEconomy::SetDate(new_economy_date, TimerGameEconomy::date_fract);
|
||||||
|
}
|
||||||
|
|
||||||
CalendarEnginesMonthlyLoop();
|
CalendarEnginesMonthlyLoop();
|
||||||
SetWindowDirty(WC_STATUS_BAR, 0);
|
SetWindowDirty(WC_STATUS_BAR, 0);
|
||||||
@@ -423,7 +426,7 @@ struct CheatWindow : Window {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Window description of the cheats GUI. */
|
/** Window description of the cheats GUI. */
|
||||||
static WindowDesc _cheats_desc(__FILE__, __LINE__,
|
static WindowDesc _cheats_desc(
|
||||||
WDP_AUTO, "cheats", 0, 0,
|
WDP_AUTO, "cheats", 0, 0,
|
||||||
WC_CHEATS, WC_NONE,
|
WC_CHEATS, WC_NONE,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static CommandCost ClearTile_Clear(TileIndex tile, DoCommandFlag flags)
|
|||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawClearLandTile(const TileInfo *ti, byte set)
|
void DrawClearLandTile(const TileInfo *ti, uint8_t set)
|
||||||
{
|
{
|
||||||
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh) + set * 19, PAL_NONE);
|
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh) + set * 19, PAL_NONE);
|
||||||
}
|
}
|
||||||
@@ -129,8 +129,7 @@ static void DrawTile_Clear(TileInfo *ti)
|
|||||||
|
|
||||||
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool)
|
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool)
|
||||||
{
|
{
|
||||||
int z;
|
auto [tileh, z] = GetTilePixelSlope(tile);
|
||||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
|
||||||
|
|
||||||
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
|
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
|
||||||
}
|
}
|
||||||
@@ -145,25 +144,25 @@ static void UpdateFences(TileIndex tile)
|
|||||||
assert(IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
|
assert(IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
|
||||||
bool neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
|
bool neighbour = (IsTileType(TileAddXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, 1, 0), CLEAR_FIELDS));
|
||||||
if (!neighbour && GetFence(tile, DIAGDIR_SW) == 0) {
|
if (!neighbour && GetFence(tile, DIAGDIR_SW) == 0) {
|
||||||
SetFence(tile, DIAGDIR_SW, 3);
|
SetFence(tile, DIAGDIR_SW, 3);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
|
neighbour = (IsTileType(TileAddXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, 1), CLEAR_FIELDS));
|
||||||
if (!neighbour && GetFence(tile, DIAGDIR_SE) == 0) {
|
if (!neighbour && GetFence(tile, DIAGDIR_SE) == 0) {
|
||||||
SetFence(tile, DIAGDIR_SE, 3);
|
SetFence(tile, DIAGDIR_SE, 3);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbour = (IsTileType(TILE_ADDXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, -1, 0), CLEAR_FIELDS));
|
neighbour = (IsTileType(TileAddXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TileAddXY(tile, -1, 0), CLEAR_FIELDS));
|
||||||
if (!neighbour && GetFence(tile, DIAGDIR_NE) == 0) {
|
if (!neighbour && GetFence(tile, DIAGDIR_NE) == 0) {
|
||||||
SetFence(tile, DIAGDIR_NE, 3);
|
SetFence(tile, DIAGDIR_NE, 3);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
neighbour = (IsTileType(TILE_ADDXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, -1), CLEAR_FIELDS));
|
neighbour = (IsTileType(TileAddXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TileAddXY(tile, 0, -1), CLEAR_FIELDS));
|
||||||
if (!neighbour && GetFence(tile, DIAGDIR_NW) == 0) {
|
if (!neighbour && GetFence(tile, DIAGDIR_NW) == 0) {
|
||||||
SetFence(tile, DIAGDIR_NW, 3);
|
SetFence(tile, DIAGDIR_NW, 3);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|||||||
@@ -13,6 +13,6 @@
|
|||||||
#include "tile_cmd.h"
|
#include "tile_cmd.h"
|
||||||
|
|
||||||
void DrawHillyLandTile(const TileInfo *ti);
|
void DrawHillyLandTile(const TileInfo *ti);
|
||||||
void DrawClearLandTile(const TileInfo *ti, byte set);
|
void DrawClearLandTile(const TileInfo *ti, uint8_t set);
|
||||||
|
|
||||||
#endif /* CLEAR_FUNC_H */
|
#endif /* CLEAR_FUNC_H */
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ protected:
|
|||||||
assert(AllClientIdsSet(args, std::index_sequence_for<Targs...>{}));
|
assert(AllClientIdsSet(args, std::index_sequence_for<Targs...>{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company);
|
||||||
if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) {
|
if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) {
|
||||||
cur_company.Trash();
|
cur_company.Trash();
|
||||||
return MakeResult(CMD_ERROR);
|
return MakeResult(CMD_ERROR);
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ template <Commands Tcmd> struct CommandTraits;
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Storage buffer for serialized command data. */
|
/** Storage buffer for serialized command data. */
|
||||||
typedef std::vector<byte> CommandDataBuffer;
|
typedef std::vector<uint8_t> CommandDataBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a callback function for the client, after the command is finished.
|
* Define a callback function for the client, after the command is finished.
|
||||||
|
|||||||
@@ -49,6 +49,19 @@ struct CompanyInfrastructure {
|
|||||||
uint32_t GetTramTotal() const;
|
uint32_t GetTramTotal() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FreeUnitIDGenerator {
|
||||||
|
public:
|
||||||
|
UnitID NextID() const;
|
||||||
|
UnitID UseID(UnitID index);
|
||||||
|
void ReleaseID(UnitID index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using BitmapStorage = size_t;
|
||||||
|
static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
|
||||||
|
|
||||||
|
std::vector<BitmapStorage> used_bitmap;
|
||||||
|
};
|
||||||
|
|
||||||
typedef Pool<Company, CompanyID, 1, MAX_COMPANIES> CompanyPool;
|
typedef Pool<Company, CompanyID, 1, MAX_COMPANIES> CompanyPool;
|
||||||
extern CompanyPool _company_pool;
|
extern CompanyPool _company_pool;
|
||||||
|
|
||||||
@@ -65,20 +78,21 @@ struct CompanyProperties {
|
|||||||
CompanyManagerFace face; ///< Face description of the president.
|
CompanyManagerFace face; ///< Face description of the president.
|
||||||
|
|
||||||
Money money; ///< Money owned by the company.
|
Money money; ///< Money owned by the company.
|
||||||
byte money_fraction; ///< Fraction of money of the company, too small to represent in #money.
|
uint8_t money_fraction; ///< Fraction of money of the company, too small to represent in #money.
|
||||||
Money current_loan; ///< Amount of money borrowed from the bank.
|
Money current_loan; ///< Amount of money borrowed from the bank.
|
||||||
Money max_loan; ///< Max allowed amount of the loan or COMPANY_MAX_LOAN_DEFAULT.
|
Money max_loan; ///< Max allowed amount of the loan or COMPANY_MAX_LOAN_DEFAULT.
|
||||||
|
|
||||||
Colours colour; ///< Company colour.
|
Colours colour; ///< Company colour.
|
||||||
|
|
||||||
byte block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics).
|
uint8_t block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics).
|
||||||
|
|
||||||
TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none.
|
TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none.
|
||||||
TileIndex last_build_coordinate; ///< Coordinate of the last build thing by this company.
|
TileIndex last_build_coordinate; ///< Coordinate of the last build thing by this company.
|
||||||
|
|
||||||
TimerGameEconomy::Year inaugurated_year; ///< Economy year of starting the company.
|
TimerGameEconomy::Year inaugurated_year; ///< Economy year of starting the company.
|
||||||
|
|
||||||
byte months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
|
uint8_t months_empty = 0; ///< NOSAVE: Number of months this company has not had a client in multiplayer.
|
||||||
|
uint8_t months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
|
||||||
CompanyMask bankrupt_asked; ///< which companies were asked about buying it?
|
CompanyMask bankrupt_asked; ///< which companies were asked about buying it?
|
||||||
int16_t bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company.
|
int16_t bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company.
|
||||||
Money bankrupt_value;
|
Money bankrupt_value;
|
||||||
@@ -97,7 +111,7 @@ struct CompanyProperties {
|
|||||||
std::array<Expenses, 3> yearly_expenses{}; ///< Expenses of the company for the last three years.
|
std::array<Expenses, 3> yearly_expenses{}; ///< Expenses of the company for the last three years.
|
||||||
CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter.
|
CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter.
|
||||||
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
|
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
|
||||||
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
uint8_t num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
||||||
|
|
||||||
Livery livery[LS_END];
|
Livery livery[LS_END];
|
||||||
|
|
||||||
@@ -129,6 +143,8 @@ struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> {
|
|||||||
|
|
||||||
CompanyInfrastructure infrastructure; ///< NOSAVE: Counts of company owned infrastructure.
|
CompanyInfrastructure infrastructure; ///< NOSAVE: Counts of company owned infrastructure.
|
||||||
|
|
||||||
|
FreeUnitIDGenerator freeunits[VEH_COMPANY_END];
|
||||||
|
|
||||||
Money GetMaxLoan() const;
|
Money GetMaxLoan() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,12 +34,13 @@
|
|||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "goal_base.h"
|
#include "goal_base.h"
|
||||||
#include "story_base.h"
|
#include "story_base.h"
|
||||||
#include "widgets/statusbar_widget.h"
|
|
||||||
#include "company_cmd.h"
|
#include "company_cmd.h"
|
||||||
#include "timer/timer.h"
|
#include "timer/timer.h"
|
||||||
#include "timer/timer_game_economy.h"
|
#include "timer/timer_game_economy.h"
|
||||||
#include "timer/timer_game_tick.h"
|
#include "timer/timer_game_tick.h"
|
||||||
|
|
||||||
|
#include "widgets/statusbar_widget.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
@@ -146,8 +147,8 @@ void SetLocalCompany(CompanyID new_company)
|
|||||||
*/
|
*/
|
||||||
TextColour GetDrawStringCompanyColour(CompanyID company)
|
TextColour GetDrawStringCompanyColour(CompanyID company)
|
||||||
{
|
{
|
||||||
if (!Company::IsValidID(company)) return (TextColour)_colour_gradient[COLOUR_WHITE][4] | TC_IS_PALETTE_COLOUR;
|
if (!Company::IsValidID(company)) return (TextColour)GetColourGradient(COLOUR_WHITE, SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
|
||||||
return (TextColour)_colour_gradient[_company_colours[company]][4] | TC_IS_PALETTE_COLOUR;
|
return (TextColour)GetColourGradient(_company_colours[company], SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,10 +299,10 @@ void SubtractMoneyFromCompany(const CommandCost &cost)
|
|||||||
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
|
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
|
||||||
{
|
{
|
||||||
Company *c = Company::Get(company);
|
Company *c = Company::Get(company);
|
||||||
byte m = c->money_fraction;
|
uint8_t m = c->money_fraction;
|
||||||
Money cost = cst.GetCost();
|
Money cost = cst.GetCost();
|
||||||
|
|
||||||
c->money_fraction = m - (byte)cost;
|
c->money_fraction = m - (uint8_t)cost;
|
||||||
cost >>= 8;
|
cost >>= 8;
|
||||||
if (c->money_fraction > m) cost++;
|
if (c->money_fraction > m) cost++;
|
||||||
if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
|
if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
|
||||||
@@ -447,7 +448,7 @@ bad_town_name:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Sorting weights for the company colours. */
|
/** Sorting weights for the company colours. */
|
||||||
static const byte _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
|
static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
|
||||||
/** Similar colours, so we can try to prevent same coloured companies. */
|
/** Similar colours, so we can try to prevent same coloured companies. */
|
||||||
static const Colours _similar_colour[COLOUR_END][2] = {
|
static const Colours _similar_colour[COLOUR_END][2] = {
|
||||||
{ COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
|
{ COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
|
||||||
@@ -477,7 +478,7 @@ static Colours GenerateCompanyColour()
|
|||||||
Colours colours[COLOUR_END];
|
Colours colours[COLOUR_END];
|
||||||
|
|
||||||
/* Initialize array */
|
/* Initialize array */
|
||||||
for (uint i = 0; i < COLOUR_END; i++) colours[i] = (Colours)i;
|
for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast<Colours>(i);
|
||||||
|
|
||||||
/* And randomize it */
|
/* And randomize it */
|
||||||
for (uint i = 0; i < 100; i++) {
|
for (uint i = 0; i < 100; i++) {
|
||||||
@@ -1255,7 +1256,7 @@ CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_compan
|
|||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
/* Add money to company */
|
/* Add money to company */
|
||||||
Backup<CompanyID> cur_company(_current_company, dest_company, FILE_LINE);
|
Backup<CompanyID> cur_company(_current_company, dest_company);
|
||||||
SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
|
SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "livery.h"
|
#include "livery.h"
|
||||||
|
|
||||||
enum ClientID : uint32_t;
|
enum ClientID : uint32_t;
|
||||||
enum Colours : byte;
|
enum Colours : uint8_t;
|
||||||
|
|
||||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id);
|
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id);
|
||||||
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company);
|
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company);
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
#include "company_manager_face.h"
|
#include "company_manager_face.h"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "timer/timer_game_economy.h"
|
#include "timer/timer_game_economy.h"
|
||||||
#include "widgets/dropdown_type.h"
|
#include "dropdown_type.h"
|
||||||
|
#include "dropdown_common_type.h"
|
||||||
#include "tilehighlight_func.h"
|
#include "tilehighlight_func.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
#include "company_cmd.h"
|
#include "company_cmd.h"
|
||||||
#include "economy_cmd.h"
|
#include "economy_cmd.h"
|
||||||
#include "group_cmd.h"
|
#include "group_cmd.h"
|
||||||
|
#include "group_gui.h"
|
||||||
#include "misc_cmd.h"
|
#include "misc_cmd.h"
|
||||||
#include "object_cmd.h"
|
#include "object_cmd.h"
|
||||||
#include "timer/timer.h"
|
#include "timer/timer.h"
|
||||||
@@ -530,7 +532,7 @@ struct CompanyFinancesWindow : Window {
|
|||||||
/** First conservative estimate of the maximum amount of money */
|
/** First conservative estimate of the maximum amount of money */
|
||||||
Money CompanyFinancesWindow::max_money = INT32_MAX;
|
Money CompanyFinancesWindow::max_money = INT32_MAX;
|
||||||
|
|
||||||
static WindowDesc _company_finances_desc(__FILE__, __LINE__,
|
static WindowDesc _company_finances_desc(
|
||||||
WDP_AUTO, "company_finances", 0, 0,
|
WDP_AUTO, "company_finances", 0, 0,
|
||||||
WC_FINANCES, WC_NONE,
|
WC_FINANCES, WC_NONE,
|
||||||
0,
|
0,
|
||||||
@@ -592,8 +594,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GUIList<const Group*> GUIGroupList;
|
|
||||||
|
|
||||||
/** Company livery colour scheme window. */
|
/** Company livery colour scheme window. */
|
||||||
struct SelectCompanyLiveryWindow : public Window {
|
struct SelectCompanyLiveryWindow : public Window {
|
||||||
private:
|
private:
|
||||||
@@ -603,7 +603,6 @@ private:
|
|||||||
uint rows;
|
uint rows;
|
||||||
uint line_height;
|
uint line_height;
|
||||||
GUIGroupList groups;
|
GUIGroupList groups;
|
||||||
std::vector<int> indents;
|
|
||||||
Scrollbar *vscroll;
|
Scrollbar *vscroll;
|
||||||
|
|
||||||
void ShowColourDropDownMenu(uint32_t widget)
|
void ShowColourDropDownMenu(uint32_t widget)
|
||||||
@@ -611,7 +610,7 @@ private:
|
|||||||
uint32_t used_colours = 0;
|
uint32_t used_colours = 0;
|
||||||
const Livery *livery, *default_livery = nullptr;
|
const Livery *livery, *default_livery = nullptr;
|
||||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||||
byte default_col = 0;
|
uint8_t default_col = 0;
|
||||||
|
|
||||||
/* Disallow other company colours for the primary colour */
|
/* Disallow other company colours for the primary colour */
|
||||||
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
||||||
@@ -652,7 +651,7 @@ private:
|
|||||||
list.push_back(std::make_unique<DropDownListColourItem<>>(i, HasBit(used_colours, i)));
|
list.push_back(std::make_unique<DropDownListColourItem<>>(i, HasBit(used_colours, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte sel;
|
uint8_t sel;
|
||||||
if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) {
|
if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||||
sel = primary ? livery->colour1 : livery->colour2;
|
sel = primary ? livery->colour1 : livery->colour2;
|
||||||
} else {
|
} else {
|
||||||
@@ -661,57 +660,15 @@ private:
|
|||||||
ShowDropDownList(this, std::move(list), sel, widget);
|
ShowDropDownList(this, std::move(list), sel, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddChildren(GUIGroupList &source, GroupID parent, int indent)
|
|
||||||
{
|
|
||||||
for (const Group *g : source) {
|
|
||||||
if (g->parent != parent) continue;
|
|
||||||
this->groups.push_back(g);
|
|
||||||
this->indents.push_back(indent);
|
|
||||||
AddChildren(source, g->index, indent + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildGroupList(CompanyID owner)
|
void BuildGroupList(CompanyID owner)
|
||||||
{
|
{
|
||||||
if (!this->groups.NeedRebuild()) return;
|
if (!this->groups.NeedRebuild()) return;
|
||||||
|
|
||||||
this->groups.clear();
|
this->groups.clear();
|
||||||
this->indents.clear();
|
|
||||||
|
|
||||||
if (this->livery_class >= LC_GROUP_RAIL) {
|
if (this->livery_class >= LC_GROUP_RAIL) {
|
||||||
GUIGroupList list;
|
|
||||||
VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL);
|
VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL);
|
||||||
|
BuildGuiGroupList(this->groups, false, owner, vtype);
|
||||||
for (const Group *g : Group::Iterate()) {
|
|
||||||
if (g->owner == owner && g->vehicle_type == vtype) {
|
|
||||||
list.push_back(g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list.ForceResort();
|
|
||||||
|
|
||||||
/* Sort the groups by their name */
|
|
||||||
const Group *last_group[2] = { nullptr, nullptr };
|
|
||||||
std::string last_name[2] = { {}, {} };
|
|
||||||
list.Sort([&](const Group * const &a, const Group * const &b) -> bool {
|
|
||||||
if (a != last_group[0]) {
|
|
||||||
last_group[0] = a;
|
|
||||||
SetDParam(0, a->index);
|
|
||||||
last_name[0] = GetString(STR_GROUP_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b != last_group[1]) {
|
|
||||||
last_group[1] = b;
|
|
||||||
SetDParam(0, b->index);
|
|
||||||
last_name[1] = GetString(STR_GROUP_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
|
|
||||||
if (r == 0) return a->index < b->index;
|
|
||||||
return r < 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddChildren(list, INVALID_GROUP, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->groups.shrink_to_fit();
|
this->groups.shrink_to_fit();
|
||||||
@@ -775,7 +732,7 @@ public:
|
|||||||
|
|
||||||
/* Position scrollbar to selected group */
|
/* Position scrollbar to selected group */
|
||||||
for (uint i = 0; i < this->rows; i++) {
|
for (uint i = 0; i < this->rows; i++) {
|
||||||
if (this->groups[i]->index == sel) {
|
if (this->groups[i].group->index == sel) {
|
||||||
this->vscroll->SetPosition(i - this->vscroll->GetCapacity() / 2);
|
this->vscroll->SetPosition(i - this->vscroll->GetCapacity() / 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -945,11 +902,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.size()));
|
auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->groups);
|
||||||
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
|
for (auto it = first; it != last; ++it) {
|
||||||
const Group *g = this->groups[i];
|
const Group *g = it->group;
|
||||||
SetDParam(0, g->index);
|
SetDParam(0, g->index);
|
||||||
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * WidgetDimensions::scaled.hsep_indent);
|
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, it->indent * WidgetDimensions::scaled.hsep_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->vscroll->GetCount() == 0) {
|
if (this->vscroll->GetCount() == 0) {
|
||||||
@@ -992,7 +949,7 @@ public:
|
|||||||
this->BuildGroupList((CompanyID)this->window_number);
|
this->BuildGroupList((CompanyID)this->window_number);
|
||||||
|
|
||||||
if (!this->groups.empty()) {
|
if (!this->groups.empty()) {
|
||||||
this->sel = this->groups[0]->index;
|
this->sel = this->groups[0].group->index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1009,10 +966,10 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_SCL_MATRIX: {
|
case WID_SCL_MATRIX: {
|
||||||
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCL_MATRIX);
|
|
||||||
if (row >= this->rows) return;
|
|
||||||
|
|
||||||
if (this->livery_class < LC_GROUP_RAIL) {
|
if (this->livery_class < LC_GROUP_RAIL) {
|
||||||
|
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget);
|
||||||
|
if (row >= this->rows) return;
|
||||||
|
|
||||||
LiveryScheme j = (LiveryScheme)row;
|
LiveryScheme j = (LiveryScheme)row;
|
||||||
|
|
||||||
for (LiveryScheme scheme = LS_BEGIN; scheme <= j && scheme < LS_END; scheme++) {
|
for (LiveryScheme scheme = LS_BEGIN; scheme <= j && scheme < LS_END; scheme++) {
|
||||||
@@ -1026,7 +983,10 @@ public:
|
|||||||
this->sel = 1 << j;
|
this->sel = 1 << j;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->sel = this->groups[row]->index;
|
auto it = this->vscroll->GetScrolledItemFromWidget(this->groups, pt.y, this, widget);
|
||||||
|
if (it == std::end(this->groups)) return;
|
||||||
|
|
||||||
|
this->sel = it->group->index;
|
||||||
}
|
}
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
break;
|
break;
|
||||||
@@ -1079,7 +1039,7 @@ public:
|
|||||||
|
|
||||||
if (!Group::IsValidID(this->sel)) {
|
if (!Group::IsValidID(this->sel)) {
|
||||||
this->sel = INVALID_GROUP;
|
this->sel = INVALID_GROUP;
|
||||||
if (!this->groups.empty()) this->sel = this->groups[0]->index;
|
if (!this->groups.empty()) this->sel = this->groups[0].group->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
@@ -1140,7 +1100,7 @@ static constexpr NWidgetPart _nested_select_company_livery_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _select_company_livery_desc(__FILE__, __LINE__,
|
static WindowDesc _select_company_livery_desc(
|
||||||
WDP_AUTO, "company_color_scheme", 0, 0,
|
WDP_AUTO, "company_color_scheme", 0, 0,
|
||||||
WC_COMPANY_COLOUR, WC_NONE,
|
WC_COMPANY_COLOUR, WC_NONE,
|
||||||
0,
|
0,
|
||||||
@@ -1769,7 +1729,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Company manager face selection window description */
|
/** Company manager face selection window description */
|
||||||
static WindowDesc _select_company_manager_face_desc(__FILE__, __LINE__,
|
static WindowDesc _select_company_manager_face_desc(
|
||||||
WDP_AUTO, nullptr, 0, 0,
|
WDP_AUTO, nullptr, 0, 0,
|
||||||
WC_COMPANY_MANAGER_FACE, WC_NONE,
|
WC_COMPANY_MANAGER_FACE, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
@@ -2146,7 +2106,7 @@ struct CompanyInfrastructureWindow : Window
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _company_infrastructure_desc(__FILE__, __LINE__,
|
static WindowDesc _company_infrastructure_desc(
|
||||||
WDP_AUTO, "company_infrastructure", 0, 0,
|
WDP_AUTO, "company_infrastructure", 0, 0,
|
||||||
WC_COMPANY_INFRASTRUCTURE, WC_NONE,
|
WC_COMPANY_INFRASTRUCTURE, WC_NONE,
|
||||||
0,
|
0,
|
||||||
@@ -2529,7 +2489,7 @@ struct CompanyWindow : Window
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WID_C_BUILD_HQ:
|
case WID_C_BUILD_HQ:
|
||||||
if ((byte)this->window_number != _local_company) return;
|
if ((uint8_t)this->window_number != _local_company) return;
|
||||||
if (this->IsWidgetLowered(WID_C_BUILD_HQ)) {
|
if (this->IsWidgetLowered(WID_C_BUILD_HQ)) {
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
this->RaiseButtons();
|
this->RaiseButtons();
|
||||||
@@ -2614,7 +2574,7 @@ struct CompanyWindow : Window
|
|||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
|
|
||||||
case WID_C_GIVE_MONEY: {
|
case WID_C_GIVE_MONEY: {
|
||||||
Money money = std::strtoull(str, nullptr, 10) / _currency->rate;
|
Money money = std::strtoull(str, nullptr, 10) / GetCurrency().rate;
|
||||||
Command<CMD_GIVE_MONEY>::Post(STR_ERROR_CAN_T_GIVE_MONEY, money, (CompanyID)this->window_number);
|
Command<CMD_GIVE_MONEY>::Post(STR_ERROR_CAN_T_GIVE_MONEY, money, (CompanyID)this->window_number);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2634,7 +2594,7 @@ struct CompanyWindow : Window
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _company_desc(__FILE__, __LINE__,
|
static WindowDesc _company_desc(
|
||||||
WDP_AUTO, "company", 0, 0,
|
WDP_AUTO, "company", 0, 0,
|
||||||
WC_COMPANY, WC_NONE,
|
WC_COMPANY, WC_NONE,
|
||||||
0,
|
0,
|
||||||
@@ -2768,7 +2728,7 @@ static constexpr NWidgetPart _nested_buy_company_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _buy_company_desc(__FILE__, __LINE__,
|
static WindowDesc _buy_company_desc(
|
||||||
WDP_AUTO, nullptr, 0, 0,
|
WDP_AUTO, nullptr, 0, 0,
|
||||||
WC_BUY_COMPANY, WC_NONE,
|
WC_BUY_COMPANY, WC_NONE,
|
||||||
WDF_CONSTRUCTION,
|
WDF_CONSTRUCTION,
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ DECLARE_POSTFIX_INCREMENT(CompanyManagerFaceVariable)
|
|||||||
|
|
||||||
/** Information about the valid values of CompanyManagerFace bitgroups as well as the sprites to draw */
|
/** Information about the valid values of CompanyManagerFace bitgroups as well as the sprites to draw */
|
||||||
struct CompanyManagerFaceBitsInfo {
|
struct CompanyManagerFaceBitsInfo {
|
||||||
byte offset; ///< Offset in bits into the CompanyManagerFace
|
uint8_t offset; ///< Offset in bits into the CompanyManagerFace
|
||||||
byte length; ///< Number of bits used in the CompanyManagerFace
|
uint8_t length; ///< Number of bits used in the CompanyManagerFace
|
||||||
byte valid_values[GE_END]; ///< The number of valid values per gender/ethnicity
|
uint8_t valid_values[GE_END]; ///< The number of valid values per gender/ethnicity
|
||||||
SpriteID first_sprite[GE_END]; ///< The first sprite per gender/ethnicity
|
SpriteID first_sprite[GE_END]; ///< The first sprite per gender/ethnicity
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
/**
|
/**
|
||||||
* Enum for all companies/owners.
|
* Enum for all companies/owners.
|
||||||
*/
|
*/
|
||||||
enum Owner : byte {
|
enum Owner : uint8_t {
|
||||||
/* All companies below MAX_COMPANIES are playable
|
/* All companies below MAX_COMPANIES are playable
|
||||||
* companies, above, they are special, computer controlled 'companies' */
|
* companies, above, they are special, computer controlled 'companies' */
|
||||||
OWNER_BEGIN = 0x00, ///< First owner
|
OWNER_BEGIN = 0x00, ///< First owner
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ static std::string RemoveUnderscores(std::string name)
|
|||||||
* @param tokencount the number of parameters passed
|
* @param tokencount the number of parameters passed
|
||||||
* @param *tokens are the parameters given to the original command (0 is the first param)
|
* @param *tokens are the parameters given to the original command (0 is the first param)
|
||||||
*/
|
*/
|
||||||
static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
|
static void IConsoleAliasExec(const IConsoleAlias *alias, uint8_t tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count)
|
||||||
{
|
{
|
||||||
std::string alias_buffer;
|
std::string alias_buffer;
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ static ConsoleFileList _console_file_list_scenario{FT_SCENARIO, false}; ///< Fil
|
|||||||
static ConsoleFileList _console_file_list_heightmap{FT_HEIGHTMAP, false}; ///< File storage cache for heightmaps.
|
static ConsoleFileList _console_file_list_heightmap{FT_HEIGHTMAP, false}; ///< File storage cache for heightmaps.
|
||||||
|
|
||||||
/* console command defines */
|
/* console command defines */
|
||||||
#define DEF_CONSOLE_CMD(function) static bool function([[maybe_unused]] byte argc, [[maybe_unused]] char *argv[])
|
#define DEF_CONSOLE_CMD(function) static bool function([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *argv[])
|
||||||
#define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
|
#define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
|
||||||
|
|
||||||
|
|
||||||
@@ -155,6 +155,21 @@ DEF_CONSOLE_HOOK(ConHookNeedNetwork)
|
|||||||
return CHR_ALLOW;
|
return CHR_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether we are in a multiplayer game and are playing, i.e. we are not the dedicated server.
|
||||||
|
* @return Are we a client or non-dedicated server in a network game? True when yes, false otherwise.
|
||||||
|
*/
|
||||||
|
DEF_CONSOLE_HOOK(ConHookNeedNonDedicatedNetwork)
|
||||||
|
{
|
||||||
|
if (!NetworkAvailable(echo)) return CHR_DISALLOW;
|
||||||
|
|
||||||
|
if (_network_dedicated) {
|
||||||
|
if (echo) IConsolePrint(CC_ERROR, "This command is not available to a dedicated network server.");
|
||||||
|
return CHR_DISALLOW;
|
||||||
|
}
|
||||||
|
return CHR_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether we are in singleplayer mode.
|
* Check whether we are in singleplayer mode.
|
||||||
* @return True when no network is active.
|
* @return True when no network is active.
|
||||||
@@ -835,6 +850,7 @@ DEF_CONSOLE_CMD(ConRcon)
|
|||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
IConsolePrint(CC_HELP, "Remote control the server from another client. Usage: 'rcon <password> <command>'.");
|
IConsolePrint(CC_HELP, "Remote control the server from another client. Usage: 'rcon <password> <command>'.");
|
||||||
IConsolePrint(CC_HELP, "Remember to enclose the command in quotes, otherwise only the first parameter is sent.");
|
IConsolePrint(CC_HELP, "Remember to enclose the command in quotes, otherwise only the first parameter is sent.");
|
||||||
|
IConsolePrint(CC_HELP, "When your client's public key is in the 'authorized keys' for 'rcon', the password is not checked and may be '*'.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,13 +935,19 @@ DEF_CONSOLE_CMD(ConJoinCompany)
|
|||||||
|
|
||||||
CompanyID company_id = (CompanyID)(atoi(argv[1]) <= MAX_COMPANIES ? atoi(argv[1]) - 1 : atoi(argv[1]));
|
CompanyID company_id = (CompanyID)(atoi(argv[1]) <= MAX_COMPANIES ? atoi(argv[1]) - 1 : atoi(argv[1]));
|
||||||
|
|
||||||
|
const NetworkClientInfo *info = NetworkClientInfo::GetByClientID(_network_own_client_id);
|
||||||
|
if (info == nullptr) {
|
||||||
|
IConsolePrint(CC_ERROR, "You have not joined the game yet!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check we have a valid company id! */
|
/* Check we have a valid company id! */
|
||||||
if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
|
if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
|
||||||
IConsolePrint(CC_ERROR, "Company does not exist. Company-id must be between 1 and {}.", MAX_COMPANIES);
|
IConsolePrint(CC_ERROR, "Company does not exist. Company-id must be between 1 and {}.", MAX_COMPANIES);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetworkClientInfo::GetByClientID(_network_own_client_id)->client_playas == company_id) {
|
if (info->client_playas == company_id) {
|
||||||
IConsolePrint(CC_ERROR, "You are already there!");
|
IConsolePrint(CC_ERROR, "You are already there!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1954,6 +1976,86 @@ DEF_CONSOLE_CMD(ConCompanyPassword)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** All the known authorized keys with their name. */
|
||||||
|
static std::vector<std::pair<std::string_view, NetworkAuthorizedKeys *>> _console_cmd_authorized_keys{
|
||||||
|
{ "rcon", &_settings_client.network.rcon_authorized_keys },
|
||||||
|
{ "server", &_settings_client.network.server_authorized_keys },
|
||||||
|
};
|
||||||
|
|
||||||
|
DEF_CONSOLE_CMD(ConNetworkAuthorizedKey)
|
||||||
|
{
|
||||||
|
if (argc <= 2) {
|
||||||
|
IConsolePrint(CC_HELP, "List and update authorized keys. Usage: 'authorized_key list [type]|add [type] [key]|remove [type] [key]'.");
|
||||||
|
IConsolePrint(CC_HELP, " list: list all the authorized keys of the given type.");
|
||||||
|
IConsolePrint(CC_HELP, " add: add the given key to the authorized keys of the given type.");
|
||||||
|
IConsolePrint(CC_HELP, " remove: remove the given key from the authorized keys of the given type; use 'all' to remove all authorized keys.");
|
||||||
|
IConsolePrint(CC_HELP, "Instead of a key, use 'client:<id>' to add/remove the key of that given client.");
|
||||||
|
|
||||||
|
std::string buffer;
|
||||||
|
for (auto [name, _] : _console_cmd_authorized_keys) fmt::format_to(std::back_inserter(buffer), ", {}", name);
|
||||||
|
IConsolePrint(CC_HELP, "The supported types are: all{}.", buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid_type = false; ///< Whether a valid type was given.
|
||||||
|
|
||||||
|
for (auto [name, authorized_keys] : _console_cmd_authorized_keys) {
|
||||||
|
if (!StrEqualsIgnoreCase(argv[2], name) && !StrEqualsIgnoreCase(argv[2], "all")) continue;
|
||||||
|
|
||||||
|
valid_type = true;
|
||||||
|
|
||||||
|
if (StrEqualsIgnoreCase(argv[1], "list")) {
|
||||||
|
IConsolePrint(CC_WHITE, "The authorized keys for {} are:", name);
|
||||||
|
for (auto &authorized_key : *authorized_keys) IConsolePrint(CC_INFO, " {}", authorized_key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc <= 3) {
|
||||||
|
IConsolePrint(CC_ERROR, "You must enter the key.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string authorized_key = argv[3];
|
||||||
|
if (StrStartsWithIgnoreCase(authorized_key, "client:")) {
|
||||||
|
std::string id_string(authorized_key.substr(7));
|
||||||
|
authorized_key = NetworkGetPublicKeyOfClient(static_cast<ClientID>(std::stoi(id_string)));
|
||||||
|
if (authorized_key.empty()) {
|
||||||
|
IConsolePrint(CC_ERROR, "You must enter a valid client id; see 'clients'.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEqualsIgnoreCase(argv[1], "add")) {
|
||||||
|
if (authorized_keys->Add(authorized_key)) {
|
||||||
|
IConsolePrint(CC_INFO, "Added {} to {}.", authorized_key, name);
|
||||||
|
} else {
|
||||||
|
IConsolePrint(CC_WARNING, "Not added {} to {} as it already exists.", authorized_key, name);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEqualsIgnoreCase(argv[1], "remove")) {
|
||||||
|
if (authorized_keys->Remove(authorized_key)) {
|
||||||
|
IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name);
|
||||||
|
} else {
|
||||||
|
IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConsolePrint(CC_WARNING, "No valid action was given.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid_type) {
|
||||||
|
IConsolePrint(CC_WARNING, "No valid type was given.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Content downloading only is available with ZLIB */
|
/* Content downloading only is available with ZLIB */
|
||||||
#if defined(WITH_ZLIB)
|
#if defined(WITH_ZLIB)
|
||||||
#include "network/network_content.h"
|
#include "network/network_content.h"
|
||||||
@@ -2091,10 +2193,14 @@ DEF_CONSOLE_CMD(ConFont)
|
|||||||
IConsolePrint(CC_HELP, "Manage the fonts configuration.");
|
IConsolePrint(CC_HELP, "Manage the fonts configuration.");
|
||||||
IConsolePrint(CC_HELP, "Usage 'font'.");
|
IConsolePrint(CC_HELP, "Usage 'font'.");
|
||||||
IConsolePrint(CC_HELP, " Print out the fonts configuration.");
|
IConsolePrint(CC_HELP, " Print out the fonts configuration.");
|
||||||
IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [<name>] [<size>] [aa|noaa]'.");
|
IConsolePrint(CC_HELP, " The \"Currently active\" configuration is the one actually in effect (after interface scaling and replacing unavailable fonts).");
|
||||||
|
IConsolePrint(CC_HELP, " The \"Requested\" configuration is the one requested via console command or config file.");
|
||||||
|
IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [<font name>] [<size>] [aa|noaa]'.");
|
||||||
IConsolePrint(CC_HELP, " Change the configuration for a font.");
|
IConsolePrint(CC_HELP, " Change the configuration for a font.");
|
||||||
IConsolePrint(CC_HELP, " Omitting an argument will keep the current value.");
|
IConsolePrint(CC_HELP, " Omitting an argument will keep the current value.");
|
||||||
IConsolePrint(CC_HELP, " Set <name> to \"\" for the sprite font (size and aa have no effect on sprite font).");
|
IConsolePrint(CC_HELP, " Set <font name> to \"\" for the default font. Note that <size> and aa/noaa have no effect if the default font is in use, and fixed defaults are used instead.");
|
||||||
|
IConsolePrint(CC_HELP, " If the sprite font is enabled in Game Options, it is used instead of the default font.");
|
||||||
|
IConsolePrint(CC_HELP, " The <size> is automatically multiplied by the current interface scaling.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2112,7 +2218,7 @@ DEF_CONSOLE_CMD(ConFont)
|
|||||||
uint size = setting->size;
|
uint size = setting->size;
|
||||||
bool aa = setting->aa;
|
bool aa = setting->aa;
|
||||||
|
|
||||||
byte arg_index = 2;
|
uint8_t arg_index = 2;
|
||||||
/* We may encounter "aa" or "noaa" but it must be the last argument. */
|
/* We may encounter "aa" or "noaa" but it must be the last argument. */
|
||||||
if (StrEqualsIgnoreCase(argv[arg_index], "aa") || StrEqualsIgnoreCase(argv[arg_index], "noaa")) {
|
if (StrEqualsIgnoreCase(argv[arg_index], "aa") || StrEqualsIgnoreCase(argv[arg_index], "noaa")) {
|
||||||
aa = !StrStartsWithIgnoreCase(argv[arg_index++], "no");
|
aa = !StrStartsWithIgnoreCase(argv[arg_index++], "no");
|
||||||
@@ -2152,7 +2258,9 @@ DEF_CONSOLE_CMD(ConFont)
|
|||||||
InitFontCache(fs == FS_MONO);
|
InitFontCache(fs == FS_MONO);
|
||||||
fc = FontCache::Get(fs);
|
fc = FontCache::Get(fs);
|
||||||
}
|
}
|
||||||
IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font, setting->size, setting->aa ? "aa" : "noaa");
|
IConsolePrint(CC_DEFAULT, "{} font:", FontSizeToName(fs));
|
||||||
|
IConsolePrint(CC_DEFAULT, "Currently active: \"{}\", size {}, {}", fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa");
|
||||||
|
IConsolePrint(CC_DEFAULT, "Requested: \"{}\", size {}, {}", setting->font, setting->size, setting->aa ? "aa" : "noaa");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2708,7 +2816,7 @@ void IConsoleStdLibRegister()
|
|||||||
IConsole::CmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
|
IConsole::CmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
|
||||||
IConsole::CmdRegister("rcon", ConRcon, ConHookNeedNetwork);
|
IConsole::CmdRegister("rcon", ConRcon, ConHookNeedNetwork);
|
||||||
|
|
||||||
IConsole::CmdRegister("join", ConJoinCompany, ConHookNeedNetwork);
|
IConsole::CmdRegister("join", ConJoinCompany, ConHookNeedNonDedicatedNetwork);
|
||||||
IConsole::AliasRegister("spectate", "join 255");
|
IConsole::AliasRegister("spectate", "join 255");
|
||||||
IConsole::CmdRegister("move", ConMoveClient, ConHookServerOnly);
|
IConsole::CmdRegister("move", ConMoveClient, ConHookServerOnly);
|
||||||
IConsole::CmdRegister("reset_company", ConResetCompany, ConHookServerOnly);
|
IConsole::CmdRegister("reset_company", ConResetCompany, ConHookServerOnly);
|
||||||
@@ -2722,6 +2830,9 @@ void IConsoleStdLibRegister()
|
|||||||
IConsole::CmdRegister("pause", ConPauseGame, ConHookServerOrNoNetwork);
|
IConsole::CmdRegister("pause", ConPauseGame, ConHookServerOrNoNetwork);
|
||||||
IConsole::CmdRegister("unpause", ConUnpauseGame, ConHookServerOrNoNetwork);
|
IConsole::CmdRegister("unpause", ConUnpauseGame, ConHookServerOrNoNetwork);
|
||||||
|
|
||||||
|
IConsole::CmdRegister("authorized_key", ConNetworkAuthorizedKey, ConHookServerOnly);
|
||||||
|
IConsole::AliasRegister("ak", "authorized_key %+");
|
||||||
|
|
||||||
IConsole::CmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
|
IConsole::CmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
|
||||||
IConsole::AliasRegister("company_password", "company_pw %+");
|
IConsole::AliasRegister("company_password", "company_pw %+");
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "textbuf_type.h"
|
#include "textbuf_type.h"
|
||||||
#include "window_gui.h"
|
#include "window_gui.h"
|
||||||
|
#include "autocompletion.h"
|
||||||
#include "console_gui.h"
|
#include "console_gui.h"
|
||||||
#include "console_internal.h"
|
#include "console_internal.h"
|
||||||
#include "window_func.h"
|
#include "window_func.h"
|
||||||
@@ -73,9 +74,44 @@ static std::deque<IConsoleLine> _iconsole_buffer;
|
|||||||
|
|
||||||
static bool TruncateBuffer();
|
static bool TruncateBuffer();
|
||||||
|
|
||||||
|
class ConsoleAutoCompletion final : public AutoCompletion {
|
||||||
|
public:
|
||||||
|
using AutoCompletion::AutoCompletion;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> GetSuggestions(std::string_view prefix, std::string_view query) override
|
||||||
|
{
|
||||||
|
prefix = StrTrimView(prefix);
|
||||||
|
std::vector<std::string> suggestions;
|
||||||
|
|
||||||
|
/* We only suggest commands or aliases, so we only do it for the first token or an argument to help command. */
|
||||||
|
if (!prefix.empty() && prefix != "help") {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &[_, command] : IConsole::Commands()) {
|
||||||
|
if (command.name.starts_with(query)) {
|
||||||
|
suggestions.push_back(command.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &[_, alias] : IConsole::Aliases()) {
|
||||||
|
if (alias.name.starts_with(query)) {
|
||||||
|
suggestions.push_back(alias.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplySuggestion(std::string_view prefix, std::string_view suggestion) override
|
||||||
|
{
|
||||||
|
this->textbuf->Assign(fmt::format("{}{} ", prefix, suggestion));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* ** main console cmd buffer ** */
|
/* ** main console cmd buffer ** */
|
||||||
static Textbuf _iconsole_cmdline(ICON_CMDLN_SIZE);
|
static Textbuf _iconsole_cmdline(ICON_CMDLN_SIZE);
|
||||||
|
static ConsoleAutoCompletion _iconsole_tab_completion(&_iconsole_cmdline);
|
||||||
static std::deque<std::string> _iconsole_history;
|
static std::deque<std::string> _iconsole_history;
|
||||||
static ptrdiff_t _iconsole_historypos;
|
static ptrdiff_t _iconsole_historypos;
|
||||||
IConsoleModes _iconsole_mode;
|
IConsoleModes _iconsole_mode;
|
||||||
@@ -91,6 +127,7 @@ static void IConsoleClearCommand()
|
|||||||
_iconsole_cmdline.pixels = 0;
|
_iconsole_cmdline.pixels = 0;
|
||||||
_iconsole_cmdline.caretpos = 0;
|
_iconsole_cmdline.caretpos = 0;
|
||||||
_iconsole_cmdline.caretxoffs = 0;
|
_iconsole_cmdline.caretxoffs = 0;
|
||||||
|
_iconsole_tab_completion.Reset();
|
||||||
SetWindowDirty(WC_CONSOLE, 0);
|
SetWindowDirty(WC_CONSOLE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +144,7 @@ static constexpr NWidgetPart _nested_console_window_widgets[] = {
|
|||||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_BACKGROUND), SetResize(1, 1),
|
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_BACKGROUND), SetResize(1, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _console_window_desc(__FILE__, __LINE__,
|
static WindowDesc _console_window_desc(
|
||||||
WDP_MANUAL, nullptr, 0, 0,
|
WDP_MANUAL, nullptr, 0, 0,
|
||||||
WC_CONSOLE, WC_NONE,
|
WC_CONSOLE, WC_NONE,
|
||||||
0,
|
0,
|
||||||
@@ -274,8 +311,18 @@ struct IConsoleWindow : Window
|
|||||||
IConsoleCmdExec("clear");
|
IConsoleCmdExec("clear");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case WKC_TAB:
|
||||||
if (_iconsole_cmdline.HandleKeyPress(key, keycode) != HKPR_NOT_HANDLED) {
|
if (_iconsole_tab_completion.AutoComplete()) {
|
||||||
|
this->SetDirty();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
HandleKeyPressResult handle_result = _iconsole_cmdline.HandleKeyPress(key, keycode);
|
||||||
|
if (handle_result != HKPR_NOT_HANDLED) {
|
||||||
|
if (handle_result == HKPR_EDITING) {
|
||||||
|
_iconsole_tab_completion.Reset();
|
||||||
|
}
|
||||||
IConsoleWindow::scroll = 0;
|
IConsoleWindow::scroll = 0;
|
||||||
IConsoleResetHistoryPos();
|
IConsoleResetHistoryPos();
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
@@ -283,6 +330,7 @@ struct IConsoleWindow : Window
|
|||||||
return ES_NOT_HANDLED;
|
return ES_NOT_HANDLED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ES_HANDLED;
|
return ES_HANDLED;
|
||||||
}
|
}
|
||||||
@@ -290,13 +338,14 @@ struct IConsoleWindow : Window
|
|||||||
void InsertTextString(WidgetID, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
|
void InsertTextString(WidgetID, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
|
||||||
{
|
{
|
||||||
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
|
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
|
||||||
|
_iconsole_tab_completion.Reset();
|
||||||
IConsoleWindow::scroll = 0;
|
IConsoleWindow::scroll = 0;
|
||||||
IConsoleResetHistoryPos();
|
IConsoleResetHistoryPos();
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Textbuf *GetFocusedTextbuf() const override
|
const Textbuf *GetFocusedTextbuf() const override
|
||||||
{
|
{
|
||||||
return &_iconsole_cmdline;
|
return &_iconsole_cmdline;
|
||||||
}
|
}
|
||||||
@@ -469,6 +518,7 @@ static void IConsoleHistoryNavigate(int direction)
|
|||||||
} else {
|
} else {
|
||||||
_iconsole_cmdline.Assign(_iconsole_history[_iconsole_historypos]);
|
_iconsole_cmdline.Assign(_iconsole_history[_iconsole_historypos]);
|
||||||
}
|
}
|
||||||
|
_iconsole_tab_completion.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -528,8 +578,8 @@ bool IsValidConsoleColour(TextColour c)
|
|||||||
/* A text colour from the palette is used; must be the company
|
/* A text colour from the palette is used; must be the company
|
||||||
* colour gradient, so it must be one of those. */
|
* colour gradient, so it must be one of those. */
|
||||||
c &= ~TC_IS_PALETTE_COLOUR;
|
c &= ~TC_IS_PALETTE_COLOUR;
|
||||||
for (uint i = COLOUR_BEGIN; i < COLOUR_END; i++) {
|
for (Colours i = COLOUR_BEGIN; i < COLOUR_END; i++) {
|
||||||
if (_colour_gradient[i][4] == c) return true;
|
if (GetColourGradient(i, SHADE_NORMAL) == c) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ enum ConsoleHookResult {
|
|||||||
* If you want to handle multiple words as one, enclose them in double-quotes
|
* If you want to handle multiple words as one, enclose them in double-quotes
|
||||||
* eg. 'say "hello everybody"'
|
* eg. 'say "hello everybody"'
|
||||||
*/
|
*/
|
||||||
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
|
typedef bool IConsoleCmdProc(uint8_t argc, char *argv[]);
|
||||||
typedef ConsoleHookResult IConsoleHook(bool echo);
|
typedef ConsoleHookResult IConsoleHook(bool echo);
|
||||||
struct IConsoleCmd {
|
struct IConsoleCmd {
|
||||||
IConsoleCmd(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook) : name(name), proc(proc), hook(hook) {}
|
IConsoleCmd(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook) : name(name), proc(proc), hook(hook) {}
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ public:
|
|||||||
* @param size the amount of bytes to allocate.
|
* @param size the amount of bytes to allocate.
|
||||||
* @return the given amounts of bytes zeroed.
|
* @return the given amounts of bytes zeroed.
|
||||||
*/
|
*/
|
||||||
inline void *operator new(size_t size) { return CallocT<byte>(size); }
|
inline void *operator new(size_t size) { return CallocT<uint8_t>(size); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory allocator for an array of class instances.
|
* Memory allocator for an array of class instances.
|
||||||
* @param size the amount of bytes to allocate.
|
* @param size the amount of bytes to allocate.
|
||||||
* @return the given amounts of bytes zeroed.
|
* @return the given amounts of bytes zeroed.
|
||||||
*/
|
*/
|
||||||
inline void *operator new[](size_t size) { return CallocT<byte>(size); }
|
inline void *operator new[](size_t size) { return CallocT<uint8_t>(size); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory release for a single class instance.
|
* Memory release for a single class instance.
|
||||||
|
|||||||
@@ -22,20 +22,18 @@ struct Backup {
|
|||||||
/**
|
/**
|
||||||
* Backup variable.
|
* Backup variable.
|
||||||
* @param original Variable to backup.
|
* @param original Variable to backup.
|
||||||
* @param file Filename for debug output. Use FILE_LINE macro.
|
* @param location Source location for debug output.
|
||||||
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
|
||||||
*/
|
*/
|
||||||
Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {}
|
Backup(T &original, const std::source_location location = std::source_location::current()) : original(original), valid(true), original_value(original), location(location) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backup variable and switch to new value.
|
* Backup variable and switch to new value.
|
||||||
* @param original Variable to backup.
|
* @param original Variable to backup.
|
||||||
* @param new_value New value for variable.
|
* @param new_value New value for variable.
|
||||||
* @param file Filename for debug output. Use FILE_LINE macro.
|
* @param location Source location for debug output.
|
||||||
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
|
||||||
*/
|
*/
|
||||||
template <typename U>
|
template <typename U>
|
||||||
Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line)
|
Backup(T &original, const U &new_value, const std::source_location location = std::source_location::current()) : original(original), valid(true), original_value(original), location(location)
|
||||||
{
|
{
|
||||||
/* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
|
/* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
|
||||||
original = new_value;
|
original = new_value;
|
||||||
@@ -51,7 +49,7 @@ struct Backup {
|
|||||||
{
|
{
|
||||||
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
|
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
|
||||||
* Exceptions are especially used to abort world generation. */
|
* Exceptions are especially used to abort world generation. */
|
||||||
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->file, this->line);
|
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->location.file_name(), this->location.line());
|
||||||
this->Restore();
|
this->Restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,8 +138,7 @@ private:
|
|||||||
bool valid;
|
bool valid;
|
||||||
T original_value;
|
T original_value;
|
||||||
|
|
||||||
const char * const file;
|
const std::source_location location;
|
||||||
const int line;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ inline void MemMoveT(T *destination, const T *source, size_t num = 1)
|
|||||||
* @param num number of items to be set (!not number of bytes!)
|
* @param num number of items to be set (!not number of bytes!)
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void MemSetT(T *ptr, byte value, size_t num = 1)
|
inline void MemSetT(T *ptr, uint8_t value, size_t num = 1)
|
||||||
{
|
{
|
||||||
memset(ptr, value, num * sizeof(T));
|
memset(ptr, value, num * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public:
|
|||||||
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||||
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||||
inline constexpr OverflowSafeInt operator * (const uint16_t factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const uint16_t factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||||
inline constexpr OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const uint8_t factor) const { OverflowSafeInt result = *this; result *= (int64_t)factor; return result; }
|
||||||
|
|
||||||
/* Operators for division. */
|
/* Operators for division. */
|
||||||
inline constexpr OverflowSafeInt& operator /= (const int64_t divisor) { this->m_value /= divisor; return *this; }
|
inline constexpr OverflowSafeInt& operator /= (const int64_t divisor) { this->m_value /= divisor; return *this; }
|
||||||
@@ -200,10 +200,10 @@ template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint a
|
|||||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||||
|
|
||||||
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const byte a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator + (const uint8_t a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
||||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const byte a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator - (const uint8_t a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
||||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const byte a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint8_t a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
||||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const byte a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint8_t a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||||
|
|
||||||
typedef OverflowSafeInt<int64_t> OverflowSafeInt64;
|
typedef OverflowSafeInt<int64_t> OverflowSafeInt64;
|
||||||
typedef OverflowSafeInt<int32_t> OverflowSafeInt32;
|
typedef OverflowSafeInt<int32_t> OverflowSafeInt32;
|
||||||
|
|||||||
@@ -123,9 +123,9 @@ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
|
|||||||
memset((void *)item, 0, sizeof(Titem));
|
memset((void *)item, 0, sizeof(Titem));
|
||||||
}
|
}
|
||||||
} else if (Tzero) {
|
} else if (Tzero) {
|
||||||
item = (Titem *)CallocT<byte>(size);
|
item = (Titem *)CallocT<uint8_t>(size);
|
||||||
} else {
|
} else {
|
||||||
item = (Titem *)MallocT<byte>(size);
|
item = (Titem *)MallocT<uint8_t>(size);
|
||||||
}
|
}
|
||||||
this->data[index] = item;
|
this->data[index] = item;
|
||||||
SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
|
SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
|
||||||
|
|||||||
@@ -49,17 +49,6 @@ uint32_t Randomizer::Next()
|
|||||||
return this->state[1] = std::rotr(s, 3) - 1;
|
return this->state[1] = std::rotr(s, 3) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the next pseudo random number scaled to \a limit, excluding \a limit
|
|
||||||
* itself.
|
|
||||||
* @param limit Limit of the range to be generated from.
|
|
||||||
* @return Random number in [0,\a limit)
|
|
||||||
*/
|
|
||||||
uint32_t Randomizer::Next(uint32_t limit)
|
|
||||||
{
|
|
||||||
return ((uint64_t)this->Next() * (uint64_t)limit) >> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Re)set the state of the random number generator.
|
* (Re)set the state of the random number generator.
|
||||||
* @param seed the new state
|
* @param seed the new state
|
||||||
@@ -81,19 +70,14 @@ void SetRandomSeed(uint32_t seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RANDOM_DEBUG
|
#ifdef RANDOM_DEBUG
|
||||||
uint32_t DoRandom(int line, const char *file)
|
uint32_t Random(const std::source_location location)
|
||||||
{
|
{
|
||||||
if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
|
if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
|
||||||
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", TimerGameEconomy::date, TimerGameEconomy::date_fract, _frame_counter, (byte)_current_company, file, line);
|
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", TimerGameEconomy::date, TimerGameEconomy::date_fract, _frame_counter, (uint8_t)_current_company, location.file_name(), location.line());
|
||||||
}
|
}
|
||||||
|
|
||||||
return _random.Next();
|
return _random.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DoRandomRange(uint32_t limit, int line, const char *file)
|
|
||||||
{
|
|
||||||
return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32;
|
|
||||||
}
|
|
||||||
#endif /* RANDOM_DEBUG */
|
#endif /* RANDOM_DEBUG */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user