Merge branch 'jgrpp-beta' into jgrpp
This commit is contained in:
17
.github/ISSUE_TEMPLATE/bug.md
vendored
17
.github/ISSUE_TEMPLATE/bug.md
vendored
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bugs
|
|
||||||
about: Found a bug in OpenTTD?
|
|
||||||
title: "Bug Report"
|
|
||||||
---
|
|
||||||
|
|
||||||
## Version of OpenTTD
|
|
||||||
<!-- Fill in below what version of OpenTTD you are using, including your OS. -->
|
|
||||||
|
|
||||||
## Expected result
|
|
||||||
<!-- Describe in a few words what you expected to happen. -->
|
|
||||||
|
|
||||||
## Actual result
|
|
||||||
<!-- Describe in a few words what actually happens. -->
|
|
||||||
|
|
||||||
## Steps to reproduce
|
|
||||||
<!-- As detailed as possible, please tell us how we can reproduce this. Feel free to attach a savegame (zip it first) to make it more clear. -->
|
|
41
.github/ISSUE_TEMPLATE/bug.yaml
vendored
Normal file
41
.github/ISSUE_TEMPLATE/bug.yaml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Found a bug in OpenTTD?
|
||||||
|
title: "[Bug]: "
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version of OpenTTD
|
||||||
|
description: Fill in below what version of OpenTTD you are using, including your OS.
|
||||||
|
placeholder: ex. 1.11.2, Windows 10
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: Expected result
|
||||||
|
description: Describe in a few words what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: actual
|
||||||
|
attributes:
|
||||||
|
label: Actual result
|
||||||
|
description: Describe in a few words what actually happens.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduce
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: As detailed as possible, please tell us how we can reproduce this. Feel free to attach a savegame (zip it first) to make it more clear.
|
||||||
|
placeholder: |
|
||||||
|
1. Loaded the attached savegame.
|
||||||
|
2. Click on the button left of that other icon.
|
||||||
|
3. The window doesn't open.
|
||||||
|
validations:
|
||||||
|
required: true
|
12
.github/ISSUE_TEMPLATE/crash.md
vendored
12
.github/ISSUE_TEMPLATE/crash.md
vendored
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
name: Crash
|
|
||||||
about: Did OpenTTD crash?
|
|
||||||
title: "Crash Report"
|
|
||||||
---
|
|
||||||
<!-- Please zip the crash.log, crash.dmp and crash.sav and attach it to this crash report. -->
|
|
||||||
|
|
||||||
## Version of OpenTTD
|
|
||||||
<!-- Fill in below what version of OpenTTD you are using, including your OS. -->
|
|
||||||
|
|
||||||
## Steps to reproduce
|
|
||||||
<!-- Please spend a few words if you can reproduce this problem. -->
|
|
37
.github/ISSUE_TEMPLATE/crash.yaml
vendored
Normal file
37
.github/ISSUE_TEMPLATE/crash.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Crash
|
||||||
|
description: Did OpenTTD crash?
|
||||||
|
title: "[Crash]: "
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this crash report!
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version of OpenTTD
|
||||||
|
description: Fill in below what version of OpenTTD you are using, including your OS.
|
||||||
|
placeholder: ex. 1.11.2, Windows 10
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduce
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Please spend a few words if you can reproduce this problem.
|
||||||
|
placeholder: |
|
||||||
|
1. Bought a new train.
|
||||||
|
2. The game crashed.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: crashlogs
|
||||||
|
attributes:
|
||||||
|
label: Upload crash files
|
||||||
|
description: With the `crash.log`, `crash.dmp`, and `crash.sav` we can analyze the crash in detail; this way you allow us to easier triage and fix the problem.
|
||||||
|
placeholder: |
|
||||||
|
1. Zip the `crash.log`, `crash.dmp` and `crash.sav`.
|
||||||
|
2. Click on this field.
|
||||||
|
3. Drag and drop the zip file in here.
|
||||||
|
validations:
|
||||||
|
required: true
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -39,6 +39,7 @@ Describe here
|
|||||||
|
|
||||||
Some things are not automated, and forgotten often. This list is a reminder for the reviewers.
|
Some things are not automated, and forgotten often. This list is a reminder for the reviewers.
|
||||||
* The bug fix is important enough to be backported? (label: 'backport requested')
|
* The bug fix is important enough to be backported? (label: 'backport requested')
|
||||||
|
* This PR touches english.txt or translations? Check the [guidelines](https://github.com/OpenTTD/OpenTTD/blob/master/docs/eints.md)
|
||||||
* This PR affects the save game format? (label 'savegame upgrade')
|
* This PR affects the save game format? (label 'savegame upgrade')
|
||||||
* This PR affects the GS/AI API? (label 'needs review: Script API')
|
* This PR affects the GS/AI API? (label 'needs review: Script API')
|
||||||
* ai_changelog.hpp, gs_changelog.hpp need updating.
|
* ai_changelog.hpp, gs_changelog.hpp need updating.
|
||||||
|
4
.github/changelog.sh
vendored
4
.github/changelog.sh
vendored
@@ -4,9 +4,9 @@ tag=$(git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed 's@\
|
|||||||
|
|
||||||
# If we are a tag, show the part of the changelog till (but excluding) the last stable
|
# If we are a tag, show the part of the changelog till (but excluding) the last stable
|
||||||
if [ -n "$tag" ]; then
|
if [ -n "$tag" ]; then
|
||||||
grep='^[0-9]\+\.[0-9]\+\.[0-9]\+[^-]'
|
grep='^[0-9]\+\.[0-9]\+[^-]'
|
||||||
next=$(cat changelog.txt | grep '^[0-9]' | awk 'BEGIN { show="false" } // { if (show=="true") print $0; if ($1=="'$tag'") show="true"} ' | grep "$grep" | head -n1 | sed 's/ .*//')
|
next=$(cat changelog.txt | grep '^[0-9]' | awk 'BEGIN { show="false" } // { if (show=="true") print $0; if ($1=="'$tag'") show="true"} ' | grep "$grep" | head -n1 | sed 's/ .*//')
|
||||||
cat changelog.txt | awk 'BEGIN { show="false" } /^[0-9]+.[0-9]+.[0-9]+/ { if ($1=="'$next'") show="false"; if ($1=="'$tag'") show="true";} // { if (show=="true") print $0 }'
|
cat changelog.txt | awk 'BEGIN { show="false" } /^[0-9]+.[0-9]+/ { if ($1=="'$next'") show="false"; if ($1=="'$tag'") show="true";} // { if (show=="true") print $0 }'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
221
.github/unused-strings.py
vendored
Normal file
221
.github/unused-strings.py
vendored
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
"""
|
||||||
|
Script to scan the OpenTTD source-tree for STR_ entries that are defined but
|
||||||
|
no longer used.
|
||||||
|
|
||||||
|
This is not completely trivial, as OpenTTD references a lot of strings in
|
||||||
|
relation to another string. The most obvious example of this is a list. OpenTTD
|
||||||
|
only references the first entry in the list, and does "+ <var>" to get to the
|
||||||
|
correct string.
|
||||||
|
|
||||||
|
There are other ways OpenTTD does use relative values. This script tries to
|
||||||
|
account for all of them, to give the best approximation we have for "this
|
||||||
|
string is unused".
|
||||||
|
"""
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
LENGTH_NAME_LOOKUP = {
|
||||||
|
"VEHICLE_TYPES": 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SkipType(Enum):
|
||||||
|
NONE = 1
|
||||||
|
LENGTH = 2
|
||||||
|
EXTERNAL = 3
|
||||||
|
ZERO_IS_SPECIAL = 4
|
||||||
|
EXPECT_NEWLINE = 5
|
||||||
|
|
||||||
|
|
||||||
|
def read_language_file(filename, strings_found, errors):
|
||||||
|
strings_defined = []
|
||||||
|
|
||||||
|
skip = SkipType.NONE
|
||||||
|
length = 0
|
||||||
|
common_prefix = ""
|
||||||
|
last_tiny_string = ""
|
||||||
|
|
||||||
|
with open(filename) as fp:
|
||||||
|
for line in fp.readlines():
|
||||||
|
if not line.strip():
|
||||||
|
if skip == SkipType.EXPECT_NEWLINE:
|
||||||
|
skip = SkipType.NONE
|
||||||
|
continue
|
||||||
|
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if skip == SkipType.EXPECT_NEWLINE:
|
||||||
|
# The only thing allowed after a list, is this next marker, or a newline.
|
||||||
|
if line == "###next-name-looks-similar":
|
||||||
|
# "###next-name-looks-similar"
|
||||||
|
# Indicates the common prefix of the last list has a very
|
||||||
|
# similar name to the next entry, but isn't part of the
|
||||||
|
# list. So do not emit a warning about them looking very
|
||||||
|
# similar.
|
||||||
|
|
||||||
|
if length != 0:
|
||||||
|
errors.append(f"ERROR: list around {name} is shorted than indicated by ###length")
|
||||||
|
|
||||||
|
common_prefix = ""
|
||||||
|
else:
|
||||||
|
errors.append(f"ERROR: expected a newline after a list, but didn't find any around {name}. Did you add an entry to the list without increasing the length?")
|
||||||
|
|
||||||
|
skip = SkipType.NONE
|
||||||
|
|
||||||
|
if line[0] == "#":
|
||||||
|
if line.startswith("###length "):
|
||||||
|
# "###length <count>"
|
||||||
|
# Indicates the next few entries are part of a list. Only
|
||||||
|
# the first entry is possibly referenced, and the rest are
|
||||||
|
# indirectly.
|
||||||
|
|
||||||
|
if length != 0:
|
||||||
|
errors.append(f"ERROR: list around {name} is shorted than indicated by ###length")
|
||||||
|
|
||||||
|
length = line.split(" ")[1].strip()
|
||||||
|
|
||||||
|
if length.isnumeric():
|
||||||
|
length = int(length)
|
||||||
|
else:
|
||||||
|
length = LENGTH_NAME_LOOKUP[length]
|
||||||
|
|
||||||
|
skip = SkipType.LENGTH
|
||||||
|
elif line.startswith("###external "):
|
||||||
|
# "###external <count>"
|
||||||
|
# Indicates the next few entries are used outside the
|
||||||
|
# source and will not be referenced.
|
||||||
|
|
||||||
|
if length != 0:
|
||||||
|
errors.append(f"ERROR: list around {name} is shorted than indicated by ###length")
|
||||||
|
|
||||||
|
length = line.split(" ")[1].strip()
|
||||||
|
length = int(length)
|
||||||
|
|
||||||
|
skip = SkipType.EXTERNAL
|
||||||
|
elif line.startswith("###setting-zero-is-special"):
|
||||||
|
# "###setting-zero-is-special"
|
||||||
|
# Indicates the next entry is part of the "zero is special"
|
||||||
|
# flag of settings. These entries are not referenced
|
||||||
|
# directly in the code.
|
||||||
|
|
||||||
|
if length != 0:
|
||||||
|
errors.append(f"ERROR: list around {name} is shorted than indicated by ###length")
|
||||||
|
|
||||||
|
skip = SkipType.ZERO_IS_SPECIAL
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = line.split(":")[0].strip()
|
||||||
|
strings_defined.append(name)
|
||||||
|
|
||||||
|
# If a string ends on _TINY or _SMALL, it can be the {TINY} variant.
|
||||||
|
# Check for this by some fuzzy matching.
|
||||||
|
if name.endswith(("_SMALL", "_TINY")):
|
||||||
|
last_tiny_string = name
|
||||||
|
elif last_tiny_string:
|
||||||
|
matching_name = "_".join(last_tiny_string.split("_")[:-1])
|
||||||
|
if name == matching_name:
|
||||||
|
strings_found.add(last_tiny_string)
|
||||||
|
else:
|
||||||
|
last_tiny_string = ""
|
||||||
|
|
||||||
|
if skip == SkipType.EXTERNAL:
|
||||||
|
strings_found.add(name)
|
||||||
|
skip = SkipType.LENGTH
|
||||||
|
|
||||||
|
if skip == SkipType.LENGTH:
|
||||||
|
skip = SkipType.NONE
|
||||||
|
length -= 1
|
||||||
|
common_prefix = name
|
||||||
|
elif skip == SkipType.ZERO_IS_SPECIAL:
|
||||||
|
strings_found.add(name)
|
||||||
|
elif length > 0:
|
||||||
|
strings_found.add(name)
|
||||||
|
length -= 1
|
||||||
|
|
||||||
|
# Find the common prefix of these strings
|
||||||
|
for i in range(len(common_prefix)):
|
||||||
|
if common_prefix[0 : i + 1] != name[0 : i + 1]:
|
||||||
|
common_prefix = common_prefix[0:i]
|
||||||
|
break
|
||||||
|
|
||||||
|
if length == 0:
|
||||||
|
skip = SkipType.EXPECT_NEWLINE
|
||||||
|
|
||||||
|
if len(common_prefix) < 6:
|
||||||
|
errors.append(f"ERROR: common prefix of block including {name} was reduced to {common_prefix}. This means the names in the list are not consistent.")
|
||||||
|
elif common_prefix:
|
||||||
|
if name.startswith(common_prefix):
|
||||||
|
errors.append(f"ERROR: {name} looks a lot like block above with prefix {common_prefix}. This mostly means that the list length was too short. Use '###next-name-looks-similar' if it is not.")
|
||||||
|
common_prefix = ""
|
||||||
|
|
||||||
|
return strings_defined
|
||||||
|
|
||||||
|
|
||||||
|
def scan_source_files(path, strings_found):
|
||||||
|
for new_path in glob.glob(f"{path}/*"):
|
||||||
|
if os.path.isdir(new_path):
|
||||||
|
scan_source_files(new_path, strings_found)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not new_path.endswith((".c", ".h", ".cpp", ".hpp", ".ini")):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Most files we can just open, but some use magic, that requires the
|
||||||
|
# G++ preprocessor before we can make sense out of it.
|
||||||
|
if new_path == "src/table/cargo_const.h":
|
||||||
|
p = subprocess.run(["g++", "-E", new_path], stdout=subprocess.PIPE)
|
||||||
|
output = p.stdout.decode()
|
||||||
|
else:
|
||||||
|
with open(new_path) as fp:
|
||||||
|
output = fp.read()
|
||||||
|
|
||||||
|
# Find all the string references.
|
||||||
|
matches = re.findall(r"[^A-Z_](STR_[A-Z0-9_]*)", output)
|
||||||
|
strings_found.update(matches)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
strings_found = set()
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
scan_source_files("src", strings_found)
|
||||||
|
strings_defined = read_language_file("src/lang/english.txt", strings_found, errors)
|
||||||
|
|
||||||
|
# STR_LAST_STRINGID is special, and not really a string.
|
||||||
|
strings_found.remove("STR_LAST_STRINGID")
|
||||||
|
# These are mentioned in comments, not really a string.
|
||||||
|
strings_found.remove("STR_XXX")
|
||||||
|
strings_found.remove("STR_NEWS")
|
||||||
|
strings_found.remove("STR_CONTENT_TYPE_")
|
||||||
|
|
||||||
|
# This string is added for completion, but never used.
|
||||||
|
strings_defined.remove("STR_JUST_DATE_SHORT")
|
||||||
|
|
||||||
|
strings_defined = sorted(strings_defined)
|
||||||
|
strings_found = sorted(list(strings_found))
|
||||||
|
|
||||||
|
for string in strings_found:
|
||||||
|
if string not in strings_defined:
|
||||||
|
errors.append(f"ERROR: {string} found but never defined.")
|
||||||
|
|
||||||
|
for string in strings_defined:
|
||||||
|
if string not in strings_found:
|
||||||
|
errors.append(f"ERROR: {string} is (possibly) no longer needed.")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
for error in errors:
|
||||||
|
print(error)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("OK")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
93
.github/workflows/ci-build.yml
vendored
93
.github/workflows/ci-build.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container:
|
container:
|
||||||
# If you change this version, change the number in the cache step too.
|
# If you change this version, change the number in the cache step too.
|
||||||
image: emscripten/emsdk:2.0.10
|
image: emscripten/emsdk:2.0.31
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -38,7 +38,12 @@ jobs:
|
|||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: /emsdk/upstream/emscripten/cache
|
path: /emsdk/upstream/emscripten/cache
|
||||||
key: 2.0.10-${{ runner.os }}
|
key: 2.0.31-${{ 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)
|
- name: Build (host tools)
|
||||||
run: |
|
run: |
|
||||||
@@ -89,7 +94,7 @@ jobs:
|
|||||||
libsdl: libsdl1.2-dev
|
libsdl: libsdl1.2-dev
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
cxxcompiler: g++
|
cxxcompiler: g++
|
||||||
extra-cmake-parameters: -DOPTION_DEDICATED=ON
|
extra-cmake-parameters: -DOPTION_DEDICATED=ON -DCMAKE_CXX_FLAGS_INIT="-DRANDOM_DEBUG"
|
||||||
|
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
@@ -314,3 +319,85 @@ jobs:
|
|||||||
echo "::group::Build"
|
echo "::group::Build"
|
||||||
cmake --build .
|
cmake --build .
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
msys2:
|
||||||
|
name: msys2
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- msystem: MINGW64
|
||||||
|
arch: x86_64
|
||||||
|
- msystem: MINGW32
|
||||||
|
arch: i686
|
||||||
|
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup MSYS2
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: ${{ matrix.msystem }}
|
||||||
|
release: false
|
||||||
|
install: >-
|
||||||
|
git
|
||||||
|
make
|
||||||
|
mingw-w64-${{ matrix.arch }}-cmake
|
||||||
|
mingw-w64-${{ matrix.arch }}-gcc
|
||||||
|
mingw-w64-${{ matrix.arch }}-lzo2
|
||||||
|
mingw-w64-${{ matrix.arch }}-libpng
|
||||||
|
|
||||||
|
- name: Install OpenGFX
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
cd "C:/Users/Public/Documents/OpenTTD/baseset"
|
||||||
|
|
||||||
|
echo "::group::Download OpenGFX"
|
||||||
|
curl -L https://cdn.openttd.org/opengfx-releases/0.6.0/opengfx-0.6.0-all.zip -o opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Unpack OpenGFX"
|
||||||
|
unzip opengfx-all.zip
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
rm -f opengfx-all.zip
|
||||||
|
|
||||||
|
- name: Install GCC problem matcher
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: msys2 {0}
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
echo "::group::CMake"
|
||||||
|
cmake .. -G"MSYS Makefiles"
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
echo "::group::Build"
|
||||||
|
echo "Running on $(nproc) cores"
|
||||||
|
cmake --build . -j $(nproc)
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
check_annotations:
|
||||||
|
name: Check Annotations
|
||||||
|
needs:
|
||||||
|
- emscripten
|
||||||
|
- linux
|
||||||
|
- macos
|
||||||
|
- windows
|
||||||
|
- msys2
|
||||||
|
|
||||||
|
if: always() && github.event_name == 'pull_request'
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check annotations
|
||||||
|
uses: OpenTTD/actions/annotation-check@v2
|
||||||
|
24
.github/workflows/preview_build.yml
vendored
24
.github/workflows/preview_build.yml
vendored
@@ -12,9 +12,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container:
|
container:
|
||||||
# If you change this version, change the number in the cache step too.
|
# If you change this version, change the number in the cache step too.
|
||||||
image: emscripten/emsdk:2.0.10
|
image: emscripten/emsdk:2.0.31
|
||||||
# uid=1001(runner) gid=121(docker)
|
|
||||||
options: -u 1001:121
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Update deployment status to in progress
|
- name: Update deployment status to in progress
|
||||||
@@ -46,7 +44,12 @@ jobs:
|
|||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: /emsdk/upstream/emscripten/cache
|
path: /emsdk/upstream/emscripten/cache
|
||||||
key: 2.0.10-${{ runner.os }}
|
key: 2.0.31-${{ 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)
|
- name: Build (host tools)
|
||||||
run: |
|
run: |
|
||||||
@@ -84,18 +87,15 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish preview
|
- name: Publish preview
|
||||||
run: |
|
run: |
|
||||||
# setuptools is missing in this Docker image, which breaks installing
|
|
||||||
# awscli. So we need to do this in two steps to recover sanity.
|
|
||||||
pip3 install setuptools
|
|
||||||
pip3 install awscli
|
pip3 install awscli
|
||||||
|
|
||||||
~/.local/bin/aws s3 cp --only-show-errors build/openttd.data s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
aws s3 cp --only-show-errors build/openttd.data s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
||||||
~/.local/bin/aws s3 cp --only-show-errors build/openttd.html s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
aws s3 cp --only-show-errors build/openttd.html s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
||||||
~/.local/bin/aws s3 cp --only-show-errors build/openttd.js s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
aws s3 cp --only-show-errors build/openttd.js s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
||||||
~/.local/bin/aws s3 cp --only-show-errors build/openttd.wasm s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
aws s3 cp --only-show-errors build/openttd.wasm s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/
|
||||||
|
|
||||||
# Invalidate the cache of the CloudFront distribution
|
# Invalidate the cache of the CloudFront distribution
|
||||||
~/.local/bin/aws cloudfront create-invalidation --distribution-id ${{ secrets.PREVIEW_CF_DISTRIBUTION_ID }} --paths "/${{ github.event.client_payload.folder }}/*"
|
aws cloudfront create-invalidation --distribution-id ${{ secrets.PREVIEW_CF_DISTRIBUTION_ID }} --paths "/${{ github.event.client_payload.folder }}/*"
|
||||||
env:
|
env:
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
43
.github/workflows/release.yml
vendored
43
.github/workflows/release.yml
vendored
@@ -374,14 +374,19 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- container_image: "ubuntu:18.04"
|
- container_image: "ubuntu:18.04"
|
||||||
bundle_name: "bionic"
|
bundle_name: "bionic"
|
||||||
|
compiler: "g++-8"
|
||||||
- container_image: "ubuntu:20.04"
|
- container_image: "ubuntu:20.04"
|
||||||
bundle_name: "focal"
|
bundle_name: "focal"
|
||||||
|
compiler: "g++"
|
||||||
- container_image: "ubuntu:20.10"
|
- container_image: "ubuntu:20.10"
|
||||||
bundle_name: "groovy"
|
bundle_name: "groovy"
|
||||||
|
compiler: "g++"
|
||||||
- container_image: "debian:buster"
|
- container_image: "debian:buster"
|
||||||
bundle_name: "buster"
|
bundle_name: "buster"
|
||||||
|
compiler: "g++"
|
||||||
- container_image: "debian:bullseye"
|
- container_image: "debian:bullseye"
|
||||||
bundle_name: "bullseye"
|
bundle_name: "bullseye"
|
||||||
|
compiler: "g++"
|
||||||
|
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container:
|
container:
|
||||||
@@ -407,7 +412,7 @@ jobs:
|
|||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
cmake \
|
cmake \
|
||||||
debhelper \
|
debhelper \
|
||||||
g++ \
|
${{ matrix.compiler }} \
|
||||||
git \
|
git \
|
||||||
make \
|
make \
|
||||||
openssl \
|
openssl \
|
||||||
@@ -434,7 +439,7 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
|
|
||||||
echo "::group::CMake"
|
echo "::group::CMake"
|
||||||
cmake ${GITHUB_WORKSPACE} \
|
CXX=${{ matrix.compiler }} cmake ${GITHUB_WORKSPACE} \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
# EOF
|
# EOF
|
||||||
@@ -470,7 +475,7 @@ jobs:
|
|||||||
name: MacOS
|
name: MacOS
|
||||||
needs: source
|
needs: source
|
||||||
|
|
||||||
runs-on: macos-10.15
|
runs-on: macos-11
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.9
|
MACOSX_DEPLOYMENT_TARGET: 10.9
|
||||||
|
|
||||||
@@ -750,6 +755,21 @@ 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: needs.source.outputs.is_tag == 'true'
|
if: needs.source.outputs.is_tag == 'true'
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -765,12 +785,15 @@ jobs:
|
|||||||
-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 \
|
||||||
|
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
|
||||||
# EOF
|
# EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Build"
|
echo "::group::Build"
|
||||||
cmake --build .
|
cmake --build .
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
env:
|
||||||
|
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
||||||
|
|
||||||
- name: Build (without installer)
|
- name: Build (without installer)
|
||||||
if: needs.source.outputs.is_tag != 'true'
|
if: needs.source.outputs.is_tag != 'true'
|
||||||
@@ -786,12 +809,15 @@ jobs:
|
|||||||
-DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \
|
-DCMAKE_TOOLCHAIN_FILE="c:\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 \
|
||||||
|
-DWINDOWS_CERTIFICATE_COMMON_NAME="${WINDOWS_CERTIFICATE_COMMON_NAME}" \
|
||||||
# EOF
|
# EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Build"
|
echo "::group::Build"
|
||||||
cmake --build .
|
cmake --build .
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
env:
|
||||||
|
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
||||||
|
|
||||||
- name: Create bundles
|
- name: Create bundles
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -813,6 +839,17 @@ jobs:
|
|||||||
rm -f bundles/*.sha256
|
rm -f bundles/*.sha256
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Sign installer
|
||||||
|
if: needs.source.outputs.is_tag == 'true'
|
||||||
|
shell: bash
|
||||||
|
# If this is run on a fork, there may not be a certificate set up - continue in this case
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
cd ${GITHUB_WORKSPACE}/build/bundles
|
||||||
|
../../os/windows/sign.bat *.exe "${WINDOWS_CERTIFICATE_COMMON_NAME}"
|
||||||
|
env:
|
||||||
|
WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }}
|
||||||
|
|
||||||
- name: Store bundles
|
- name: Store bundles
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
18
.github/workflows/unused-strings.yml
vendored
Normal file
18
.github/workflows/unused-strings.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: Unused strings
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unused-strings:
|
||||||
|
name: Unused strings
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Check for unused strings
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
python3 .github/unused-strings.py
|
@@ -5,7 +5,7 @@ if(NOT BINARY_NAME)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(${BINARY_NAME}
|
project(${BINARY_NAME}
|
||||||
VERSION 1.12.0
|
VERSION 13.0
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||||
@@ -96,7 +96,6 @@ if(OPTION_TOOLS_ONLY)
|
|||||||
-DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
|
-DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
|
||||||
-DREV_MAJOR=${PROJECT_VERSION_MAJOR}
|
-DREV_MAJOR=${PROJECT_VERSION_MAJOR}
|
||||||
-DREV_MINOR=${PROJECT_VERSION_MINOR}
|
-DREV_MINOR=${PROJECT_VERSION_MINOR}
|
||||||
-DREV_BUILD=${PROJECT_VERSION_PATCH}
|
|
||||||
$<$<PLATFORM_ID:Windows>:-DWIN32=TRUE>
|
$<$<PLATFORM_ID:Windows>:-DWIN32=TRUE>
|
||||||
-P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
|
-P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
@@ -311,6 +310,10 @@ target_link_libraries(openttd
|
|||||||
Threads::Threads
|
Threads::Threads
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(HAIKU)
|
||||||
|
target_link_libraries(openttd "be" "network" "midi")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(IPO_FOUND)
|
if(IPO_FOUND)
|
||||||
set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE True)
|
set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE True)
|
||||||
set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL True)
|
set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL True)
|
||||||
@@ -375,7 +378,7 @@ if(EMSCRIPTEN)
|
|||||||
add_definitions(-s DISABLE_EXCEPTION_CATCHING=0)
|
add_definitions(-s DISABLE_EXCEPTION_CATCHING=0)
|
||||||
|
|
||||||
# Export functions to Javascript.
|
# Export functions to Javascript.
|
||||||
target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_FUNCTIONS='[\"_main\", \"_em_openttd_add_server\"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_FUNCTIONS='[\"_main\", \"_em_openttd_add_server\"]' -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||||
|
|
||||||
# Preload all the files we generate during build.
|
# Preload all the files we generate during build.
|
||||||
# As we do not compile with FreeType / FontConfig, we also have no way to
|
# As we do not compile with FreeType / FontConfig, we also have no way to
|
||||||
@@ -429,6 +432,7 @@ if(WIN32)
|
|||||||
-DUNICODE
|
-DUNICODE
|
||||||
-D_UNICODE
|
-D_UNICODE
|
||||||
-DWITH_UNISCRIBE
|
-DWITH_UNISCRIBE
|
||||||
|
-DPSAPI_VERSION=1
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(openttd
|
target_link_libraries(openttd
|
||||||
@@ -436,11 +440,12 @@ if(WIN32)
|
|||||||
winmm
|
winmm
|
||||||
imm32
|
imm32
|
||||||
usp10
|
usp10
|
||||||
|
psapi
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
add_definitions(-D_SQ64)
|
add_definitions(-DPOINTER_IS_64BIT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CreateRegression)
|
include(CreateRegression)
|
||||||
@@ -470,7 +475,6 @@ add_custom_target(find_version
|
|||||||
-DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
|
-DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
|
||||||
-DREV_MAJOR=${PROJECT_VERSION_MAJOR}
|
-DREV_MAJOR=${PROJECT_VERSION_MAJOR}
|
||||||
-DREV_MINOR=${PROJECT_VERSION_MINOR}
|
-DREV_MINOR=${PROJECT_VERSION_MINOR}
|
||||||
-DREV_BUILD=${PROJECT_VERSION_PATCH}
|
|
||||||
-DCONFIGURE_DEFINES="${CFG_DEFS}"
|
-DCONFIGURE_DEFINES="${CFG_DEFS}"
|
||||||
$<$<PLATFORM_ID:Windows>:-DWIN32=TRUE>
|
$<$<PLATFORM_ID:Windows>:-DWIN32=TRUE>
|
||||||
-P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
|
-P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
|
||||||
|
@@ -383,7 +383,7 @@ Both 'stable' and 'nightly' versions are available for download:
|
|||||||
- most people should choose the 'stable' version, as this has been more extensively tested
|
- most people should choose the 'stable' version, as this has been more extensively tested
|
||||||
- the 'nightly' version includes the latest changes and features, but may sometimes be less reliable
|
- the 'nightly' version includes the latest changes and features, but may sometimes be less reliable
|
||||||
|
|
||||||
On some platforms OpenTTD will also be available via your OS package manager or a similar service.
|
OpenTTD is also available for free on [Steam](https://store.steampowered.com/app/1536610/OpenTTD/), [GOG.com](https://www.gog.com/game/openttd), and the [Microsoft Store](https://www.microsoft.com/p/openttd-official/9ncjg5rvrr1c). On some platforms OpenTTD will be available via your OS package manager or a similar service.
|
||||||
|
|
||||||
|
|
||||||
## 1.2) OpenTTD gameplay manual
|
## 1.2) OpenTTD gameplay manual
|
||||||
|
8
bin/ai/compat_12.nut
Normal file
8
bin/ai/compat_12.nut
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AILog.Info("12 API compatibility in effect.");
|
8
bin/game/compat_12.nut
Normal file
8
bin/game/compat_12.nut
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GSLog.Info("12 API compatibility in effect.");
|
227
changelog.txt
227
changelog.txt
@@ -1,3 +1,216 @@
|
|||||||
|
12.0-beta2 (2021-08-19)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Feature: [Linkgraph] Prioritize faster routes for passengers, mail and express cargo (#9457)
|
||||||
|
Fix: Wrong town window refreshed when building an airport with noise levels enabled (#9497)
|
||||||
|
Fix: Improve wording of network-related messages (#9494, #9495, #9500)
|
||||||
|
Fix: [Network] Report reuse of invite-code (#9487)
|
||||||
|
Fix: [Network] Connecting with the same client name thrice hangs the server (#9485)
|
||||||
|
|
||||||
|
|
||||||
|
12.0-beta1 (2021-08-15)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Feature: [Network] Remove lobby window; pressing "Join Game" now immediately joins a server (#9467)
|
||||||
|
Feature: [Network] Synchronize server name to clients and display in Online Players window (#9472)
|
||||||
|
Feature: [Network] Mention you are a spectator in the status bar (#9471)
|
||||||
|
Feature: [Network] No longer require port-forwarding to host a server (#9443, #9447)
|
||||||
|
Feature: [Network] Allow setting your server visibility to "invite-only" (#9434)
|
||||||
|
Feature: [Network] Join servers based on their invite code (#9432)
|
||||||
|
Feature: Raise the maximum NewGRF limit to 255 (#9428)
|
||||||
|
Feature: Persistent rotation of numbered auto/netsave after restart (#9395, #9397)
|
||||||
|
Feature: [NewGRF] Maximum curve speed modifier for rail vehicles (#9346)
|
||||||
|
Feature: Move sensitive information to secrets.cfg and private information to private.cfg (#9298)
|
||||||
|
Feature: Signed Windows builds (#9294)
|
||||||
|
Feature: [NewGRF] Define refittability of default vehicles using cargo classes (#9148)
|
||||||
|
Feature: Configurable subsidy duration, up to 5000 years (#9081)
|
||||||
|
Feature: [Network] Rework in-game Online Players window (#9067)
|
||||||
|
Feature: [Network] Show previous chat history when the chat message box is open (#9025)
|
||||||
|
Feature: Button to reset game settings to their default values (#8958)
|
||||||
|
Feature: Press Ctrl to build diagonal rivers in Scenario Editor (#8880)
|
||||||
|
Feature: Set wagon replacement per group when using autoreplace (#7441)
|
||||||
|
Add: [Network] Open Online Players window on starting/joining a server (#9479)
|
||||||
|
Add: [Script] Basic information about loaded NewGRFs for scripts (#9464)
|
||||||
|
Add: [AI] Get the number of vehicles in a given group (#9462)
|
||||||
|
Add: [Network] Inform network clients what game-script a server is running (#9441)
|
||||||
|
Add: Hindi translation (#9086)
|
||||||
|
Add: [Network] Ensure players fill in a name instead of defaulting to "Player" (#9080)
|
||||||
|
Change: Allow pause/unpause console command in single player (#9342)
|
||||||
|
Change: Make savegame format self-descriptive and consistent across all objects (#9322, #9335, #9338, #9339)
|
||||||
|
Change: By default, make "unload all" leave stations empty (#9301)
|
||||||
|
Change: Reworked the debug levels and messages for network logs (#9230, #9251)
|
||||||
|
Change: [Emscripten] Set default scrolling mode to non-pointer-locking (#9191)
|
||||||
|
Change: Use neutral pronouns for various strings (#9189, #9203, #9228)
|
||||||
|
Change: Make the town directory horizontally resizable (#9157)
|
||||||
|
Change: Allow non-ASCII currency separators (#9121)
|
||||||
|
Change: [NewGRF] Display a pop-up window for Errors with severity ERROR (#9119)
|
||||||
|
Change: Treat languages as finished, if translations are 75% completed (#9019, #9086)
|
||||||
|
Change: Disable NewGRF window apply button if no change was made (#8934)
|
||||||
|
Fix: [Script] Crash when iterating lists of which the key is larger than 32bit (#9465)
|
||||||
|
Fix: [Network] Desync due to use of unstable sort when distributing cargo production (#9460)
|
||||||
|
Fix #9440: Negative cargo payments not being handled correctly (#9455)
|
||||||
|
Fix: [Network] Crash when joining a server again after a TCP disconnect (#9453)
|
||||||
|
Fix: Don't enable rename button for network clients in build vehicle window (#9452)
|
||||||
|
Fix: Money could underflow and wrap around (#9451)
|
||||||
|
Fix: Parse the console settings the same way as config settings (#9438)
|
||||||
|
Fix: Ensure no more than the allowed number of NewGRFs are loaded from the configuration (#9430)
|
||||||
|
Fix: [NewGRF] Overflow when determining cargo mask for string code 9A 1E (#9423)
|
||||||
|
Fix: Integers for scripts are 64bit, but saved as 32bit (#9415)
|
||||||
|
Fix #9392: [Script] Return a valid value with GetBuildWithRefitCapacity even when AIs are maxed out in vehicles (#9393)
|
||||||
|
Fix #8169: Crash when autoreplacing vehicle with no orders (#9387)
|
||||||
|
Fix: Wrong cargo line position in IndustryCargo window (#9383)
|
||||||
|
Fix: Race-condition during startup of NewGRF scan (#9382)
|
||||||
|
Fix: Don't propagate Shift/Ctrl state till next game-tick (#9381)
|
||||||
|
Fix: Prevent palette updates during copying to the video driver (#9379)
|
||||||
|
Fix: [Network] Determining GetNetworkRevisionString could overflow and underflow its buffer (#9372)
|
||||||
|
Fix #9358: Don't skip empty files in tar archives (#9367)
|
||||||
|
Fix: For old savegames, station bus/truck station cache was not updated (#9366)
|
||||||
|
Fix #9353: [Script] Garbage collecting on priority queues could crash the game (#9356)
|
||||||
|
Fix: Respect the autosave_on_exit setting for Null video driver (#9343)
|
||||||
|
Fix: Compatible NewGRFs in crash-log reported wrong MD5 hash (#9340)
|
||||||
|
Fix: [Script] Ensure the saved script strings are properly validated and terminated (#9336)
|
||||||
|
Fix #9316: Town bridge length limit check incorrect above 250k inhabitants (#9318)
|
||||||
|
Fix: Limit heightmap sizes to 8192x8192 (#9307)
|
||||||
|
Fix #9281: Money generating exploit when buying out a company (#9300)
|
||||||
|
Fix: Part of a tile might not be redrawn when terraforming (#9296)
|
||||||
|
Fix: [OpenGL] Increase timeout when waiting for the GPU to be done with the drawing buffer (#9282)
|
||||||
|
Fix: Vehicles sent in the wrong direction if there is no path to the destination (#9280)
|
||||||
|
Fix #9264: Do not attach temporary wagons to free wagon chains when autoreplacing (#9278)
|
||||||
|
Fix #9267: [Script] Crash during garbage collection (#9275)
|
||||||
|
Fix: Encountering two-way red signals could prune unrelated Pathfinder branches (#9271)
|
||||||
|
Fix #9255: [Network] Crash when hostname is not found (#9259)
|
||||||
|
Fix #9256: Invalid read after free when replacing train chains (#9258)
|
||||||
|
Fix: [Emscripten] Force secure WebSockets over HTTPS (#9248)
|
||||||
|
Fix #9242: Tree tick handler did not scale by map size (#9246)
|
||||||
|
Fix: [Network] Mark server as offline when no longer reachable (#9244)
|
||||||
|
Fix: [Network] Don't rebuild the host-list during iterating the list (#9240)
|
||||||
|
Fix: [Network] Don't mark the last-joined server as a manually added server (#9239)
|
||||||
|
Fix: [Network] Clients leaving because of broken connections was not broadcasted (#9238)
|
||||||
|
Fix: [Network] Check on CIDR for netmask check considered everything valid (#9235)
|
||||||
|
Fix: Creating screenshots on dedicated servers failed (#9232)
|
||||||
|
Fix: Leaking file descriptors for downloaded content (#9229)
|
||||||
|
Fix: Spelling of several town names (#9222)
|
||||||
|
Fix #9209: Game hangs when resizing highscore/news window if the screen is too small (#9210)
|
||||||
|
Fix: [Network] Optimize creating network connections for clients using IPv4 and IPv6 (#9199)
|
||||||
|
Fix #9186: Fix incorrect bounding box height causing station sprite glitch (#9187)
|
||||||
|
Fix: Truncating strings in settings could leave invalid UTF-8 characters (#9121)
|
||||||
|
Fix: Many issues related to window scaling (#9087, #9219)
|
||||||
|
Fix: Invalidate cached vehicle colourmaps when changing liveries setting (#9006)
|
||||||
|
Fix #8981: Don't attempt to re-reserve path if already entering/entered depot (#9000)
|
||||||
|
Fix: Missing 'Town names:' colon in map gen GUI (#8986)
|
||||||
|
Fix: Sorting and filtering industries that produce/accept many cargoes (#8468)
|
||||||
|
Remove: [Network] COMPANY_INFO packets (#9475)
|
||||||
|
Remove: [Network] A server can no longer set a limit to the amount of spectators allowed (#9466)
|
||||||
|
Remove: Arbitrary limit on number of statically loaded NewGRFs (#9431)
|
||||||
|
Remove: [Network] Language and map-name from server information (#9070)
|
||||||
|
|
||||||
|
|
||||||
|
1.11.2 (2021-05-03)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Change: [Win32] Limit hardware accelerated video driver to OpenGL 3.2 or higher (#9077)
|
||||||
|
Change: More improvements to the GUI at different scales (#9075, #9102, #9107, #9133, #9174, #9183)
|
||||||
|
Fix: Query windows could be partially drawn (#9184)
|
||||||
|
Fix #9113: Crash when removing an airport that exists in an aircraft's orders (#9182)
|
||||||
|
Fix #9117: [Fluidsynth] Hang when changing song (#9181)
|
||||||
|
Fix: String validation could leave invalid UTF-8 encoded strings (#9096)
|
||||||
|
Fix: [Network] Out-of-bounds memory access with modified servers sending too short password salts (#9176)
|
||||||
|
Fix: Crash when extra viewport with zero height has sign in view (#9175)
|
||||||
|
Fix #9147: Crash when taking screenshots (#9169)
|
||||||
|
Fix #6598: [Network] Prevent crashes when (re)joining network game by falling back to main menu first (#9163)
|
||||||
|
Fix #9152: Screenshot success popup window was treated as an error (#9159)
|
||||||
|
Fix: Fast-forward stuttering when vsync is enabled (#9140)
|
||||||
|
Fix: [Network, Win32] Network errors were handled badly (#9116)
|
||||||
|
Fix: [Network] Savegame transfer could stall in rare cases (#9106)
|
||||||
|
Fix #9097: [NewGRF] Cargo initial payment variable was being truncated (#9098)
|
||||||
|
Fix: [NewGRF] Industry variable 66 and object variable 46 erroneously truncated the distance (#9088)
|
||||||
|
Fix: [NewGRF] Industry variables 65 and 66 ignored the parameter, and always used the north tile (#9088)
|
||||||
|
Fix: Do not include regression test AI in bundle (#9068, #9164)
|
||||||
|
Fix #9062: [Win32] Version in executable was not set to current release version (#9066, #9154)
|
||||||
|
|
||||||
|
|
||||||
|
1.11.1 (2021-04-18)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Feature: Toggle to enable/disable vsync (#8997)
|
||||||
|
Feature: Volume controls in the Game Options window, and better defaults (#8943)
|
||||||
|
Add: Hotkey to focus object and rail filters (#8908)
|
||||||
|
Add: Better plural support for Romanian (#8936)
|
||||||
|
Change: Improve layout and spacing of several windows at different GUI scales (#9041, #9042, #9044, #9050)
|
||||||
|
Change: [Win32] Use user UI language setting for initial language selection (#8974)
|
||||||
|
Change: Make effect volume scale more intuitively (#8945, #8950)
|
||||||
|
Change: Improve padding of Object & Rail station windows (#8929)
|
||||||
|
Fix #6322: [Script] Crash when script allocates too much memory, now kills script instead (#9047)
|
||||||
|
Fix #7513: [Script] Crash on garbage collection with misbehaving script (#9040)
|
||||||
|
Fix #9028: [OpenGL] Crash when changing max sprite zoom level (#9032)
|
||||||
|
Fix #8874: show a warning when a NewGRF scan is requested multiple times (#9022)
|
||||||
|
Fix: Desync when GS unlocks railtype with wagon unlock (#9021)
|
||||||
|
Fix #9015: [Win32] Crash on running "pwd" command in the console (#9016)
|
||||||
|
Fix #9008: Validate starting year given on the command line (-t) (#9014)
|
||||||
|
Fix #8878: [Network] Slow DNS queries could block the server and disconnect clients (#9013)
|
||||||
|
Fix: Improve validation of OpenGL video driver to avoid crashes (#9007)
|
||||||
|
Fix: Credits scrolled too slowly with larger font sizes (#8994)
|
||||||
|
Fix #8977: Crash when altering max sprite resolution (#8993)
|
||||||
|
Fix #8956: Industry disaster news messages showed the wrong location (#8992)
|
||||||
|
Fix: [Win32] Font glyphs of certain widths had broken rendering (#8990)
|
||||||
|
Fix #8930: [Win32] Duplicate text input issue for systems using IME (#8976)
|
||||||
|
Fix: [Network] Potential stale client entries in client list (#8959)
|
||||||
|
Fix: Graphical issues when dragging measurement tooltips (#8951)
|
||||||
|
Fix: [Fluidsynth] Use provided default soundfont if available (#8948, #8953)
|
||||||
|
Fix #8935: [macOS] Crash on save (#8944)
|
||||||
|
Fix #8922: Crash when selling shared vehicles with shared vehicle window open (#8926)
|
||||||
|
Fix: Compiling on armhf (Raspberry Pi) (#8924)
|
||||||
|
|
||||||
|
|
||||||
|
1.11.0 (2021-04-01)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Feature: Allow setting a custom terrain type to define highest peak (#8891)
|
||||||
|
Feature: Auto-detect map height limit based on generated map (#8891)
|
||||||
|
Feature: Setting to indicate desert coverage for tropic climate and snow coverage for arctic climate (replaces snow line height) (#8891)
|
||||||
|
Add: Allow setting the highest mountain for heightmaps (#8891)
|
||||||
|
Change: Scale exported heightmaps to highest peak and inform the user of this value (#8891)
|
||||||
|
Change: Remove "maximum map height" from the New Game GUI (#8891)
|
||||||
|
Fix #8803: Only auto-remove signals when rail can be built (#8904)
|
||||||
|
Fix #8565: Stopped road vehicle displays a speed different than 0 (#8901)
|
||||||
|
Fix #8886: Don't try to resolve folders within tars named '.' (#8893)
|
||||||
|
Fix: Placing random trees in SE crashes the game (#8892)
|
||||||
|
Fix #8875: Filter string in station window breaks flow in user interface (#8885)
|
||||||
|
Fix #8871: [OpenGL] Initialize all buffers after resize and clear back buffer (#8877)
|
||||||
|
Fix: OpenGL performance with some AMD GPUs (#8876)
|
||||||
|
Fix: Recompute road/railtype availability after disabling the engine (#8872)
|
||||||
|
Fix: OSK layout not scaled for 2x or 4x GUI scale (#8868)
|
||||||
|
|
||||||
|
|
||||||
|
1.11.0-RC1 (2021-03-14)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Feature: Option to (dis-)allow hardware accelerated video drivers (#8819)
|
||||||
|
Feature: Option to set display refresh rate (#8813)
|
||||||
|
Feature: Allow custom width/height of screenshot and making heightmap screenshots via console (#8804)
|
||||||
|
Feature: Allow filtering on name in rail station window (#8706)
|
||||||
|
Feature: Setting for highest resolution of sprites to use (#8604)
|
||||||
|
Add: Make NewGRF Scanner / World Generation update smoother and make aborting it react faster (#8830)
|
||||||
|
Add: Malaysia Ringgit as Currency (#8783)
|
||||||
|
Add: "Engines only" filter in build train window (#8733)
|
||||||
|
Change: De-limit framerate window's framerate (#8772)
|
||||||
|
Change: Clarify what effect town interactions have (#8744)
|
||||||
|
Change: Don't show global goals in company goal windows (#8709)
|
||||||
|
Change: Recolour graph windows to brown (#8700)
|
||||||
|
Fix #8855: Bootstrap could result in an empty screen when bootstrap fails (#8856)
|
||||||
|
Fix #8851: Don't allow infinite "exec" depth in script, but limit to 10 deep (#8852)
|
||||||
|
Fix #8647: Incorrect drawing order of tram catenary sprites (#8843)
|
||||||
|
Fix #8711: Having gui_zoom lower than zoom_min causes a crash (#8835)
|
||||||
|
Fix #8810: "aircraft out of fuel" news shows the wrong place (#8832)
|
||||||
|
Fix #8833: Don't reload NewGRFs when we are shutting down (#8830)
|
||||||
|
Fix: Scale padding between elements the same as other padding (#8829)
|
||||||
|
Fix #8808: [OSX, OpenGL] Crash on switching blitters due to double-mapping the video buffer (#8822)
|
||||||
|
Fix #8784: Using Alt+Enter doesn't update the fullscreen toggle visibly (#8820)
|
||||||
|
Fix #8817: Keep NewGRF order for object class sorting (#8818)
|
||||||
|
Fix #8809: Crash when removing airport when hangar window open (#8815)
|
||||||
|
Fix #8799: Crash when Search Internet in Multiplayer (#8801)
|
||||||
|
Fix #8775: [Win32] Don't create the main window when Alt-Tabbing back into fullscreen (#8792)
|
||||||
|
Fix #8774: Black screenshots when using 40bpp-blitter (#8791)
|
||||||
|
Fix: [OSX] Hide dock when entering fullscreen (#8789)
|
||||||
|
Fix: Bootstrap fails to start on clean install (#8788)
|
||||||
|
Fix: Terraform limit acts random when maxing out per_64k_frames setting (#8782)
|
||||||
|
Fix: Max-value of fast-forward-speed-limit can be outside its storage size (#8769)
|
||||||
|
|
||||||
|
|
||||||
1.11.0-beta2 (2021-02-28)
|
1.11.0-beta2 (2021-02-28)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Feature: Add setting to limit fast-forward speed (#8766)
|
Feature: Add setting to limit fast-forward speed (#8766)
|
||||||
@@ -2186,7 +2399,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: [NewGRF] Additional text in fund industry window is NewGRF supplied and thus should have a default colour (r22631)
|
- Fix: [NewGRF] Additional text in fund industry window is NewGRF supplied and thus should have a default colour (r22631)
|
||||||
- Fix: Also initialise _old_vds with newgame settings; TTD savegames do not contain these settings [FS#4622] (r22626)
|
- Fix: Also initialise _old_vds with newgame settings; TTD savegames do not contain these settings [FS#4622] (r22626)
|
||||||
- Fix: Do not zero the orders of disaster vehicles when converting savegames [FS#4642] (r22625)
|
- Fix: Do not zero the orders of disaster vehicles when converting savegames [FS#4642] (r22625)
|
||||||
- Fix: When closing an AI company the local player cheated to, we need to cheat him to another company [FS#4654] (r22624, r22623)
|
- Fix: When closing an AI company the local player cheated to, we need to cheat them to another company [FS#4654] (r22624, r22623)
|
||||||
- Fix: When closing down companies their shares in other companies must be sold even if share trading is disabled at that point of time (r22622)
|
- Fix: When closing down companies their shares in other companies must be sold even if share trading is disabled at that point of time (r22622)
|
||||||
- Fix: When asking the user to confirm an unsafe unpausing, there is no need to execute a command if 'no' is chosen. This also prevents crashing when clicking unpause while the confirm window is shown (r22621)
|
- Fix: When asking the user to confirm an unsafe unpausing, there is no need to execute a command if 'no' is chosen. This also prevents crashing when clicking unpause while the confirm window is shown (r22621)
|
||||||
- Fix: Enforce refit orders to be 'always go to depot' orders; service-only and stop-in-depot orders make no sense with refitting [FS#4651] (r22620)
|
- Fix: Enforce refit orders to be 'always go to depot' orders; service-only and stop-in-depot orders make no sense with refitting [FS#4651] (r22620)
|
||||||
@@ -2908,7 +3121,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Chat message caused glitch when rejoining a network game [FS#3757] (r19629)
|
- Fix: Chat message caused glitch when rejoining a network game [FS#3757] (r19629)
|
||||||
- Fix: Desync when a command is received and in the queue while a client starts joining, i.e. save the game state. This can happen in two ways: with frame_freq > 1 a command received in a previous frame might not be executed yet or when a command is received in the same frame as the join but before the savegame is made. In both cases the joining client would not get all commands to get in-sync with the server (and the other clients) (r19620)
|
- Fix: Desync when a command is received and in the queue while a client starts joining, i.e. save the game state. This can happen in two ways: with frame_freq > 1 a command received in a previous frame might not be executed yet or when a command is received in the same frame as the join but before the savegame is made. In both cases the joining client would not get all commands to get in-sync with the server (and the other clients) (r19620)
|
||||||
- Fix: Company related graphs were not updated correctly after changing the company colour [FS#3763] (r19615)
|
- Fix: Company related graphs were not updated correctly after changing the company colour [FS#3763] (r19615)
|
||||||
- Fix: Possible invalid read when server moves client to spectators before he finishes joining [FS#3755] (r19613)
|
- Fix: Possible invalid read when server moves client to spectators before they finish joining [FS#3755] (r19613)
|
||||||
- Fix: Crash when opening a savegame with a waypoint from around 0.4.0 [FS#3756] (r19612)
|
- Fix: Crash when opening a savegame with a waypoint from around 0.4.0 [FS#3756] (r19612)
|
||||||
- Fix: Improve joining behaviour; kicking clients when entering passwords that was just cleared, 'connection lost' for people failing the password, access restriction circumvention [CVE-2010-0401] [FS#3754] (r19610, r19609, r19608, r19607, r19606)
|
- Fix: Improve joining behaviour; kicking clients when entering passwords that was just cleared, 'connection lost' for people failing the password, access restriction circumvention [CVE-2010-0401] [FS#3754] (r19610, r19609, r19608, r19607, r19606)
|
||||||
- Fix: Desync debugging; false positives in the cache validity checks and saving/loading the command stream (r19619, r19617, r19602, r19601, r19600, r19596, r19593, r19592, r19589, r19587, r19586)
|
- Fix: Desync debugging; false positives in the cache validity checks and saving/loading the command stream (r19619, r19617, r19602, r19601, r19600, r19596, r19593, r19592, r19589, r19587, r19586)
|
||||||
@@ -3263,7 +3476,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Do not account for path reservation costs when entering a signal block via a 'block' signal. This way you will not get double penalties, both red signals and reservation costs, for the block signalled tracks [FS#2722] (r18535)
|
- Fix: Do not account for path reservation costs when entering a signal block via a 'block' signal. This way you will not get double penalties, both red signals and reservation costs, for the block signalled tracks [FS#2722] (r18535)
|
||||||
- Fix: [NewGRF] An industry NewGRF that defined a too small size for action0 prop 0A could cause a crash (r18527)
|
- Fix: [NewGRF] An industry NewGRF that defined a too small size for action0 prop 0A could cause a crash (r18527)
|
||||||
- Fix: Allegro does not like to work with extmidi, so warn the user about that [FS#3272] (r18520)
|
- Fix: Allegro does not like to work with extmidi, so warn the user about that [FS#3272] (r18520)
|
||||||
- Fix: When you pass a signal at danger, in a PBS controlled area, do not try to do the 'safe' thing and stop, but continue going; the user wanted the train to pass the signal at danger so (s)he has to suffer the consequences. Of course one can always stop the train manually [FS#2891] (r18515)
|
- Fix: When you pass a signal at danger, in a PBS controlled area, do not try to do the 'safe' thing and stop, but continue going; the user wanted the train to pass the signal at danger so they have to suffer the consequences. Of course one can always stop the train manually [FS#2891] (r18515)
|
||||||
- Fix: No error message was created for the first fatal NewGRF error [FS#3368] (r18506)
|
- Fix: No error message was created for the first fatal NewGRF error [FS#3368] (r18506)
|
||||||
- Fix: Improve airport movement on several airports [FS#3169] (r18505)
|
- Fix: Improve airport movement on several airports [FS#3169] (r18505)
|
||||||
- Fix: Autoreplace and autorenew always reset their cargo sub type to 0. Now find a sub cargo type with the exact same name and use that, otherwise fallback to 0. So cargo sub types can be maintained via autoreplace *if* the new vehicle supports the same cargo sub type [FS#3159] (r18499)
|
- Fix: Autoreplace and autorenew always reset their cargo sub type to 0. Now find a sub cargo type with the exact same name and use that, otherwise fallback to 0. So cargo sub types can be maintained via autoreplace *if* the new vehicle supports the same cargo sub type [FS#3159] (r18499)
|
||||||
@@ -3746,7 +3959,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Make the join/spectate command require to be connected to a network game; in SP it could lead to crashes (r15514)
|
- Fix: Make the join/spectate command require to be connected to a network game; in SP it could lead to crashes (r15514)
|
||||||
- Fix: Generating a map with the original map generator with freeform edges on resulted in a crash [FS#2641] (r15511)
|
- Fix: Generating a map with the original map generator with freeform edges on resulted in a crash [FS#2641] (r15511)
|
||||||
- Fix: Pre-0.5 OpenTTD stored new_nonstop and full_load_any in a different way, savegame conversion was not working for them (r15500)
|
- Fix: Pre-0.5 OpenTTD stored new_nonstop and full_load_any in a different way, savegame conversion was not working for them (r15500)
|
||||||
- Fix: Crash when opening the game options when the currently loaded base graphics pack has less than 2 valid graphics files. For example when someone replaces all his/her original base graphics with custom work (but keeps the name) or renames the dos ones to windows or vice versa [FS#2630] (r15476)
|
- Fix: Crash when opening the game options when the currently loaded base graphics pack has less than 2 valid graphics files. For example when someone replaces all their original base graphics with custom work (but keeps the name) or renames the dos ones to windows or vice versa [FS#2630] (r15476)
|
||||||
|
|
||||||
|
|
||||||
0.7.0-beta1 (2009-02-16)
|
0.7.0-beta1 (2009-02-16)
|
||||||
@@ -4508,7 +4721,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Switching players (using the cheat) crashed on Big Endian machines [FS#1150] (r11023)
|
- Fix: Switching players (using the cheat) crashed on Big Endian machines [FS#1150] (r11023)
|
||||||
- Fix: The canal border determination did not take oil rigs into consideration (r11022)
|
- Fix: The canal border determination did not take oil rigs into consideration (r11022)
|
||||||
- Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat/giving money [FS#1175] (r11021)
|
- Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat/giving money [FS#1175] (r11021)
|
||||||
- Fix: One could not give money when (s)he had too much money or rather: when casting the amount of money to an int32 becomes negative [FS#1174] (r11020)
|
- Fix: One could not give money when they had too much money or rather: when casting the amount of money to an int32 becomes negative [FS#1174] (r11020)
|
||||||
- Fix: When determining the gender of a string, do not assume that the gender is in the front of the string when there can be case switching code at that location [FS#1104] (r10792)
|
- Fix: When determining the gender of a string, do not assume that the gender is in the front of the string when there can be case switching code at that location [FS#1104] (r10792)
|
||||||
- Fix: Determining whether there is a tunnel going under the lowered area is only needed in two directions instead of all four, so take the directions (one for each axis) to the nearest border (along the given axis) [FS#1058] (r10686)
|
- Fix: Determining whether there is a tunnel going under the lowered area is only needed in two directions instead of all four, so take the directions (one for each axis) to the nearest border (along the given axis) [FS#1058] (r10686)
|
||||||
- Fix: Graphical glitches when the 'link landscape toolbar' patch is turned on when opening one of the construction toolbars [FS#1076] (r10685)
|
- Fix: Graphical glitches when the 'link landscape toolbar' patch is turned on when opening one of the construction toolbars [FS#1076] (r10685)
|
||||||
@@ -4569,7 +4782,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Do not unconditionally assume that a tile has a depot (r11027)
|
- Fix: Do not unconditionally assume that a tile has a depot (r11027)
|
||||||
- Fix: Give a more correct error when building some things on tile 0 [FS#1173] (r11024)
|
- Fix: Give a more correct error when building some things on tile 0 [FS#1173] (r11024)
|
||||||
- Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat and giving money [FS#1175] (r11021)
|
- Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat and giving money [FS#1175] (r11021)
|
||||||
- Fix: One could not give money when (s)he had too much money [FS#1174] (r11020)
|
- Fix: One could not give money when they had too much money [FS#1174] (r11020)
|
||||||
- Fix: Disallow buying/selling shares in your own company or a bankrupt company [FS#1169] (r11018)
|
- Fix: Disallow buying/selling shares in your own company or a bankrupt company [FS#1169] (r11018)
|
||||||
- Fix: Crash when quitting the game in one of the end score windows [FS#1218] (r11071)
|
- Fix: Crash when quitting the game in one of the end score windows [FS#1218] (r11071)
|
||||||
|
|
||||||
@@ -5529,7 +5742,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe
|
|||||||
- Fix: Vehicles slow down under bridge if the track is on a foundation
|
- Fix: Vehicles slow down under bridge if the track is on a foundation
|
||||||
- Fix: You can no longer change name of waypoints whom are owned by somebody else
|
- Fix: You can no longer change name of waypoints whom are owned by somebody else
|
||||||
- Fix: Shares are now also sold when a company goes bankrupt [SF#1090313]
|
- Fix: Shares are now also sold when a company goes bankrupt [SF#1090313]
|
||||||
- Fix: It is no longer possible to crash trains of other companies by building a depot close to a station; trains do no longer enter tiles that do not belong to his owner [SF#1087701]
|
- Fix: It is no longer possible to crash trains of other companies by building a depot close to a station; trains do no longer enter tiles that do not belong to their owner [SF#1087701]
|
||||||
- Fix: Crashed trains are not reported to have too few orders any more [SF#1087403]
|
- Fix: Crashed trains are not reported to have too few orders any more [SF#1087403]
|
||||||
- Fix: Backup-order-list was not closed with an OT_NOTHING, [SF#1086375]
|
- Fix: Backup-order-list was not closed with an OT_NOTHING, [SF#1086375]
|
||||||
- Fix: Docks now have a button to display the catchment area [SF#1085255]
|
- Fix: Docks now have a button to display the catchment area [SF#1085255]
|
||||||
|
@@ -26,8 +26,10 @@ macro(compile_flags)
|
|||||||
add_compile_options(/Zc:rvalueCast)
|
add_compile_options(/Zc:rvalueCast)
|
||||||
|
|
||||||
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
# Enable multi-threaded compilation.
|
add_compile_options(
|
||||||
add_compile_options(/MP)
|
/MP # Enable multi-threaded compilation.
|
||||||
|
/FC # Display the full path of source code files passed to the compiler in diagnostics.
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -165,7 +167,7 @@ macro(compile_flags)
|
|||||||
message(FATAL_ERROR "No warning flags are set for this compiler yet; please consider creating a Pull Request to add support for this compiler.")
|
message(FATAL_ERROR "No warning flags are set for this compiler yet; please consider creating a Pull Request to add support for this compiler.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32 AND NOT HAIKU)
|
||||||
# rdynamic is used to get useful stack traces from crash reports.
|
# rdynamic is used to get useful stack traces from crash reports.
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
|
||||||
endif()
|
endif()
|
||||||
|
@@ -139,6 +139,13 @@ elseif(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}")
|
set(CPACK_PACKAGE_FILE_NAME "openttd-#CPACK_PACKAGE_VERSION#-windows-${CPACK_SYSTEM_NAME}")
|
||||||
|
|
||||||
|
if(WINDOWS_CERTIFICATE_COMMON_NAME)
|
||||||
|
add_custom_command(TARGET openttd
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND "${CMAKE_SOURCE_DIR}/os/windows/sign.bat" "$<TARGET_FILE:openttd>" "${WINDOWS_CERTIFICATE_COMMON_NAME}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
# With FHS, we can create deb/rpm/... Without it, they would be horribly broken
|
# With FHS, we can create deb/rpm/... Without it, they would be horribly broken
|
||||||
# and not work. The other way around is also true; with FHS they are not
|
# and not work. The other way around is also true; with FHS they are not
|
||||||
|
@@ -6,9 +6,6 @@ endif()
|
|||||||
if(NOT REV_MINOR)
|
if(NOT REV_MINOR)
|
||||||
set(REV_MINOR 0)
|
set(REV_MINOR 0)
|
||||||
endif()
|
endif()
|
||||||
if(NOT REV_BUILD)
|
|
||||||
set(REV_BUILD 0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Finds the current version of the current folder.
|
# Finds the current version of the current folder.
|
||||||
|
@@ -28,10 +28,10 @@ endmacro()
|
|||||||
macro(dump_class_templates NAME)
|
macro(dump_class_templates NAME)
|
||||||
string(REGEX REPLACE "^Script" "" REALNAME ${NAME})
|
string(REGEX REPLACE "^Script" "" REALNAME ${NAME})
|
||||||
|
|
||||||
string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} *GetParam(ForceType<${NAME} *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (${NAME} *)instance; }")
|
string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} *GetParam(ForceType<${NAME} *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; }")
|
||||||
string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} &GetParam(ForceType<${NAME} &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(${NAME} *)instance; }")
|
string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} &GetParam(ForceType<${NAME} &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; }")
|
||||||
string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} *GetParam(ForceType<const ${NAME} *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (${NAME} *)instance; }")
|
string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} *GetParam(ForceType<const ${NAME} *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; }")
|
||||||
string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} &GetParam(ForceType<const ${NAME} &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(${NAME} *)instance; }")
|
string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} &GetParam(ForceType<const ${NAME} &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; }")
|
||||||
if("${NAME}" STREQUAL "ScriptEvent")
|
if("${NAME}" STREQUAL "ScriptEvent")
|
||||||
string(APPEND SQUIRREL_EXPORT "\n template <> inline int Return<${NAME} *>(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; }")
|
string(APPEND SQUIRREL_EXPORT "\n template <> inline int Return<${NAME} *>(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; }")
|
||||||
elseif("${NAME}" STREQUAL "ScriptText")
|
elseif("${NAME}" STREQUAL "ScriptText")
|
||||||
|
117
docs/eints.md
Normal file
117
docs/eints.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Translations for OpenTTD
|
||||||
|
|
||||||
|
Eints is [OpenTTD's WebTranslator](https://translator.openttd.org/).
|
||||||
|
|
||||||
|
- Registered translators translate from English to their language.
|
||||||
|
- Eints validates the translations syntactically and that parameter usage matches the English base language.
|
||||||
|
- Eints synchronises translations to OpenTTD's repository every day, shortly before the nightly build.
|
||||||
|
|
||||||
|
When adding or altering strings in english.txt, you should stick to some rules, so translations are handled smoothly by Eints and translators.
|
||||||
|
This document gives some guidelines.
|
||||||
|
|
||||||
|
|
||||||
|
## I want to change a translation.
|
||||||
|
|
||||||
|
### I want to become a regular translator.
|
||||||
|
|
||||||
|
Just [sign up](https://github.com/OpenTTD/team/issues/new/choose) as a translator.
|
||||||
|
|
||||||
|
### I only want to point out some issues / typos in the current translation, or suggest a change.
|
||||||
|
|
||||||
|
[Open an issue](https://github.com/OpenTTD/OpenTTD/issues/new/choose), so it can be assigned to the translation team of the language.
|
||||||
|
The translators will decide whether, where and how to apply your suggestion.
|
||||||
|
|
||||||
|
### I want to submit translations via PR.
|
||||||
|
|
||||||
|
Sorry, we don't offer this option.
|
||||||
|
|
||||||
|
### I want to change the language definition (plural form, genders, cases) of a translation.
|
||||||
|
|
||||||
|
Please [create an issue](https://github.com/OpenTTD/OpenTTD/issues/new/choose) for this.
|
||||||
|
|
||||||
|
### I want to add an entirely new translation language.
|
||||||
|
|
||||||
|
OpenTTD has more than 4000 strings, translating all of them is a lot of work.
|
||||||
|
Despite the initial enthusiasm, only few people have the endurance to get to even 20% translation progress.
|
||||||
|
|
||||||
|
As such, starting a new translation requires the prospect that there is also translation interest in the future.
|
||||||
|
And, frankly, OpenTTD probably already covers all languages to which this applies, and a few more.
|
||||||
|
|
||||||
|
If you still want to make the case, that your language is spoken by several 100 million people, please [create an issue](https://github.com/OpenTTD/OpenTTD/issues/new/choose) for adding a new language.
|
||||||
|
|
||||||
|
|
||||||
|
## I want to change the English base language (english.txt).
|
||||||
|
|
||||||
|
### I want to change the wording / fix a typo in an English string, without changing the meaning (drastically).
|
||||||
|
|
||||||
|
Just change it in your PR.
|
||||||
|
|
||||||
|
Translators will be notified that their translation became "outdated", so they can double-check whether the translation needs updating.
|
||||||
|
|
||||||
|
### I want to add/change/remove parameters from an English string.
|
||||||
|
|
||||||
|
Just change the parameters in english.txt in your PR.
|
||||||
|
Don't touch the translations, please ignore compile warnings about them.
|
||||||
|
|
||||||
|
Translators will be notified that their translation became "invalid", so they can adjust the translation.
|
||||||
|
Eints will remember the old translations for translators to view, but remove them from the git repository, while they are "invalid"; so there won't be any compile warnings after the nightly sync.
|
||||||
|
|
||||||
|
### I want to change the meaning of an English string, so that no existing translation makes any sense anymore.
|
||||||
|
|
||||||
|
In this case, please change the STR_xxx string identifier of the string; basically: remove the old string, add a new one.
|
||||||
|
Don't touch the translations, please ignore compile warnings about them.
|
||||||
|
|
||||||
|
Eints will discard all memory of the old strings in the nightly sync, and translators can start fresh with a new string.
|
||||||
|
|
||||||
|
### I want to add a new string.
|
||||||
|
|
||||||
|
Add the new string somewhere in english.txt, where it fits with the neighbouring strings.
|
||||||
|
Don't touch the translations, even if you can speak some of the languages.
|
||||||
|
|
||||||
|
### I want to remove an unused string.
|
||||||
|
|
||||||
|
Remove the string from english.txt.
|
||||||
|
Don't touch the translations, please ignore compile warnings about them.
|
||||||
|
|
||||||
|
Eints will remove the translations from the git repository in the nightly sync.
|
||||||
|
|
||||||
|
### I want to reorder strings in english.txt without changing them.
|
||||||
|
|
||||||
|
Reorder english.txt as you like. Don't touch the translations.
|
||||||
|
|
||||||
|
Eints will reorder all translations to match english.txt in the nightly sync.
|
||||||
|
|
||||||
|
### I want to add/change '#' comments.
|
||||||
|
|
||||||
|
Change comments in english.txt as you like. Don't touch the translations.
|
||||||
|
|
||||||
|
Eints will replicate comments into all translations in the nightly sync. Comments are not translated.
|
||||||
|
|
||||||
|
### I want to change the STR_xxx string identifier for code style reasons, without changing the English text.
|
||||||
|
|
||||||
|
This is the only case, where your PR should also edit translations.
|
||||||
|
The STR_xxx string identifier is used by Eints as key value to track strings and translations. If you change it, that's the same as deleting a string and adding an unrelated new one.
|
||||||
|
So, to keep translations, you have to replace the STR_xxx for all translations in the PR as well.
|
||||||
|
|
||||||
|
However, you will only be able to keep the translations which are part of the git repository.
|
||||||
|
Translation history and information about translations being "outdated" will be lost.
|
||||||
|
So, keep your code style OCD to a minimum :)
|
||||||
|
|
||||||
|
|
||||||
|
## I want to fight a bot and lose.
|
||||||
|
|
||||||
|
Here are some things, people sometimes want to do, but which won't work.
|
||||||
|
|
||||||
|
### I want to enforce re-translation by clearing current translations.
|
||||||
|
|
||||||
|
You have to change the STR_xxx string identifier, that's the only option.
|
||||||
|
|
||||||
|
You cannot "clear" translations by removing them via PR; eints will reinstall the previous "syntactically perfect valid" translation.
|
||||||
|
|
||||||
|
### I want to revert a broken change, some translator just did via eints.
|
||||||
|
|
||||||
|
You have to revert the translations via the WebTranslator interface.
|
||||||
|
If there are many changes, ask someone with Admin access to eints, so they can manually upload a fixed translation file to eints.
|
||||||
|
|
||||||
|
You cannot revert translations changes via PR. Eints merges translations from git and from web by keeping a translation history, and committing the newest translation to git.
|
||||||
|
If you revert to an old translation in git, eints will simply think git did not yet get the newer translation, and commit it again.
|
83
docs/game_coordinator.md
Normal file
83
docs/game_coordinator.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Game Coordinator
|
||||||
|
|
||||||
|
To allow two players to play together, OpenTTD uses a Game Coordinator to
|
||||||
|
facilitate this.
|
||||||
|
|
||||||
|
When a server starts, it can register itself to the Game Coordinator. This
|
||||||
|
happens when `server_game_type` is set to either `invite-only` or `public`.
|
||||||
|
Upon registration, the Game Coordinator probes the network of the server, and
|
||||||
|
assigns the server an unique code, called an `invite code`.
|
||||||
|
|
||||||
|
When a client wants to join a server, it asks the Game Coordinator to help
|
||||||
|
with this by giving it the `invite code` of the server. The Game Coordinator
|
||||||
|
will, in this order, attempt several ways to connect the client and server
|
||||||
|
together:
|
||||||
|
|
||||||
|
## 1) Via direct IPv4 / IPv6
|
||||||
|
|
||||||
|
Upon registration, the Game Coordinator probes the server to see if a
|
||||||
|
direction connection to the server is possible based on the game port. It
|
||||||
|
tries this over the public IPv4 and IPv6, as announced by the server.
|
||||||
|
If either (or both) are successful, a client will always be asked to try
|
||||||
|
these direct IPs first when it wants to connect to this server.
|
||||||
|
|
||||||
|
- If the server is IPv4 only, the client is only asked to connect via IPv4.
|
||||||
|
- If the server is IPv6 only, the client is only asked to connect via IPv6.
|
||||||
|
- If the server is both IPv4 and IPv6, the client is asked to connect to to
|
||||||
|
one of those first. If that fails, it is asked to connect to the other.
|
||||||
|
Whether it tries IPv4 or IPv6 first, strongly depends on several network
|
||||||
|
infrastructure related events. The biggest influence is the network
|
||||||
|
latency over both protocols to the OpenTTD infrastructure.
|
||||||
|
|
||||||
|
In the end, if either the server is not reachable directly from the Internet
|
||||||
|
or the client fails to connect to either one of them, the connection attempt
|
||||||
|
continues with the next available method.
|
||||||
|
|
||||||
|
## 2) Via STUN
|
||||||
|
|
||||||
|
When a client wants to join a server via STUN, both the client and server
|
||||||
|
are asked to create a connection to the STUN server (normally
|
||||||
|
`stun.openttd.org`) via both IPv4 and IPv6. If the client or server has no
|
||||||
|
IPv4 or IPv6, it will not make a connection attempt via that protocol.
|
||||||
|
|
||||||
|
The STUN server collects the public IPv4 and/or IPv6 of the client and server,
|
||||||
|
together with the port the connection came in from. For most NAT gateways it
|
||||||
|
holds true that as long as you use the same local IP + port, your public
|
||||||
|
IP + port will remain the same, and allow for bi-directional communication.
|
||||||
|
And this fact is used to later on pair the client and server.
|
||||||
|
|
||||||
|
The STUN server reports this information directly to the Game Coordinator
|
||||||
|
(this in contrast to most STUN implementation, where this information is
|
||||||
|
first reported back to the peer itself, which has to relay it back to the
|
||||||
|
coordinator. OpenTTD skips this step, as the STUN server can directly talk to
|
||||||
|
the Game Coordinator). When the Game Coordinator sees a matching pair (in
|
||||||
|
terms of IPv4 / IPv6), it will ask both the client and server to connect to
|
||||||
|
their peer based on this public IP + port.
|
||||||
|
|
||||||
|
As the NAT gateway forwards the traffic on the public IP + port to the local
|
||||||
|
port, this creates a bi-directional socket between client and server. The
|
||||||
|
connection to the STUN server can now safely be closed, and the client and
|
||||||
|
server can continue to talk to each other.
|
||||||
|
|
||||||
|
Some NAT gateways do not allow this method; for those this attempt will fail,
|
||||||
|
and this also means that it is not possible to create a connection between
|
||||||
|
the client and server.
|
||||||
|
|
||||||
|
## 3) Via TURN
|
||||||
|
|
||||||
|
As a last resort, the Game Coordinator can decide to connect the client and
|
||||||
|
server together via TURN. TURN is a relay service, relaying the messages
|
||||||
|
between client and server.
|
||||||
|
|
||||||
|
As the client and server can already connect to the Game Coordinator, it is
|
||||||
|
very likely this is successful.
|
||||||
|
|
||||||
|
It is important to note that a relay service has full view of the traffic
|
||||||
|
send between client and server, and as such it is important that you trust
|
||||||
|
the relay service used.
|
||||||
|
For official binaries, this relay service is hosted by openttd.org. The relay
|
||||||
|
service as hosted by openttd.org only validates it is relaying valid OpenTTD
|
||||||
|
packets and does no further inspection of the payload itself.
|
||||||
|
Although in our experience most patch-packs also use the services as offered
|
||||||
|
by openttd.org, it is possible they use different services. Please be mindful
|
||||||
|
about this.
|
@@ -80,7 +80,7 @@ the array so you can quickly see what is used and what is not.
|
|||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2">0</td>
|
<td rowspan="2">0</td>
|
||||||
<td class="caption">ground</td>
|
<td class="caption">ground</td>
|
||||||
<td class="bits" rowspan=29><span class="used" title="Tile type">XXXX</span> <span class="used" title="Presence and direction of bridge above">XX</span> <span class="used" title="Tropic Zone: only meaningfull in tropic climate. It contains the definition of the available zones">XX</span></td>
|
<td class="bits" rowspan=29><span class="used" title="Tile type">XXXX</span> <span class="used" title="Presence and direction of bridge above">XX</span> <span class="used" title="Tropic Zone: only meaningful in tropic climate. It contains the definition of the available zones">XX</span></td>
|
||||||
<td class="bits" rowspan=29><span class="used" title="Tile height">XXXX XXXX</span></td>
|
<td class="bits" rowspan=29><span class="used" title="Tile height">XXXX XXXX</span></td>
|
||||||
<td class="bits" rowspan=2><span class="free">OOO</span><span class="usable" title="Owner (always OWNER_NONE)">1 OOOO</span></td>
|
<td class="bits" rowspan=2><span class="free">OOO</span><span class="usable" title="Owner (always OWNER_NONE)">1 OOOO</span></td>
|
||||||
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
|
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
|
||||||
|
@@ -1,220 +1,207 @@
|
|||||||
# Multiplayer manual for OpenTTD
|
# Multiplayer manual for OpenTTD
|
||||||
|
|
||||||
Last updated: 2011-02-16
|
|
||||||
|
|
||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
- 1.0) [Starting a server](#10-starting-a-server)
|
- 1.0) [Starting a server](#10-starting-a-server)
|
||||||
- 2.0) [Connecting to a server](#20-connecting-to-a-server)
|
- 2.0) [Connecting to a server](#20-connecting-to-a-server)
|
||||||
- 2.1) [Connecting to a server over the console](#21-connecting-to-a-server-over-the-console)
|
- 2.1) [Connecting to a server over the console](#21-connecting-to-a-server-over-the-console)
|
||||||
- 3.0) [Playing internet games](#30-playing-internet-games)
|
- 3.0) [Playing internet games](#30-playing-internet-games)
|
||||||
- 4.0) [Tips for servers](#40-tips-for-servers)
|
- 4.0) [Tips for servers](#40-tips-for-servers)
|
||||||
- 4.1)[Imposing landscaping limits](#41-imposing-landscaping-limits)
|
- 4.1)[Imposing landscaping limits](#41-imposing-landscaping-limits)
|
||||||
- 5.0) [Some useful things](#50-some-useful-things)
|
- 5.0) [Some useful things](#50-some-useful-things)
|
||||||
- 6.0) [Troubleshooting](#60-troubleshooting)
|
- 6.0) [Troubleshooting](#60-troubleshooting)
|
||||||
|
|
||||||
|
|
||||||
## 1.0) Starting a server
|
## 1.0) Starting a server
|
||||||
|
|
||||||
- Make sure that you have your firewall of the computer as well as possible
|
- Click on "Multiplayer" in the Start Menu.
|
||||||
routers or modems of the server configured such that:
|
- Click on "Start Server".
|
||||||
- port 3979 is free for both UDP and TCP connections in- and outgoing
|
- Give your server a name.
|
||||||
- port 3978 is free outbound for UDP in order to advertise with the master
|
- Select the visibility of your server:
|
||||||
server (if desired). Otherwise you'll have to tell players your IP.
|
- "Public": your server will be publicly listed.
|
||||||
- port 3977 if use of the admin interface is desired (see admin_network.txt)
|
- "Invite Only": only players who have the invite code for your server can
|
||||||
- Click "multiplayer" on the startup screen
|
join.
|
||||||
- Click "start server"
|
- "Local": only players on your local network can join.
|
||||||
- Type in a game name
|
- (optional) Set a password for your server.
|
||||||
- Select the type of game ('LAN/Internet' or 'Internet (advertise)'. With the
|
- Click "New Game", "Load Game", or "Play Scenario".
|
||||||
last one other people are able to see you online. Else they need your IP and
|
- Start playing.
|
||||||
port to join)
|
|
||||||
- Click "start game", "load game" or "load scenario"
|
|
||||||
- Start playing
|
|
||||||
|
|
||||||
|
|
||||||
## 2.0) Connecting to a server
|
## 2.0) Connecting to a server
|
||||||
|
|
||||||
- Click "multiplayer" on the startup screen
|
- Click on "Multiplayer" in the Start Menu.
|
||||||
- If you want to connect to any network game in your LAN click on 'LAN', then
|
- There are three ways to join a server:
|
||||||
on 'Find Server'
|
- If you want to connect to a local server, click "Search LAN".
|
||||||
- If you want to see which servers all online on the Internet, click on
|
- If you want to connect to a public game, click "Search internet".
|
||||||
'Internet' and 'Find Server'
|
- If the server-owner shared an invite code with you:
|
||||||
- If there were more than one server
|
- Click "Add Server".
|
||||||
- select one in the list below the buttons
|
- Fill in the invite code, which always starts with a `+`.
|
||||||
- click on 'join game'
|
- Click "OK".
|
||||||
- If you want to play and you have the ip or hostname of the game server you
|
- Click on the server you want to join.
|
||||||
want connect to.
|
- Click "Join Game".
|
||||||
- click add server
|
- If the server has a password, it will ask you for this.
|
||||||
- type in the ip address or hostname
|
- You see a progressbar how far you are with joining the server.
|
||||||
- if you want to add a port use :<port>
|
- Happy playing.
|
||||||
- Now you can select a company and press: "Join company", to help that company
|
|
||||||
- Or you can press "Spectate game", to spectate the game
|
|
||||||
- Or you can press "New company", and start your own company (if there are
|
|
||||||
slots free)
|
|
||||||
- You see a progressbar how far you are with joining the server.
|
|
||||||
- Happy playing
|
|
||||||
|
|
||||||
## 2.1) Connecting to a server over the console
|
## 2.1) Connecting to a server over the console
|
||||||
|
|
||||||
- Open the console and type in the following command:
|
- Open the console and type `connect` for help how to connect via the console.
|
||||||
connect `<ip/host>:<port>#<company-no>`
|
|
||||||
|
|
||||||
|
|
||||||
## 3.0) Playing internet games
|
## 3.0) Playing internet games
|
||||||
|
|
||||||
- Servers with a red dot behind it have a different version then you have. You
|
- Servers with a red dot behind it have a different version then you have. You
|
||||||
will not be able to join those servers.
|
will not be able to join those servers.
|
||||||
|
|
||||||
- Servers with a yellow dot behind it have NewGRFs that you do not have. You
|
- Servers with a yellow dot behind it have NewGRFs that you do not have. You
|
||||||
will not be able to join those servers. However, via "NewGRF Settings" and
|
will not be able to join those servers. However, via "NewGRF Settings" and
|
||||||
"Find missing content online" you might be able to download the needed
|
"Find missing content online" you might be able to download the needed
|
||||||
NewGRFs after which you can join the server.
|
NewGRFs after which you can join the server.
|
||||||
|
|
||||||
- It can happen that a connection is that slow, or you have that many clients
|
- It can happen that a connection is that slow, or you have that many clients
|
||||||
connected to your server, that your clients start to loose their connection.
|
connected to your server, that your clients start to loose their connection.
|
||||||
Some things you can do about it:
|
Some things you can do about it:
|
||||||
- [network] frame_freq:
|
- `[network] frame_freq`:
|
||||||
change it in console with: 'set network.frame_freq <number>'
|
change it in console with: `set network.frame_freq <number>`
|
||||||
the number should be between the 0 and 10, not much higher. It indicates
|
the number should be between the 0 and 10, not much higher. It indicates
|
||||||
the delay between clicking and showing up. The higher, the more you notice
|
the delay between clicking and showing up. The higher, the more you notice
|
||||||
it, but the less bandwidth you use.
|
it, but the less bandwidth you use.
|
||||||
A good value for Internet-games is 2 or 3.
|
A good value for Internet-games is 2 or 3.
|
||||||
|
|
||||||
- [network] sync_freq:
|
- `[network] sync_freq`:
|
||||||
change it in console with: 'set network.sync_freq <number>'
|
change it in console with: `set network.sync_freq <number>`
|
||||||
the number should be between the 50 and 1000, not much lower, not much
|
the number should be between the 50 and 1000, not much lower, not much
|
||||||
higher. It indicates the time between sync-frames. A sync-frame is a frame
|
higher. It indicates the time between sync-frames. A sync-frame is a frame
|
||||||
which checks if all clients are still in sync. When the value it too high,
|
which checks if all clients are still in sync. When the value it too high,
|
||||||
clients can desync in 1960, but the server detects it in 1970. Not really
|
clients can desync in 1960, but the server detects it in 1970. Not really
|
||||||
handy. The lower the value, the more bandwidth it uses.
|
handy. The lower the value, the more bandwidth it uses.
|
||||||
|
|
||||||
NB: changing frame_freq has more effect on the bandwidth then sync_freq.
|
|
||||||
|
|
||||||
|
NB: changing `frame_freq` has more effect on the bandwidth then `sync_freq`.
|
||||||
|
|
||||||
## 4.0) Tips for servers
|
## 4.0) Tips for servers
|
||||||
|
|
||||||
- You can launch a dedicated server by adding -D as parameter.
|
- You can launch a dedicated server by adding `-D` as parameter.
|
||||||
- In UNIX like systems, you can fork your dedicated server by adding -f as
|
- In UNIX like systems, you can fork your dedicated server by adding `-f` as
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
- You can automatically clean companies that do not have a client connected to
|
- You can automatically clean companies that do not have a client connected to
|
||||||
them, for, let's say, 3 years. You can do this via: 'set autoclean_companies'
|
them, for, let's say, 3 years. You can do this via: `set autoclean_companies`
|
||||||
and 'set autoclean_protected' and 'set autoclean_unprotected'. Unprotected
|
and `set autoclean_protected` and `set autoclean_unprotected`. Unprotected
|
||||||
removes a password from a company when it is not used for more then the
|
removes a password from a company when it is not used for more then the
|
||||||
defined amount of months. 'set autoclean_novehicles' can be used to remove
|
defined amount of months. `set autoclean_novehicles` can be used to remove
|
||||||
companies without any vehicles quickly.
|
companies without any vehicles quickly.
|
||||||
|
|
||||||
- You can also do this manually via the console: 'reset_company'.
|
- You can also do this manually via the console: `reset_company`.
|
||||||
|
|
||||||
- You can let your server automatically restart a map when, let's say, year 2030
|
- You can let your server automatically restart a map when, let's say,
|
||||||
is reached. See 'set restart_game_date' for detail.
|
year 2030 is reached. See `set restart_game_date` for detail.
|
||||||
|
|
||||||
- If you want to be on the server-list, enable Advertising. To do this, select
|
- If you want to be on the server-list, make your server public. You can do
|
||||||
'Internet (advertise)' in the Start Server menu, or type in console:
|
this either from the Start Server window, via the in-game Online Players
|
||||||
'set server_advertise 1'.
|
window, or by typing in the console: `set server_game_type public`.
|
||||||
|
|
||||||
- You can protect your server with a password via the console: 'set server_pw',
|
- You can protect your server with a password via the console: `set server_pw`,
|
||||||
or via the Start Server menu.
|
or via the Start Server menu.
|
||||||
|
|
||||||
- When you have many clients connected to your server via Internet, watch your
|
- When you have many clients connected to your server via Internet, watch your
|
||||||
bandwidth (if you have any limit on it, set by your ISP). One client uses
|
bandwidth (if you have any limit on it, set by your ISP). One client uses
|
||||||
about 1.5 kilobytes per second up and down. To decrease this amount, setting
|
about 1.5 kilobytes per second up and down. To decrease this amount, setting
|
||||||
'frame_freq' to 1 will reduce it to roughly 1 kilobyte per second per client.
|
`frame_freq` to 1 will reduce it to roughly 1 kilobyte per second per client.
|
||||||
|
|
||||||
- OpenTTD's default settings for maximum number of clients, and amount of data
|
- OpenTTD's default settings for maximum number of clients, and amount of data
|
||||||
from clients to process are chosen to not influence the normal playing of
|
from clients to process are chosen to not influence the normal playing of
|
||||||
people, but to prevent or at least make it less likely that someone can
|
people, but to prevent or at least make it less likely that someone can
|
||||||
perform a (distributed) denial-of-service attack on your server by causing
|
perform a (distributed) denial-of-service attack on your server by causing
|
||||||
an out-of-memory event by flooding the server with data to send to all
|
an out-of-memory event by flooding the server with data to send to all
|
||||||
clients. The major factor in this is the maximum number of clients; with
|
clients. The major factor in this is the maximum number of clients; with
|
||||||
32 clients "only" sending one chat message causes 1024 messages to be
|
32 clients "only" sending one chat message causes 1024 messages to be
|
||||||
distributed in total, with 64 clients that already quadruples to 4096. Given
|
distributed in total, with 64 clients that already quadruples to 4096. Given
|
||||||
that upstream bandwidth is usually the limiting factor, a queue of packets
|
that upstream bandwidth is usually the limiting factor, a queue of packets
|
||||||
that need to be sent will be created.
|
that need to be sent will be created.
|
||||||
To prevent clients from exploiting this "explosion" of packets to send we
|
To prevent clients from exploiting this "explosion" of packets to send we
|
||||||
limit the number of incoming data, resulting in effectively limiting the
|
limit the number of incoming data, resulting in effectively limiting the
|
||||||
amount of data that OpenTTD will send to the clients. Even with the default
|
amount of data that OpenTTD will send to the clients. Even with the default
|
||||||
limits it is possible to generate about 70.000 packets per second, or about
|
limits it is possible to generate about 70.000 packets per second, or about
|
||||||
7 megabit per second of traffic.
|
7 megabit per second of traffic.
|
||||||
Given that OpenTTD kicks clients after they have not reacted within about 9
|
Given that OpenTTD kicks clients after they have not reacted within about 9
|
||||||
seconds from sending a frame update packet it would be possible that OpenTTD
|
seconds from sending a frame update packet it would be possible that OpenTTD
|
||||||
keeps about 600.000 packets in memory, using about 50 megabytes of memory.
|
keeps about 600.000 packets in memory, using about 50 megabytes of memory.
|
||||||
Given that OpenTTD allows short bursts of packets, you can have slightly
|
Given that OpenTTD allows short bursts of packets, you can have slightly
|
||||||
more packets in memory in case of a distributed denial of service attack.
|
more packets in memory in case of a distributed denial of service attack.
|
||||||
When increasing the amount of incoming data, or the maximum number of
|
When increasing the amount of incoming data, or the maximum number of
|
||||||
clients the amount of memory OpenTTD needs in case of a distributed denial
|
clients the amount of memory OpenTTD needs in case of a distributed denial
|
||||||
of service attack is linearly related to the amount of incoming data and
|
of service attack is linearly related to the amount of incoming data and
|
||||||
quadratic to the amount of clients. In short, a rule of thumb for, the
|
quadratic to the amount of clients. In short, a rule of thumb for, the
|
||||||
maximum memory usage for packets is:
|
maximum memory usage for packets is:
|
||||||
#max_clients * #max_clients * bytes_per_frame * 10 KiB.
|
`#max_clients * #max_clients * bytes_per_frame * 10 KiB`.
|
||||||
|
|
||||||
### 4.1) Imposing landscaping limits
|
### 4.1) Imposing landscaping limits
|
||||||
|
|
||||||
- You can impose limits on companies by the following 4 settings:
|
- You can impose limits on companies by the following 4 settings:
|
||||||
- terraform_per_64k_frames
|
- `terraform_per_64k_frames`
|
||||||
- terraform_frame_burst
|
- `terraform_frame_burst`
|
||||||
- clear_per_64k_frames
|
- `clear_per_64k_frames`
|
||||||
- clear_frame_burst
|
- `clear_frame_burst`
|
||||||
|
|
||||||
- Explaining 'per_64K_frames' and 'burst'
|
- Explaining `NNN_burst` and `NNN_per_64K_frames`
|
||||||
- 'burst' defines 3 things, the maximum limit, the limit of a single action,
|
- `NNN_burst` defines 3 things, the maximum limit, the limit of a single
|
||||||
and the initial value for the limit assigned to a new company.
|
action, and the initial value for the limit assigned to a new company.
|
||||||
This setting is fairly simple and requires no math.
|
This setting is fairly simple and requires no math.
|
||||||
|
|
||||||
A value of 1 means a single tile can be affected by a single action.
|
A value of 1 means a single tile can be affected by a single action.
|
||||||
This results in having to click 400 times when wanting to cover an area
|
This results in having to click 400 times when wanting to cover an area
|
||||||
of 20 x 20 tiles.
|
of 20 x 20 tiles.
|
||||||
|
|
||||||
The default value 4096 covers an area of 64 x 64 tiles.
|
The default value 4096 covers an area of 64 x 64 tiles.
|
||||||
|
|
||||||
- 'per_64k_frames' defines the number of tiles added to each companies limit
|
- `NNN_per_64K_frames` defines the number of tiles added to each companies
|
||||||
per frame (however not past the possible maximum value,the 'burst').
|
limit per frame (however not past the possible maximum value,the
|
||||||
64k rather resembles the exact number of 65536 frames. So setting this
|
`NNN_burst`). 64k rather resembles the exact number of 65536 frames. So
|
||||||
variable to 65536 means: 65536 / 65536 = 1 tile per frame.
|
setting this variable to 65536 means: `65536 / 65536 = 1 tile per frame`.
|
||||||
As a day consists of 74 frames, a company's limit is increased by 74
|
|
||||||
tiles during the course of a single day (2.22 seconds).
|
|
||||||
|
|
||||||
To achieve a 1 tile per day increase the following calculation is needed:
|
As a day consists of 74 frames, a company's limit is increased by 74
|
||||||
1 / 74 (frames per day) * 65536 (per_64k_frames) = 885.62...
|
tiles during the course of a single day (2.22 seconds).
|
||||||
after rounding: a value of 886 means adding a bit over 1 tile per day.
|
To achieve a 1 tile per day increase the following calculation is needed:
|
||||||
|
`1 / 74 (frames per day) * 65536 (per_64k_frames) = 885.62...`.
|
||||||
|
After rounding: a value of 886 means adding a bit over 1 tile per day.
|
||||||
|
|
||||||
There is still enough space to scale this value downwards:
|
There is still enough space to scale this value downwards:
|
||||||
decreasing this value to 127 results in a bit over 1 tile added to the
|
decreasing this value to 127 results in a bit over 1 tile added to the
|
||||||
allowance per week (7 days).
|
allowance per week (7 days).
|
||||||
|
|
||||||
To create a setup in which a company gets an initial allowance only,
|
To create a setup in which a company gets an initial allowance only,
|
||||||
set the value to 0 - no increase of the allowance per frame.
|
set the value to 0 - no increase of the allowance per frame.
|
||||||
|
|
||||||
- Even though construction actions include a clear tile action, they are not
|
|
||||||
affected by the above settings.
|
|
||||||
|
|
||||||
|
- Even though construction actions include a clear tile action, they are not
|
||||||
|
affected by the above settings.
|
||||||
|
|
||||||
## 5.0) Some useful things
|
## 5.0) Some useful things
|
||||||
|
|
||||||
- You can protect your company so nobody else can join uninvited. To do this,
|
- You can protect your company so nobody else can join uninvited. To do this,
|
||||||
set a password in your Company Screen
|
set a password in your Company window.
|
||||||
|
|
||||||
- You can give other players some money via the ClientList (under the 'head'
|
- You can chat with other players via ENTER or via SHIFT+T or via the Online
|
||||||
in the mainbar).
|
Players window
|
||||||
|
|
||||||
- You can chat with other players via ENTER or via SHIFT+T or via the ClientList
|
|
||||||
|
|
||||||
- Servers can now kick players, so don't make them use it!
|
|
||||||
|
|
||||||
|
- Servers can kick players, so don't make them use it!
|
||||||
|
|
||||||
## 6.0) Troubleshooting
|
## 6.0) Troubleshooting
|
||||||
|
|
||||||
- My advertising server does not show up in list at servers.openttd.org
|
### My server does not show up in the serverlist
|
||||||
Run openttd with the '-d net=2' parameter. That will show which incoming
|
|
||||||
communication is received, whether the replies from the master server or
|
|
||||||
communication from an admin tool reach the programme. See section 1
|
|
||||||
'Starting a server' further up for the ports and protocols used by OpenTTD.
|
|
||||||
The ports can be configured in the config file.
|
|
||||||
|
|
||||||
- My advertising server warns a lot about getaddrinfo taking N seconds
|
Check if the visibility of your server is set to `public`.
|
||||||
This could be a transient issue with your (local) DNS server, but if the
|
|
||||||
problem persists there is likely a configuration issue in DNS resolving
|
If it is, and your server still isn't showing up, start OpenTTD with
|
||||||
on your computer. This seems to be a common configuration issue for
|
`-d net=4` as extra argument. This will show debug message related to the
|
||||||
Docker instances, where the DNS resolving waits for a time out of usually
|
network, including communication to/from the Game Coordinator.
|
||||||
5 seconds.
|
|
||||||
|
### My server warns a lot about getaddrinfo taking N seconds
|
||||||
|
|
||||||
|
This could be a transient issue with your (local) DNS server, but if the
|
||||||
|
problem persists there is likely a configuration issue in DNS resolving on
|
||||||
|
your computer.
|
||||||
|
|
||||||
|
#### Running OpenTTD in a Docker container?
|
||||||
|
|
||||||
|
This is an issue with dual-stack Docker containers. If there is no default
|
||||||
|
IPv6 resolver and IPv6 traffic is preferred, DNS requests will time out after
|
||||||
|
5 seconds. To resolve this, use an IPv4 DNS server for your Docker container,
|
||||||
|
for example by adding `--dns 1.1.1.1` to your `docker run` command.
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
OpenTTD's known bugs
|
OpenTTD's known bugs
|
||||||
Last updated: 2021-02-28
|
|
||||||
Release version: 1.11.0-beta2
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
BIN
media/openttd.1024.png
Normal file
BIN
media/openttd.1024.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
BIN
media/openttd.2048.png
Normal file
BIN
media/openttd.2048.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 148 KiB |
BIN
media/openttd.512.png
Normal file
BIN
media/openttd.512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
@@ -1,4 +1,4 @@
|
|||||||
FROM emscripten/emsdk:2.0.10
|
FROM emscripten/emsdk:2.0.31
|
||||||
|
|
||||||
COPY emsdk-liblzma.patch /
|
COPY emsdk-liblzma.patch /
|
||||||
RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch
|
RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## How to build with Emscripten
|
## How to build with Emscripten
|
||||||
|
|
||||||
Building with Emscripten works with emsdk 2.0.10 and above.
|
Building with Emscripten works with emsdk 2.0.31 and above.
|
||||||
|
|
||||||
Currently there is no LibLZMA support upstream; for this we suggest to apply
|
Currently there is no LibLZMA support upstream; for this we suggest to apply
|
||||||
the provided patch in this folder to your emsdk installation.
|
the provided patch in this folder to your emsdk installation.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# LibLZMA is a recent addition to the emscripten SDK, so it is possible
|
# LibLZMA is a recent addition to the emscripten SDK, so it is possible
|
||||||
# someone hasn't updated his SDK yet. Test out if the SDK supports LibLZMA.
|
# someone hasn't updated their SDK yet. Test out if the SDK supports LibLZMA.
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
set(CMAKE_REQUIRED_FLAGS "-sUSE_LIBLZMA=1")
|
set(CMAKE_REQUIRED_FLAGS "-sUSE_LIBLZMA=1")
|
||||||
|
|
||||||
|
@@ -10,44 +10,35 @@ Modifed by OpenTTD to have the bare minimum needed to work. Otherwise there
|
|||||||
are constantly conflicts when trying to apply this patch to different versions
|
are constantly conflicts when trying to apply this patch to different versions
|
||||||
of emsdk.
|
of emsdk.
|
||||||
|
|
||||||
diff --git a/embuilder.py b/embuilder.py
|
diff --git a/tools/settings.py b/tools/settings.py
|
||||||
index 818262190ed..ab7d5adb7b2 100755
|
--- a/tools/settings.py
|
||||||
--- a/embuilder.py
|
+++ b/tools/settings.py
|
||||||
+++ b/embuilder.py
|
@@ -38,6 +38,7 @@
|
||||||
@@ -60,6 +60,7 @@
|
'USE_SDL_NET',
|
||||||
'harfbuzz',
|
'USE_SDL_GFX',
|
||||||
'icu',
|
'USE_LIBJPEG',
|
||||||
'libjpeg',
|
+ 'USE_LIBLZMA',
|
||||||
+ 'liblzma',
|
'USE_OGG',
|
||||||
'libpng',
|
'USE_REGAL',
|
||||||
'ogg',
|
'USE_BOOST_HEADERS',
|
||||||
'regal',
|
|
||||||
@@ -197,6 +198,8 @@ def main():
|
|
||||||
build_port('ogg', libname('libogg'))
|
|
||||||
elif what == 'libjpeg':
|
|
||||||
build_port('libjpeg', libname('libjpeg'))
|
|
||||||
+ elif what == 'liblzma':
|
|
||||||
+ build_port('liblzma', libname('liblzma'))
|
|
||||||
elif what == 'libpng':
|
|
||||||
build_port('libpng', libname('libpng'))
|
|
||||||
elif what == 'sdl2':
|
|
||||||
diff --git a/src/settings.js b/src/settings.js
|
diff --git a/src/settings.js b/src/settings.js
|
||||||
index 61cd98939ba..be6fcb678c6 100644
|
|
||||||
--- a/src/settings.js
|
--- a/src/settings.js
|
||||||
+++ b/src/settings.js
|
+++ b/src/settings.js
|
||||||
@@ -1197,6 +1197,9 @@ var USE_BZIP2 = 0;
|
@@ -1382,8 +1382,12 @@ var USE_BZIP2 = 0;
|
||||||
// 1 = use libjpeg from emscripten-ports
|
// 1 = use libjpeg from emscripten-ports
|
||||||
|
// [link]
|
||||||
var USE_LIBJPEG = 0;
|
var USE_LIBJPEG = 0;
|
||||||
|
|
||||||
+// 1 = use liblzma from emscripten-ports
|
+// 1 = use liblzma from emscripten-ports
|
||||||
|
+// [link]
|
||||||
+var USE_LIBLZMA = 0;
|
+var USE_LIBLZMA = 0;
|
||||||
+
|
+
|
||||||
// 1 = use libpng from emscripten-ports
|
// 1 = use libpng from emscripten-ports
|
||||||
|
// [link]
|
||||||
var USE_LIBPNG = 0;
|
var USE_LIBPNG = 0;
|
||||||
|
|
||||||
diff --git a/tools/ports/liblzma.py b/tools/ports/liblzma.py
|
diff --git a/tools/ports/liblzma.py b/tools/ports/liblzma.py
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 00000000000..e9567ef36ff
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/tools/ports/liblzma.py
|
+++ b/tools/ports/liblzma.py
|
||||||
@@ -0,0 +1,160 @@
|
@@ -0,0 +1,160 @@
|
||||||
@@ -58,6 +49,8 @@ index 00000000000..e9567ef36ff
|
|||||||
+
|
+
|
||||||
+import os
|
+import os
|
||||||
+import shutil
|
+import shutil
|
||||||
|
+import logging
|
||||||
|
+from pathlib import Path
|
||||||
+
|
+
|
||||||
+VERSION = '5.2.5'
|
+VERSION = '5.2.5'
|
||||||
+HASH = '7443674247deda2935220fbc4dfc7665e5bb5a260be8ad858c8bd7d7b9f0f868f04ea45e62eb17c0a5e6a2de7c7500ad2d201e2d668c48ca29bd9eea5a73a3ce'
|
+HASH = '7443674247deda2935220fbc4dfc7665e5bb5a260be8ad858c8bd7d7b9f0f868f04ea45e62eb17c0a5e6a2de7c7500ad2d201e2d668c48ca29bd9eea5a73a3ce'
|
||||||
@@ -68,10 +61,11 @@ index 00000000000..e9567ef36ff
|
|||||||
+
|
+
|
||||||
+
|
+
|
||||||
+def get(ports, settings, shared):
|
+def get(ports, settings, shared):
|
||||||
+ libname = ports.get_lib_name('liblzma')
|
|
||||||
+ ports.fetch_project('liblzma', 'https://tukaani.org/xz/xz-' + VERSION + '.tar.gz', 'xz-' + VERSION, sha512hash=HASH)
|
+ ports.fetch_project('liblzma', 'https://tukaani.org/xz/xz-' + VERSION + '.tar.gz', 'xz-' + VERSION, sha512hash=HASH)
|
||||||
+
|
+
|
||||||
+ def create():
|
+ def create(final):
|
||||||
|
+ logging.info('building port: liblzma')
|
||||||
|
+
|
||||||
+ ports.clear_project_build('liblzma')
|
+ ports.clear_project_build('liblzma')
|
||||||
+
|
+
|
||||||
+ source_path = os.path.join(ports.get_dir(), 'liblzma', 'xz-' + VERSION)
|
+ source_path = os.path.join(ports.get_dir(), 'liblzma', 'xz-' + VERSION)
|
||||||
@@ -88,22 +82,19 @@ index 00000000000..e9567ef36ff
|
|||||||
+ 'tuklib_exit.c', 'tuklib_mbstr_fw.c', 'tuklib_mbstr_width.c', 'tuklib_open_stdxxx.c', 'tuklib_progname.c']
|
+ 'tuklib_exit.c', 'tuklib_mbstr_fw.c', 'tuklib_mbstr_width.c', 'tuklib_open_stdxxx.c', 'tuklib_progname.c']
|
||||||
+ include_dirs_rel = ['../common', 'api', 'common', 'check', 'lz', 'rangecoder', 'lzma', 'delta', 'simple']
|
+ include_dirs_rel = ['../common', 'api', 'common', 'check', 'lz', 'rangecoder', 'lzma', 'delta', 'simple']
|
||||||
+
|
+
|
||||||
+ open(os.path.join(dest_path, 'src', 'config.h'), 'w').write(config_h)
|
+ Path(dest_path, os.path.join('src', 'config.h')).write_text(config_h)
|
||||||
+
|
+
|
||||||
+ final = os.path.join(dest_path, libname)
|
|
||||||
+ include_dirs = [os.path.join(dest_path, 'src', 'liblzma', p) for p in include_dirs_rel]
|
+ include_dirs = [os.path.join(dest_path, 'src', 'liblzma', p) for p in include_dirs_rel]
|
||||||
+ ports.build_port(os.path.join(dest_path, 'src'), final, flags=build_flags, exclude_dirs=exclude_dirs, exclude_files=exclude_files, includes=include_dirs)
|
+ ports.build_port(os.path.join(dest_path, 'src'), final, flags=build_flags, exclude_dirs=exclude_dirs, exclude_files=exclude_files, includes=include_dirs)
|
||||||
+
|
+
|
||||||
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api'), 'lzma.h')
|
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api'), 'lzma.h')
|
||||||
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api', 'lzma'), '*.h', 'lzma')
|
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api', 'lzma'), '*.h', 'lzma')
|
||||||
+
|
+
|
||||||
+ return final
|
+ return [shared.Cache.get_lib('liblzma.a', create, what='port')]
|
||||||
+
|
|
||||||
+ return [shared.Cache.get(libname, create, what='port')]
|
|
||||||
+
|
+
|
||||||
+
|
+
|
||||||
+def clear(ports, settings, shared):
|
+def clear(ports, settings, shared):
|
||||||
+ shared.Cache.erase_file(ports.get_lib_name('liblzma'))
|
+ shared.Cache.erase_lib('liblzma.a')
|
||||||
+
|
+
|
||||||
+
|
+
|
||||||
+def process_args(ports):
|
+def process_args(ports):
|
||||||
|
@@ -9,7 +9,15 @@ Module['websocket'] = { url: function(host, port, proto) {
|
|||||||
* If you run your own server you can setup your own WebSocket proxy in
|
* If you run your own server you can setup your own WebSocket proxy in
|
||||||
* front of it and let people connect to your server via the proxy. You
|
* front of it and let people connect to your server via the proxy. You
|
||||||
* are best to add another "if" statement as above for this. */
|
* are best to add another "if" statement as above for this. */
|
||||||
return null;
|
|
||||||
|
if (location.protocol === 'https:') {
|
||||||
|
/* Insecure WebSockets do not work over HTTPS, so we force
|
||||||
|
* secure ones. */
|
||||||
|
return 'wss://';
|
||||||
|
} else {
|
||||||
|
/* Use the default provided by Emscripten. */
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} };
|
} };
|
||||||
|
|
||||||
Module.preRun.push(function() {
|
Module.preRun.push(function() {
|
||||||
@@ -65,10 +73,14 @@ Module.preRun.push(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.openttd_server_list = function() {
|
window.openttd_server_list = function() {
|
||||||
add_server = Module.cwrap("em_openttd_add_server", null, ["string", "number"]);
|
add_server = Module.cwrap("em_openttd_add_server", null, ["string"]);
|
||||||
|
|
||||||
/* Add servers that support WebSocket here. Example:
|
/* Add servers that support WebSocket here. Examples:
|
||||||
* add_server("localhost", 3979); */
|
* add_server("localhost");
|
||||||
|
* add_server("localhost:3979");
|
||||||
|
* add_server("127.0.0.1:3979");
|
||||||
|
* add_server("[::1]:3979");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
var leftButtonDown = false;
|
var leftButtonDown = false;
|
||||||
|
@@ -85,6 +85,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
/* OpenTTD draws the cursor itself */
|
||||||
|
cursor: none !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
18
os/windows/sign.bat
Normal file
18
os/windows/sign.bat
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
@echo off
|
||||||
|
REM Signing script
|
||||||
|
REM Arguments: sign.bat exe_to_sign certificate_subject_name
|
||||||
|
|
||||||
|
REM This is a loose wrapper around the Microsoft signtool application (included in the Windows SDK).
|
||||||
|
REM See https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe for more details.
|
||||||
|
|
||||||
|
REM Path to signtool.exe
|
||||||
|
IF NOT DEFINED SIGNTOOL_PATH (SET SIGNTOOL_PATH=signtool)
|
||||||
|
|
||||||
|
REM URL of the timestamp server
|
||||||
|
IF NOT DEFINED SIGNTOOL_TIMESTAMP_URL (SET SIGNTOOL_TIMESTAMP_URL=http://timestamp.digicert.com)
|
||||||
|
|
||||||
|
REM Sign with SHA-1 for Windows 7 and below
|
||||||
|
"%SIGNTOOL_PATH%" sign -v -n %2 -t %SIGNTOOL_TIMESTAMP_URL% %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
|
@@ -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 "1.12"; }
|
function GetAPIVersion() { return "13"; }
|
||||||
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; }
|
||||||
|
@@ -547,6 +547,8 @@ function Regression::Prices()
|
|||||||
print(" BT_DOCK: " + AIMarine.GetBuildCost(AIMarine.BT_DOCK));
|
print(" BT_DOCK: " + AIMarine.GetBuildCost(AIMarine.BT_DOCK));
|
||||||
print(" BT_DEPOT: " + AIMarine.GetBuildCost(AIMarine.BT_DEPOT));
|
print(" BT_DEPOT: " + AIMarine.GetBuildCost(AIMarine.BT_DEPOT));
|
||||||
print(" BT_BUOY: " + AIMarine.GetBuildCost(AIMarine.BT_BUOY));
|
print(" BT_BUOY: " + AIMarine.GetBuildCost(AIMarine.BT_BUOY));
|
||||||
|
print(" BT_LOCK: " + AIMarine.GetBuildCost(AIMarine.BT_LOCK));
|
||||||
|
print(" BT_CANAL: " + AIMarine.GetBuildCost(AIMarine.BT_CANAL));
|
||||||
print(" -Tile-");
|
print(" -Tile-");
|
||||||
print(" BT_FOUNDATION: " + AITile.GetBuildCost(AITile.BT_FOUNDATION));
|
print(" BT_FOUNDATION: " + AITile.GetBuildCost(AITile.BT_FOUNDATION));
|
||||||
print(" BT_TERRAFORM: " + AITile.GetBuildCost(AITile.BT_TERRAFORM));
|
print(" BT_TERRAFORM: " + AITile.GetBuildCost(AITile.BT_TERRAFORM));
|
||||||
@@ -556,6 +558,7 @@ function Regression::Prices()
|
|||||||
print(" BT_CLEAR_ROCKY: " + AITile.GetBuildCost(AITile.BT_CLEAR_ROCKY));
|
print(" BT_CLEAR_ROCKY: " + AITile.GetBuildCost(AITile.BT_CLEAR_ROCKY));
|
||||||
print(" BT_CLEAR_FIELDS: " + AITile.GetBuildCost(AITile.BT_CLEAR_FIELDS));
|
print(" BT_CLEAR_FIELDS: " + AITile.GetBuildCost(AITile.BT_CLEAR_FIELDS));
|
||||||
print(" BT_CLEAR_HOUSE: " + AITile.GetBuildCost(AITile.BT_CLEAR_HOUSE));
|
print(" BT_CLEAR_HOUSE: " + AITile.GetBuildCost(AITile.BT_CLEAR_HOUSE));
|
||||||
|
print(" BT_CLEAR_WATER: " + AITile.GetBuildCost(AITile.BT_CLEAR_WATER));
|
||||||
}
|
}
|
||||||
|
|
||||||
function cost_callback(old_path, new_tile, new_direction, self) { if (old_path == null) return 0; return old_path.GetCost() + 1; }
|
function cost_callback(old_path, new_tile, new_direction, self) { if (old_path == null) return 0; return old_path.GetCost() + 1; }
|
||||||
@@ -919,6 +922,9 @@ function Regression::Marine()
|
|||||||
|
|
||||||
print(" BuildWaterDepot(): " + AIMarine.BuildWaterDepot(28479, 28480));
|
print(" BuildWaterDepot(): " + AIMarine.BuildWaterDepot(28479, 28480));
|
||||||
print(" BuildDock(): " + AIMarine.BuildDock(29253, AIStation.STATION_JOIN_ADJACENT));
|
print(" BuildDock(): " + AIMarine.BuildDock(29253, AIStation.STATION_JOIN_ADJACENT));
|
||||||
|
print(" BuildBuoy(): " + AIMarine.BuildBuoy(28481));
|
||||||
|
print(" BuildLock(): " + AIMarine.BuildLock(28487));
|
||||||
|
print(" BuildCanal(): " + AIMarine.BuildCanal(28744));
|
||||||
}
|
}
|
||||||
|
|
||||||
function Regression::Order()
|
function Regression::Order()
|
||||||
@@ -1470,9 +1476,41 @@ function Regression::TileList()
|
|||||||
print(" " + i + " => " + list.GetValue(i));
|
print(" " + i + " => " + list.GetValue(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
list.AddRectangle(54421 - 256 * 2, 256 * 2 + 54421 + 8);
|
list.AddRectangle(0x6F3F, 0x7248);
|
||||||
list.Valuate(AITile.IsWaterTile);
|
list.Valuate(AITile.IsWaterTile);
|
||||||
print(" Water(): done");
|
print(" IsWaterTile(): done");
|
||||||
|
print(" Count(): " + list.Count());
|
||||||
|
print(" ListDump:");
|
||||||
|
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
||||||
|
print(" " + i + " => " + list.GetValue(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Valuate(AITile.IsSeaTile);
|
||||||
|
print(" IsSeaTile(): done");
|
||||||
|
print(" Count(): " + list.Count());
|
||||||
|
print(" ListDump:");
|
||||||
|
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
||||||
|
print(" " + i + " => " + list.GetValue(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Valuate(AITile.IsRiverTile);
|
||||||
|
print(" IsRiverTile() done");
|
||||||
|
print(" Count(): " + list.Count());
|
||||||
|
print(" ListDump:");
|
||||||
|
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
||||||
|
print(" " + i + " => " + list.GetValue(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Valuate(AIMarine.IsCanalTile);
|
||||||
|
print(" IsCanalTile() done");
|
||||||
|
print(" Count(): " + list.Count());
|
||||||
|
print(" ListDump:");
|
||||||
|
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
||||||
|
print(" " + i + " => " + list.GetValue(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Valuate(AITile.IsCoastTile);
|
||||||
|
print(" IsCoastTile() done");
|
||||||
print(" Count(): " + list.Count());
|
print(" Count(): " + list.Count());
|
||||||
print(" ListDump:");
|
print(" ListDump:");
|
||||||
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
for (local i = list.Begin(); !list.IsEnd(); i = list.Next()) {
|
||||||
|
@@ -7365,6 +7365,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
GetBankBalance(): 1999959285
|
GetBankBalance(): 1999959285
|
||||||
BuildWaterDepot(): true
|
BuildWaterDepot(): true
|
||||||
BuildDock(): true
|
BuildDock(): true
|
||||||
|
BuildBuoy(): true
|
||||||
|
BuildLock(): true
|
||||||
|
BuildCanal(): true
|
||||||
|
|
||||||
--Prices--
|
--Prices--
|
||||||
-Rail-
|
-Rail-
|
||||||
@@ -7391,6 +7394,8 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
BT_DOCK: 262
|
BT_DOCK: 262
|
||||||
BT_DEPOT: 525
|
BT_DEPOT: 525
|
||||||
BT_BUOY: 262
|
BT_BUOY: 262
|
||||||
|
BT_LOCK: 5625
|
||||||
|
BT_CANAL: 3750
|
||||||
-Tile-
|
-Tile-
|
||||||
BT_FOUNDATION: 187
|
BT_FOUNDATION: 187
|
||||||
BT_TERRAFORM: 187
|
BT_TERRAFORM: 187
|
||||||
@@ -7400,6 +7405,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
BT_CLEAR_ROCKY: 150
|
BT_CLEAR_ROCKY: 150
|
||||||
BT_CLEAR_FIELDS: 375
|
BT_CLEAR_FIELDS: 375
|
||||||
BT_CLEAR_HOUSE: 1200
|
BT_CLEAR_HOUSE: 1200
|
||||||
|
BT_CLEAR_WATER: 7500
|
||||||
|
|
||||||
--Rail--
|
--Rail--
|
||||||
IsRailTile(): false
|
IsRailTile(): false
|
||||||
@@ -8450,54 +8456,221 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
KeepValue(1): done
|
KeepValue(1): done
|
||||||
Count(): 0
|
Count(): 0
|
||||||
ListDump:
|
ListDump:
|
||||||
Water(): done
|
IsWaterTile(): done
|
||||||
Count(): 45
|
Count(): 40
|
||||||
ListDump:
|
ListDump:
|
||||||
54941 => 1
|
29251 => 1
|
||||||
54940 => 1
|
29250 => 1
|
||||||
54939 => 1
|
29249 => 1
|
||||||
54938 => 1
|
29248 => 1
|
||||||
54937 => 1
|
29247 => 1
|
||||||
54936 => 1
|
28996 => 1
|
||||||
54935 => 1
|
28995 => 1
|
||||||
54934 => 1
|
28994 => 1
|
||||||
54933 => 1
|
28993 => 1
|
||||||
54685 => 1
|
28992 => 1
|
||||||
54684 => 1
|
28991 => 1
|
||||||
54683 => 1
|
28744 => 1
|
||||||
54682 => 1
|
28741 => 1
|
||||||
54681 => 1
|
28740 => 1
|
||||||
54680 => 1
|
28739 => 1
|
||||||
54679 => 1
|
28738 => 1
|
||||||
54678 => 1
|
28737 => 1
|
||||||
54677 => 1
|
28736 => 1
|
||||||
54429 => 1
|
28735 => 1
|
||||||
54428 => 1
|
28488 => 1
|
||||||
54427 => 1
|
28487 => 1
|
||||||
54426 => 1
|
28486 => 1
|
||||||
54425 => 1
|
28485 => 1
|
||||||
54424 => 1
|
28484 => 1
|
||||||
54423 => 1
|
28483 => 1
|
||||||
54422 => 1
|
28482 => 1
|
||||||
54421 => 1
|
28480 => 1
|
||||||
54173 => 1
|
28479 => 1
|
||||||
54172 => 1
|
29256 => 0
|
||||||
54171 => 1
|
29255 => 0
|
||||||
54170 => 1
|
29254 => 0
|
||||||
54169 => 1
|
29253 => 0
|
||||||
54168 => 0
|
29252 => 0
|
||||||
54167 => 0
|
29000 => 0
|
||||||
54166 => 0
|
28999 => 0
|
||||||
54165 => 0
|
28998 => 0
|
||||||
53917 => 0
|
28997 => 0
|
||||||
53916 => 0
|
28743 => 0
|
||||||
53915 => 0
|
28742 => 0
|
||||||
53914 => 0
|
28481 => 0
|
||||||
53913 => 0
|
IsSeaTile(): done
|
||||||
53912 => 0
|
Count(): 40
|
||||||
53911 => 0
|
ListDump:
|
||||||
53910 => 0
|
29251 => 1
|
||||||
53909 => 0
|
29250 => 1
|
||||||
|
29249 => 1
|
||||||
|
29248 => 1
|
||||||
|
29247 => 1
|
||||||
|
28996 => 1
|
||||||
|
28995 => 1
|
||||||
|
28994 => 1
|
||||||
|
28993 => 1
|
||||||
|
28992 => 1
|
||||||
|
28991 => 1
|
||||||
|
28741 => 1
|
||||||
|
28740 => 1
|
||||||
|
28739 => 1
|
||||||
|
28738 => 1
|
||||||
|
28737 => 1
|
||||||
|
28736 => 1
|
||||||
|
28735 => 1
|
||||||
|
28485 => 1
|
||||||
|
28484 => 1
|
||||||
|
28483 => 1
|
||||||
|
28482 => 1
|
||||||
|
29256 => 0
|
||||||
|
29255 => 0
|
||||||
|
29254 => 0
|
||||||
|
29253 => 0
|
||||||
|
29252 => 0
|
||||||
|
29000 => 0
|
||||||
|
28999 => 0
|
||||||
|
28998 => 0
|
||||||
|
28997 => 0
|
||||||
|
28744 => 0
|
||||||
|
28743 => 0
|
||||||
|
28742 => 0
|
||||||
|
28488 => 0
|
||||||
|
28487 => 0
|
||||||
|
28486 => 0
|
||||||
|
28481 => 0
|
||||||
|
28480 => 0
|
||||||
|
28479 => 0
|
||||||
|
IsRiverTile() done
|
||||||
|
Count(): 40
|
||||||
|
ListDump:
|
||||||
|
29256 => 0
|
||||||
|
29255 => 0
|
||||||
|
29254 => 0
|
||||||
|
29253 => 0
|
||||||
|
29252 => 0
|
||||||
|
29251 => 0
|
||||||
|
29250 => 0
|
||||||
|
29249 => 0
|
||||||
|
29248 => 0
|
||||||
|
29247 => 0
|
||||||
|
29000 => 0
|
||||||
|
28999 => 0
|
||||||
|
28998 => 0
|
||||||
|
28997 => 0
|
||||||
|
28996 => 0
|
||||||
|
28995 => 0
|
||||||
|
28994 => 0
|
||||||
|
28993 => 0
|
||||||
|
28992 => 0
|
||||||
|
28991 => 0
|
||||||
|
28744 => 0
|
||||||
|
28743 => 0
|
||||||
|
28742 => 0
|
||||||
|
28741 => 0
|
||||||
|
28740 => 0
|
||||||
|
28739 => 0
|
||||||
|
28738 => 0
|
||||||
|
28737 => 0
|
||||||
|
28736 => 0
|
||||||
|
28735 => 0
|
||||||
|
28488 => 0
|
||||||
|
28487 => 0
|
||||||
|
28486 => 0
|
||||||
|
28485 => 0
|
||||||
|
28484 => 0
|
||||||
|
28483 => 0
|
||||||
|
28482 => 0
|
||||||
|
28481 => 0
|
||||||
|
28480 => 0
|
||||||
|
28479 => 0
|
||||||
|
IsCanalTile() done
|
||||||
|
Count(): 40
|
||||||
|
ListDump:
|
||||||
|
28744 => 1
|
||||||
|
29256 => 0
|
||||||
|
29255 => 0
|
||||||
|
29254 => 0
|
||||||
|
29253 => 0
|
||||||
|
29252 => 0
|
||||||
|
29251 => 0
|
||||||
|
29250 => 0
|
||||||
|
29249 => 0
|
||||||
|
29248 => 0
|
||||||
|
29247 => 0
|
||||||
|
29000 => 0
|
||||||
|
28999 => 0
|
||||||
|
28998 => 0
|
||||||
|
28997 => 0
|
||||||
|
28996 => 0
|
||||||
|
28995 => 0
|
||||||
|
28994 => 0
|
||||||
|
28993 => 0
|
||||||
|
28992 => 0
|
||||||
|
28991 => 0
|
||||||
|
28743 => 0
|
||||||
|
28742 => 0
|
||||||
|
28741 => 0
|
||||||
|
28740 => 0
|
||||||
|
28739 => 0
|
||||||
|
28738 => 0
|
||||||
|
28737 => 0
|
||||||
|
28736 => 0
|
||||||
|
28735 => 0
|
||||||
|
28488 => 0
|
||||||
|
28487 => 0
|
||||||
|
28486 => 0
|
||||||
|
28485 => 0
|
||||||
|
28484 => 0
|
||||||
|
28483 => 0
|
||||||
|
28482 => 0
|
||||||
|
28481 => 0
|
||||||
|
28480 => 0
|
||||||
|
28479 => 0
|
||||||
|
IsCoastTile() done
|
||||||
|
Count(): 40
|
||||||
|
ListDump:
|
||||||
|
28998 => 1
|
||||||
|
28997 => 1
|
||||||
|
28743 => 1
|
||||||
|
28742 => 1
|
||||||
|
29256 => 0
|
||||||
|
29255 => 0
|
||||||
|
29254 => 0
|
||||||
|
29253 => 0
|
||||||
|
29252 => 0
|
||||||
|
29251 => 0
|
||||||
|
29250 => 0
|
||||||
|
29249 => 0
|
||||||
|
29248 => 0
|
||||||
|
29247 => 0
|
||||||
|
29000 => 0
|
||||||
|
28999 => 0
|
||||||
|
28996 => 0
|
||||||
|
28995 => 0
|
||||||
|
28994 => 0
|
||||||
|
28993 => 0
|
||||||
|
28992 => 0
|
||||||
|
28991 => 0
|
||||||
|
28744 => 0
|
||||||
|
28741 => 0
|
||||||
|
28740 => 0
|
||||||
|
28739 => 0
|
||||||
|
28738 => 0
|
||||||
|
28737 => 0
|
||||||
|
28736 => 0
|
||||||
|
28735 => 0
|
||||||
|
28488 => 0
|
||||||
|
28487 => 0
|
||||||
|
28486 => 0
|
||||||
|
28485 => 0
|
||||||
|
28484 => 0
|
||||||
|
28483 => 0
|
||||||
|
28482 => 0
|
||||||
|
28481 => 0
|
||||||
|
28480 => 0
|
||||||
|
28479 => 0
|
||||||
|
|
||||||
--TileList_IndustryAccepting--
|
--TileList_IndustryAccepting--
|
||||||
Count(): 47
|
Count(): 47
|
||||||
@@ -9099,12 +9272,12 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
GetLocation(): 33417
|
GetLocation(): 33417
|
||||||
GetEngineType(): 153
|
GetEngineType(): 153
|
||||||
GetUnitNumber(): 1
|
GetUnitNumber(): 1
|
||||||
GetAge(): 0
|
GetAge(): 1
|
||||||
GetMaxAge(): 5490
|
GetMaxAge(): 5490
|
||||||
GetAgeLeft(): 5490
|
GetAgeLeft(): 5489
|
||||||
GetCurrentSpeed(): 7
|
GetCurrentSpeed(): 7
|
||||||
GetRunningCost(): 421
|
GetRunningCost(): 421
|
||||||
GetProfitThisYear(): 0
|
GetProfitThisYear(): -1
|
||||||
GetProfitLastYear(): 0
|
GetProfitLastYear(): 0
|
||||||
GetCurrentValue(): 5947
|
GetCurrentValue(): 5947
|
||||||
GetVehicleType(): 1
|
GetVehicleType(): 1
|
||||||
@@ -9114,7 +9287,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
IsInDepot(): false
|
IsInDepot(): false
|
||||||
GetNumWagons(): 1
|
GetNumWagons(): 1
|
||||||
GetWagonEngineType(): 153
|
GetWagonEngineType(): 153
|
||||||
GetWagonAge(): 0
|
GetWagonAge(): 1
|
||||||
GetLength(): 8
|
GetLength(): 8
|
||||||
GetOwner(): 1
|
GetOwner(): 1
|
||||||
BuildVehicle(): 14
|
BuildVehicle(): 14
|
||||||
@@ -9139,9 +9312,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
GetNumWagons(): 3
|
GetNumWagons(): 3
|
||||||
GetLength(): 24
|
GetLength(): 24
|
||||||
GetWagonEngineType(): 9
|
GetWagonEngineType(): 9
|
||||||
GetWagonAge(): 1
|
GetWagonAge(): 0
|
||||||
GetWagonEngineType(): 27
|
GetWagonEngineType(): 27
|
||||||
GetWagonAge(): 1
|
GetWagonAge(): 0
|
||||||
GetWagonEngineType(): 27
|
GetWagonEngineType(): 27
|
||||||
GetWagonAge(): 0
|
GetWagonAge(): 0
|
||||||
GetWagonEngineType(): 65535
|
GetWagonEngineType(): 65535
|
||||||
@@ -9187,11 +9360,11 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
14 => 1
|
14 => 1
|
||||||
12 => 1
|
12 => 1
|
||||||
Age ListDump:
|
Age ListDump:
|
||||||
17 => 1
|
|
||||||
16 => 1
|
|
||||||
14 => 1
|
|
||||||
13 => 1
|
13 => 1
|
||||||
12 => 1
|
12 => 1
|
||||||
|
17 => 0
|
||||||
|
16 => 0
|
||||||
|
14 => 0
|
||||||
MaxAge ListDump:
|
MaxAge ListDump:
|
||||||
16 => 10980
|
16 => 10980
|
||||||
14 => 10980
|
14 => 10980
|
||||||
@@ -9199,9 +9372,9 @@ ERROR: IsEnd() is invalid as Begin() is never called
|
|||||||
13 => 5490
|
13 => 5490
|
||||||
12 => 5490
|
12 => 5490
|
||||||
AgeLeft ListDump:
|
AgeLeft ListDump:
|
||||||
16 => 10979
|
16 => 10980
|
||||||
14 => 10979
|
14 => 10980
|
||||||
17 => 7319
|
17 => 7320
|
||||||
13 => 5489
|
13 => 5489
|
||||||
12 => 5489
|
12 => 5489
|
||||||
CurrentSpeed ListDump:
|
CurrentSpeed ListDump:
|
||||||
|
@@ -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 "1.12"; }
|
function GetAPIVersion() { return "13"; }
|
||||||
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; }
|
||||||
|
147
src/3rdparty/optional/optional.hpp
vendored
147
src/3rdparty/optional/optional.hpp
vendored
@@ -826,185 +826,62 @@ template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) no
|
|||||||
|
|
||||||
|
|
||||||
// 20.5.10, Comparison with T
|
// 20.5.10, Comparison with T
|
||||||
template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator==(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x == v : false;
|
return bool(x) ? *x == v : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator==(const T& v, const optional<U>& x)
|
||||||
{
|
{
|
||||||
return bool(x) ? v == *x : false;
|
return bool(x) ? v == *x : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x != v : true;
|
return bool(x) ? *x != v : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x)
|
||||||
{
|
{
|
||||||
return bool(x) ? v != *x : true;
|
return bool(x) ? v != *x : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator<(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x < v : true;
|
return bool(x) ? *x < v : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator>(const T& v, const optional<U>& x)
|
||||||
{
|
{
|
||||||
return bool(x) ? v > *x : true;
|
return bool(x) ? v > *x : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator>(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x > v : false;
|
return bool(x) ? *x > v : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator<(const T& v, const optional<T>& x)
|
||||||
{
|
{
|
||||||
return bool(x) ? v < *x : false;
|
return bool(x) ? v < *x : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x >= v : false;
|
return bool(x) ? *x >= v : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x)
|
||||||
{
|
{
|
||||||
return bool(x) ? v <= *x : false;
|
return bool(x) ? v <= *x : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
|
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v)
|
||||||
{
|
{
|
||||||
return bool(x) ? *x <= v : true;
|
return bool(x) ? *x <= v : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
|
template <class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x)
|
||||||
{
|
|
||||||
return bool(x) ? v >= *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Comparison of optional<T&> with T
|
|
||||||
template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x == v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v == *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x != v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v != *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x < v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v > *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x > v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v < *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x >= v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v <= *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x <= v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v >= *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comparison of optional<T const&> with T
|
|
||||||
template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x == v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v == *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x != v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v != *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x < v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v > *x : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x > v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v < *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x >= v : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
|
||||||
return bool(x) ? v <= *x : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
|
|
||||||
{
|
|
||||||
return bool(x) ? *x <= v : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
|
|
||||||
{
|
{
|
||||||
return bool(x) ? v >= *x : true;
|
return bool(x) ? v >= *x : true;
|
||||||
}
|
}
|
||||||
|
4
src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp
vendored
4
src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp
vendored
@@ -17,7 +17,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
|
|||||||
SQFloat f;
|
SQFloat f;
|
||||||
const SQChar *s;
|
const SQChar *s;
|
||||||
SQInteger level=1; //1 is to skip this function that is level 0
|
SQInteger level=1; //1 is to skip this function that is level 0
|
||||||
const SQChar *name=0;
|
const SQChar *name=nullptr;
|
||||||
SQInteger seq=0;
|
SQInteger seq=0;
|
||||||
pf(v,"\nCALLSTACK\n");
|
pf(v,"\nCALLSTACK\n");
|
||||||
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
|
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
|
||||||
@@ -116,7 +116,7 @@ static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
|
|||||||
{
|
{
|
||||||
SQPRINTFUNCTION pf = sq_getprintfunc(v);
|
SQPRINTFUNCTION pf = sq_getprintfunc(v);
|
||||||
if(pf) {
|
if(pf) {
|
||||||
const SQChar *sErr = 0;
|
const SQChar *sErr = nullptr;
|
||||||
if(sq_gettop(v)>=1) {
|
if(sq_gettop(v)>=1) {
|
||||||
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
|
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
|
||||||
pf(v,"\nAN ERROR HAS OCCURRED [%s]\n",sErr);
|
pf(v,"\nAN ERROR HAS OCCURRED [%s]\n",sErr);
|
||||||
|
4
src/3rdparty/squirrel/sqstdlib/sqstdmath.cpp
vendored
4
src/3rdparty/squirrel/sqstdlib/sqstdmath.cpp
vendored
@@ -88,7 +88,7 @@ static SQRegFunction mathlib_funcs[] = {
|
|||||||
#endif /* EXPORT_DEFAULT_SQUIRREL_FUNCTIONS */
|
#endif /* EXPORT_DEFAULT_SQUIRREL_FUNCTIONS */
|
||||||
_DECL_FUNC(fabs,2,".n"),
|
_DECL_FUNC(fabs,2,".n"),
|
||||||
_DECL_FUNC(abs,2,".n"),
|
_DECL_FUNC(abs,2,".n"),
|
||||||
{0,0,0,0},
|
{nullptr,nullptr,0,nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
@@ -98,7 +98,7 @@ static SQRegFunction mathlib_funcs[] = {
|
|||||||
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
|
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
|
||||||
{
|
{
|
||||||
SQInteger i=0;
|
SQInteger i=0;
|
||||||
while(mathlib_funcs[i].name!=0) {
|
while(mathlib_funcs[i].name!=nullptr) {
|
||||||
sq_pushstring(v,mathlib_funcs[i].name,-1);
|
sq_pushstring(v,mathlib_funcs[i].name,-1);
|
||||||
sq_newclosure(v,mathlib_funcs[i].f,0);
|
sq_newclosure(v,mathlib_funcs[i].f,0);
|
||||||
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
|
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
|
||||||
|
58
src/3rdparty/squirrel/squirrel/sqapi.cpp
vendored
58
src/3rdparty/squirrel/squirrel/sqapi.cpp
vendored
@@ -60,11 +60,11 @@ HSQUIRRELVM sq_open(SQInteger initialstacksize)
|
|||||||
v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
|
v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
|
||||||
new (v) SQVM(ss);
|
new (v) SQVM(ss);
|
||||||
ss->_root_vm = v;
|
ss->_root_vm = v;
|
||||||
if(v->Init(NULL, initialstacksize)) {
|
if(v->Init(nullptr, initialstacksize)) {
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
sq_delete(v, SQVM);
|
sq_delete(v, SQVM);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
|
|||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
sq_delete(v, SQVM);
|
sq_delete(v, SQVM);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ void sq_close(HSQUIRRELVM v)
|
|||||||
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
|
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
|
||||||
{
|
{
|
||||||
SQObjectPtr o;
|
SQObjectPtr o;
|
||||||
if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
|
if(Compile(v, read, p, sourcename, o, raiseerror != 0, _ss(v)->_debuginfo)) {
|
||||||
v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
|
v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
}
|
}
|
||||||
@@ -144,12 +144,12 @@ SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQCha
|
|||||||
|
|
||||||
void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
|
void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
|
||||||
{
|
{
|
||||||
_ss(v)->_debuginfo = enable?true:false;
|
_ss(v)->_debuginfo = enable != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
|
void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
|
||||||
{
|
{
|
||||||
_ss(v)->_notifyallexceptions = enable?true:false;
|
_ss(v)->_notifyallexceptions = enable != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
|
void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
|
||||||
@@ -178,7 +178,7 @@ const SQChar *sq_objtostring(HSQOBJECT *o)
|
|||||||
if(sq_type(*o) == OT_STRING) {
|
if(sq_type(*o) == OT_STRING) {
|
||||||
return _stringval(*o);
|
return _stringval(*o);
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQInteger sq_objtointeger(HSQOBJECT *o)
|
SQInteger sq_objtointeger(HSQOBJECT *o)
|
||||||
@@ -224,7 +224,7 @@ void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
|
|||||||
|
|
||||||
void sq_pushbool(HSQUIRRELVM v,SQBool b)
|
void sq_pushbool(HSQUIRRELVM v,SQBool b)
|
||||||
{
|
{
|
||||||
v->Push(b?true:false);
|
v->Push(b != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
|
void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
|
||||||
@@ -256,7 +256,7 @@ void sq_newarray(HSQUIRRELVM v,SQInteger size)
|
|||||||
|
|
||||||
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
|
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
|
||||||
{
|
{
|
||||||
SQClass *baseclass = NULL;
|
SQClass *baseclass = nullptr;
|
||||||
if(hasbase) {
|
if(hasbase) {
|
||||||
SQObjectPtr &base = stack_get(v,-1);
|
SQObjectPtr &base = stack_get(v,-1);
|
||||||
if(type(base) != OT_CLASS)
|
if(type(base) != OT_CLASS)
|
||||||
@@ -555,7 +555,7 @@ SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
|
|||||||
|
|
||||||
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
|
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_STRING,o);
|
_GETSAFE_OBJ(v, idx, OT_STRING,o);
|
||||||
*c = _stringval(*o);
|
*c = _stringval(*o);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -563,7 +563,7 @@ SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
|
|||||||
|
|
||||||
SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
|
SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_THREAD,o);
|
_GETSAFE_OBJ(v, idx, OT_THREAD,o);
|
||||||
*thread = _thread(*o);
|
*thread = _thread(*o);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -598,7 +598,7 @@ SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
|
|||||||
|
|
||||||
SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
|
SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_USERDATA,o);
|
_GETSAFE_OBJ(v, idx, OT_USERDATA,o);
|
||||||
(*p) = _userdataval(*o);
|
(*p) = _userdataval(*o);
|
||||||
if(typetag) *typetag = _userdata(*o)->_typetag;
|
if(typetag) *typetag = _userdata(*o)->_typetag;
|
||||||
@@ -637,7 +637,7 @@ SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
|
|||||||
|
|
||||||
SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
|
SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
|
_GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
|
||||||
(*p) = _userpointer(*o);
|
(*p) = _userpointer(*o);
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -666,13 +666,13 @@ SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserP
|
|||||||
SQObjectPtr &o = stack_get(v,idx);
|
SQObjectPtr &o = stack_get(v,idx);
|
||||||
if(type(o) != OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
|
if(type(o) != OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
|
||||||
(*p) = _instance(o)->_userpointer;
|
(*p) = _instance(o)->_userpointer;
|
||||||
if(typetag != 0) {
|
if(typetag != nullptr) {
|
||||||
SQClass *cl = _instance(o)->_class;
|
SQClass *cl = _instance(o)->_class;
|
||||||
do{
|
do{
|
||||||
if(cl->_typetag == typetag)
|
if(cl->_typetag == typetag)
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
cl = cl->_base;
|
cl = cl->_base;
|
||||||
}while(cl != NULL);
|
}while(cl != nullptr);
|
||||||
return sq_throwerror(v,"invalid type tag");
|
return sq_throwerror(v,"invalid type tag");
|
||||||
}
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -724,7 +724,7 @@ SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
|
|||||||
if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
|
if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
|
||||||
SQObjectPtr &key = v->GetUp(-2);
|
SQObjectPtr &key = v->GetUp(-2);
|
||||||
if(type(key) == OT_NULL) return sq_throwerror(v, "null is not a valid key");
|
if(type(key) == OT_NULL) return sq_throwerror(v, "null is not a valid key");
|
||||||
v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
|
v->NewSlot(self, key, v->GetUp(-1),bstatic != 0);
|
||||||
v->Pop(2);
|
v->Pop(2);
|
||||||
}
|
}
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -801,14 +801,14 @@ SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
|
|||||||
if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, "delagate cycle");
|
if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, "delagate cycle");
|
||||||
v->Pop();}
|
v->Pop();}
|
||||||
else if(type(mt)==OT_NULL) {
|
else if(type(mt)==OT_NULL) {
|
||||||
_table(self)->SetDelegate(NULL); v->Pop(); }
|
_table(self)->SetDelegate(nullptr); v->Pop(); }
|
||||||
else return sq_aux_invalidtype(v,type);
|
else return sq_aux_invalidtype(v,type);
|
||||||
break;
|
break;
|
||||||
case OT_USERDATA:
|
case OT_USERDATA:
|
||||||
if(type(mt)==OT_TABLE) {
|
if(type(mt)==OT_TABLE) {
|
||||||
_userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
|
_userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
|
||||||
else if(type(mt)==OT_NULL) {
|
else if(type(mt)==OT_NULL) {
|
||||||
_userdata(self)->SetDelegate(NULL); v->Pop(); }
|
_userdata(self)->SetDelegate(nullptr); v->Pop(); }
|
||||||
else return sq_aux_invalidtype(v, type);
|
else return sq_aux_invalidtype(v, type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -909,7 +909,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
|
|||||||
}
|
}
|
||||||
SQVM::CallInfo &ci=v->_callsstack[lvl];
|
SQVM::CallInfo &ci=v->_callsstack[lvl];
|
||||||
if(type(ci._closure)!=OT_CLOSURE)
|
if(type(ci._closure)!=OT_CLOSURE)
|
||||||
return NULL;
|
return nullptr;
|
||||||
SQClosure *c=_closure(ci._closure);
|
SQClosure *c=_closure(ci._closure);
|
||||||
SQFunctionProto *func=_funcproto(c->_function);
|
SQFunctionProto *func=_funcproto(c->_function);
|
||||||
if(func->_noutervalues > (SQInteger)idx) {
|
if(func->_noutervalues > (SQInteger)idx) {
|
||||||
@@ -919,7 +919,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
|
|||||||
idx -= func->_noutervalues;
|
idx -= func->_noutervalues;
|
||||||
return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
|
return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
|
void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
|
||||||
@@ -929,7 +929,7 @@ void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
|
|||||||
|
|
||||||
void sq_resetobject(HSQOBJECT *po)
|
void sq_resetobject(HSQOBJECT *po)
|
||||||
{
|
{
|
||||||
po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
|
po->_unVal.pUserPointer=nullptr;po->_type=OT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
|
SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
|
||||||
@@ -975,7 +975,7 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror,
|
|||||||
v->_can_suspend = suspend >= 0;
|
v->_can_suspend = suspend >= 0;
|
||||||
if (v->_can_suspend) v->_ops_till_suspend = suspend;
|
if (v->_can_suspend) v->_ops_till_suspend = suspend;
|
||||||
|
|
||||||
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false,v->_can_suspend)){
|
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror != 0,v->_can_suspend)){
|
||||||
if(!v->_suspended) {
|
if(!v->_suspended) {
|
||||||
v->Pop(params);//pop closure and args
|
v->Pop(params);//pop closure and args
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1051,7 @@ void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
|
|||||||
|
|
||||||
SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
|
SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
|
_GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
|
||||||
unsigned short tag = SQ_BYTECODE_STREAM_TAG;
|
unsigned short tag = SQ_BYTECODE_STREAM_TAG;
|
||||||
if(w(up,&tag,2) != 2)
|
if(w(up,&tag,2) != 2)
|
||||||
@@ -1093,7 +1093,7 @@ SQInteger sq_collectgarbage(HSQUIRRELVM v)
|
|||||||
const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
|
const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
|
||||||
{
|
{
|
||||||
SQObjectPtr &self = stack_get(v,idx);
|
SQObjectPtr &self = stack_get(v,idx);
|
||||||
const SQChar *name = NULL;
|
const SQChar *name = nullptr;
|
||||||
if(type(self) == OT_CLOSURE) {
|
if(type(self) == OT_CLOSURE) {
|
||||||
if(_closure(self)->_outervalues.size()>nval) {
|
if(_closure(self)->_outervalues.size()>nval) {
|
||||||
v->Push(_closure(self)->_outervalues[nval]);
|
v->Push(_closure(self)->_outervalues[nval]);
|
||||||
@@ -1131,7 +1131,7 @@ SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
|
|||||||
|
|
||||||
SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
|
SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||||
SQObjectPtr &key = stack_get(v,-2);
|
SQObjectPtr &key = stack_get(v,-2);
|
||||||
SQObjectPtr &val = stack_get(v,-1);
|
SQObjectPtr &val = stack_get(v,-1);
|
||||||
@@ -1153,7 +1153,7 @@ SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
|
|||||||
|
|
||||||
SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
|
SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||||
SQObjectPtr &key = stack_get(v,-1);
|
SQObjectPtr &key = stack_get(v,-1);
|
||||||
SQObjectPtr attrs;
|
SQObjectPtr attrs;
|
||||||
@@ -1173,7 +1173,7 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
|
|||||||
|
|
||||||
SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
|
SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||||
if(_class(*o)->_base)
|
if(_class(*o)->_base)
|
||||||
v->Push(SQObjectPtr(_class(*o)->_base));
|
v->Push(SQObjectPtr(_class(*o)->_base));
|
||||||
@@ -1184,7 +1184,7 @@ SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
|
|||||||
|
|
||||||
SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
|
SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
|
_GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
|
||||||
v->Push(SQObjectPtr(_instance(*o)->_class));
|
v->Push(SQObjectPtr(_instance(*o)->_class));
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
@@ -1192,7 +1192,7 @@ SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
|
|||||||
|
|
||||||
SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
|
SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
|
||||||
{
|
{
|
||||||
SQObjectPtr *o = NULL;
|
SQObjectPtr *o = nullptr;
|
||||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||||
v->Push(_class(*o)->CreateInstance());
|
v->Push(_class(*o)->CreateInstance());
|
||||||
return SQ_OK;
|
return SQ_OK;
|
||||||
|
50
src/3rdparty/squirrel/squirrel/sqbaselib.cpp
vendored
50
src/3rdparty/squirrel/squirrel/sqbaselib.cpp
vendored
@@ -248,29 +248,29 @@ static SQRegFunction base_funcs[]={
|
|||||||
{"getconsttable",base_getconsttable,1, NULL},
|
{"getconsttable",base_getconsttable,1, NULL},
|
||||||
{"setconsttable",base_setconsttable,2, NULL},
|
{"setconsttable",base_setconsttable,2, NULL},
|
||||||
#endif
|
#endif
|
||||||
{"assert",base_assert,2, NULL},
|
{"assert",base_assert,2, nullptr},
|
||||||
{"print",base_print,2, NULL},
|
{"print",base_print,2, nullptr},
|
||||||
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
||||||
{"compilestring",base_compilestring,-2, ".ss"},
|
{"compilestring",base_compilestring,-2, ".ss"},
|
||||||
{"newthread",base_newthread,2, ".c"},
|
{"newthread",base_newthread,2, ".c"},
|
||||||
{"suspend",base_suspend,-1, NULL},
|
{"suspend",base_suspend,-1, NULL},
|
||||||
#endif
|
#endif
|
||||||
{"array",base_array,-2, ".n"},
|
{"array",base_array,-2, ".n"},
|
||||||
{"type",base_type,2, NULL},
|
{"type",base_type,2, nullptr},
|
||||||
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
||||||
{"dummy",base_dummy,0,NULL},
|
{"dummy",base_dummy,0,NULL},
|
||||||
#ifndef NO_GARBAGE_COLLECTOR
|
#ifndef NO_GARBAGE_COLLECTOR
|
||||||
{"collectgarbage",base_collectgarbage,1, "t"},
|
{"collectgarbage",base_collectgarbage,1, "t"},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
void sq_base_register(HSQUIRRELVM v)
|
void sq_base_register(HSQUIRRELVM v)
|
||||||
{
|
{
|
||||||
SQInteger i=0;
|
SQInteger i=0;
|
||||||
sq_pushroottable(v);
|
sq_pushroottable(v);
|
||||||
while(base_funcs[i].name!=0) {
|
while(base_funcs[i].name!=nullptr) {
|
||||||
sq_pushstring(v,base_funcs[i].name,-1);
|
sq_pushstring(v,base_funcs[i].name,-1);
|
||||||
sq_newclosure(v,base_funcs[i].f,0);
|
sq_newclosure(v,base_funcs[i].f,0);
|
||||||
sq_setnativeclosurename(v,-1,base_funcs[i].name);
|
sq_setnativeclosurename(v,-1,base_funcs[i].name);
|
||||||
@@ -415,10 +415,10 @@ SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
|
|||||||
{"rawset",table_rawset,3, "t"},
|
{"rawset",table_rawset,3, "t"},
|
||||||
{"rawdelete",table_rawdelete,2, "t"},
|
{"rawdelete",table_rawdelete,2, "t"},
|
||||||
{"rawin",container_rawexists,2, "t"},
|
{"rawin",container_rawexists,2, "t"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{"clear",obj_clear,1, "."},
|
{"clear",obj_clear,1, "."},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//ARRAY DEFAULT DELEGATE///////////////////////////////////////
|
//ARRAY DEFAULT DELEGATE///////////////////////////////////////
|
||||||
@@ -624,10 +624,10 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
|
|||||||
{"reverse",array_reverse,1, "a"},
|
{"reverse",array_reverse,1, "a"},
|
||||||
{"sort",array_sort,-1, "ac"},
|
{"sort",array_sort,-1, "ac"},
|
||||||
{"slice",array_slice,-1, "ann"},
|
{"slice",array_slice,-1, "ann"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{"clear",obj_clear,1, "."},
|
{"clear",obj_clear,1, "."},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//STRING DEFAULT DELEGATE//////////////////////////
|
//STRING DEFAULT DELEGATE//////////////////////////
|
||||||
@@ -687,8 +687,8 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
|
|||||||
{"find",string_find,-2, "s s n "},
|
{"find",string_find,-2, "s s n "},
|
||||||
{"tolower",string_tolower,1, "s"},
|
{"tolower",string_tolower,1, "s"},
|
||||||
{"toupper",string_toupper,1, "s"},
|
{"toupper",string_toupper,1, "s"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//INTEGER DEFAULT DELEGATE//////////////////////////
|
//INTEGER DEFAULT DELEGATE//////////////////////////
|
||||||
@@ -697,8 +697,8 @@ SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
|
|||||||
{"tofloat",default_delegate_tofloat,1, "n|b"},
|
{"tofloat",default_delegate_tofloat,1, "n|b"},
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{"tochar",number_delegate_tochar,1, "n|b"},
|
{"tochar",number_delegate_tochar,1, "n|b"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//CLOSURE DEFAULT DELEGATE//////////////////////////
|
//CLOSURE DEFAULT DELEGATE//////////////////////////
|
||||||
@@ -782,11 +782,11 @@ SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
|
|||||||
{"pcall",closure_pcall,-1, "c"},
|
{"pcall",closure_pcall,-1, "c"},
|
||||||
{"acall",closure_acall,2, "ca"},
|
{"acall",closure_acall,2, "ca"},
|
||||||
{"pacall",closure_pacall,2, "ca"},
|
{"pacall",closure_pacall,2, "ca"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{"bindenv",closure_bindenv,2, "c x|y|t"},
|
{"bindenv",closure_bindenv,2, "c x|y|t"},
|
||||||
{"getinfos",closure_getinfos,1, "c"},
|
{"getinfos",closure_getinfos,1, "c"},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//GENERATOR DEFAULT DELEGATE
|
//GENERATOR DEFAULT DELEGATE
|
||||||
@@ -803,9 +803,9 @@ static SQInteger generator_getstatus(HSQUIRRELVM v)
|
|||||||
|
|
||||||
SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
|
SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
|
||||||
{"getstatus",generator_getstatus,1, "g"},
|
{"getstatus",generator_getstatus,1, "g"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
//THREAD DEFAULT DELEGATE
|
//THREAD DEFAULT DELEGATE
|
||||||
@@ -889,9 +889,9 @@ SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
|
|||||||
{"call", thread_call, -1, "v"},
|
{"call", thread_call, -1, "v"},
|
||||||
{"wakeup", thread_wakeup, -1, "v"},
|
{"wakeup", thread_wakeup, -1, "v"},
|
||||||
{"getstatus", thread_getstatus, 1, "v"},
|
{"getstatus", thread_getstatus, 1, "v"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{0,0,0,0},
|
{nullptr,nullptr,0,nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static SQInteger class_getattributes(HSQUIRRELVM v)
|
static SQInteger class_getattributes(HSQUIRRELVM v)
|
||||||
@@ -919,10 +919,10 @@ SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
|
|||||||
{"getattributes", class_getattributes, 2, "y."},
|
{"getattributes", class_getattributes, 2, "y."},
|
||||||
{"setattributes", class_setattributes, 3, "y.."},
|
{"setattributes", class_setattributes, 3, "y.."},
|
||||||
{"rawin",container_rawexists,2, "y"},
|
{"rawin",container_rawexists,2, "y"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{"instance",class_instance,1, "y"},
|
{"instance",class_instance,1, "y"},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
static SQInteger instance_getclass(HSQUIRRELVM v)
|
static SQInteger instance_getclass(HSQUIRRELVM v)
|
||||||
@@ -935,9 +935,9 @@ static SQInteger instance_getclass(HSQUIRRELVM v)
|
|||||||
SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
|
SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
|
||||||
{"getclass", instance_getclass, 1, "x"},
|
{"getclass", instance_getclass, 1, "x"},
|
||||||
{"rawin",container_rawexists,2, "x"},
|
{"rawin",container_rawexists,2, "x"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
static SQInteger weakref_ref(HSQUIRRELVM v)
|
static SQInteger weakref_ref(HSQUIRRELVM v)
|
||||||
@@ -949,9 +949,9 @@ static SQInteger weakref_ref(HSQUIRRELVM v)
|
|||||||
|
|
||||||
SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
|
SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
|
||||||
{"ref",weakref_ref,1, "r"},
|
{"ref",weakref_ref,1, "r"},
|
||||||
{"weakref",obj_delegate_weakref,1, NULL },
|
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||||
{"tostring",default_delegate_tostring,1, "."},
|
{"tostring",default_delegate_tostring,1, "."},
|
||||||
{0,0,0,0}
|
{nullptr,nullptr,0,nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
10
src/3rdparty/squirrel/squirrel/sqclass.cpp
vendored
10
src/3rdparty/squirrel/squirrel/sqclass.cpp
vendored
@@ -15,8 +15,8 @@
|
|||||||
SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
||||||
{
|
{
|
||||||
_base = base;
|
_base = base;
|
||||||
_typetag = 0;
|
_typetag = nullptr;
|
||||||
_hook = NULL;
|
_hook = nullptr;
|
||||||
_udsize = 0;
|
_udsize = 0;
|
||||||
_metamethods.resize(MT_LAST); //size it to max size
|
_metamethods.resize(MT_LAST); //size it to max size
|
||||||
if(_base) {
|
if(_base) {
|
||||||
@@ -139,8 +139,8 @@ bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
void SQInstance::Init(SQSharedState *ss)
|
void SQInstance::Init(SQSharedState *ss)
|
||||||
{
|
{
|
||||||
_userpointer = NULL;
|
_userpointer = nullptr;
|
||||||
_hook = NULL;
|
_hook = nullptr;
|
||||||
__ObjAddRef(_class);
|
__ObjAddRef(_class);
|
||||||
_delegate = _class->_members;
|
_delegate = _class->_members;
|
||||||
INIT_CHAIN();
|
INIT_CHAIN();
|
||||||
@@ -196,7 +196,7 @@ bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
|
|||||||
bool SQInstance::InstanceOf(SQClass *trg)
|
bool SQInstance::InstanceOf(SQClass *trg)
|
||||||
{
|
{
|
||||||
SQClass *parent = _class;
|
SQClass *parent = _class;
|
||||||
while(parent != NULL) {
|
while(parent != nullptr) {
|
||||||
if(parent == trg)
|
if(parent == trg)
|
||||||
return true;
|
return true;
|
||||||
parent = parent->_base;
|
parent = parent->_base;
|
||||||
|
2
src/3rdparty/squirrel/squirrel/sqclosure.h
vendored
2
src/3rdparty/squirrel/squirrel/sqclosure.h
vendored
@@ -45,7 +45,7 @@ struct SQGenerator : public CHAINABLE_OBJ
|
|||||||
{
|
{
|
||||||
enum SQGeneratorState{eRunning,eSuspended,eDead};
|
enum SQGeneratorState{eRunning,eSuspended,eDead};
|
||||||
private:
|
private:
|
||||||
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
|
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=nullptr;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
|
||||||
public:
|
public:
|
||||||
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
|
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
|
||||||
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
|
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
|
||||||
|
@@ -57,7 +57,7 @@ typedef sqvector<ExpState> ExpStateVec;
|
|||||||
class SQCompiler
|
class SQCompiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(NULL), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
|
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(nullptr), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
|
||||||
{
|
{
|
||||||
_vm=v;
|
_vm=v;
|
||||||
_sourcename = SQString::Create(_ss(v), sourcename);
|
_sourcename = SQString::Create(_ss(v), sourcename);
|
||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
_debugline = 1;
|
_debugline = 1;
|
||||||
_debugop = 0;
|
_debugop = 0;
|
||||||
|
|
||||||
SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
|
SQFuncState funcstate(_ss(_vm), nullptr,ThrowError,this);
|
||||||
funcstate._name = SQString::Create(_ss(_vm), "main");
|
funcstate._name = SQString::Create(_ss(_vm), "main");
|
||||||
_fs = &funcstate;
|
_fs = &funcstate;
|
||||||
_fs->AddParameter(_fs->CreateString("this"));
|
_fs->AddParameter(_fs->CreateString("this"));
|
||||||
@@ -835,8 +835,7 @@ public:
|
|||||||
nkeys++;
|
nkeys++;
|
||||||
SQInteger val = _fs->PopTarget();
|
SQInteger val = _fs->PopTarget();
|
||||||
SQInteger key = _fs->PopTarget();
|
SQInteger key = _fs->PopTarget();
|
||||||
SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
|
[[maybe_unused]] SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
|
||||||
(void)attrs; // assert only
|
|
||||||
assert((hasattrs && attrs == key-1) || !hasattrs);
|
assert((hasattrs && attrs == key-1) || !hasattrs);
|
||||||
unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
|
unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
|
||||||
SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
|
SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
|
||||||
|
@@ -79,7 +79,7 @@ SQInstructionDesc g_InstrDesc[]={
|
|||||||
{"_OP_NEWSLOTA"},
|
{"_OP_NEWSLOTA"},
|
||||||
{"_OP_SCOPE_END"}
|
{"_OP_SCOPE_END"}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
void DumpLiteral(SQObjectPtr &o)
|
void DumpLiteral(SQObjectPtr &o)
|
||||||
{
|
{
|
||||||
switch(type(o)){
|
switch(type(o)){
|
||||||
@@ -90,6 +90,7 @@ void DumpLiteral(SQObjectPtr &o)
|
|||||||
default: printf("(%s %p)",GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
|
default: printf("(%s %p)",GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
|
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
|
||||||
{
|
{
|
||||||
|
4
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
4
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
@@ -87,7 +87,7 @@ SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerE
|
|||||||
_prevtoken = -1;
|
_prevtoken = -1;
|
||||||
_curtoken = -1;
|
_curtoken = -1;
|
||||||
|
|
||||||
_svalue = NULL;
|
_svalue = nullptr;
|
||||||
_nvalue = 0;
|
_nvalue = 0;
|
||||||
_fvalue = 0;
|
_fvalue = 0;
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ const SQChar *SQLexer::Tok2Str(SQInteger tok)
|
|||||||
if(((SQInteger)_integer(val)) == tok)
|
if(((SQInteger)_integer(val)) == tok)
|
||||||
return _stringval(key);
|
return _stringval(key);
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQLexer::LexBlockComment()
|
void SQLexer::LexBlockComment()
|
||||||
|
10
src/3rdparty/squirrel/squirrel/sqobject.cpp
vendored
10
src/3rdparty/squirrel/squirrel/sqobject.cpp
vendored
@@ -41,7 +41,7 @@ const SQChar *IdType2Name(SQObjectType type)
|
|||||||
case _RT_INSTANCE: return "instance";
|
case _RT_INSTANCE: return "instance";
|
||||||
case _RT_WEAKREF: return "weakref";
|
case _RT_WEAKREF: return "weakref";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,13 +101,13 @@ SQRefCounted::~SQRefCounted()
|
|||||||
{
|
{
|
||||||
if(_weakref) {
|
if(_weakref) {
|
||||||
_weakref->_obj._type = OT_NULL;
|
_weakref->_obj._type = OT_NULL;
|
||||||
_weakref->_obj._unVal.pRefCounted = NULL;
|
_weakref->_obj._unVal.pRefCounted = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQWeakRef::Release() {
|
void SQWeakRef::Release() {
|
||||||
if(ISREFCOUNTED(_obj._type)) {
|
if(ISREFCOUNTED(_obj._type)) {
|
||||||
_obj._unVal.pRefCounted->_weakref = NULL;
|
_obj._unVal.pRefCounted->_weakref = nullptr;
|
||||||
}
|
}
|
||||||
sq_delete(this,SQWeakRef);
|
sq_delete(this,SQWeakRef);
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ bool SQGenerator::Yield(SQVM *v)
|
|||||||
for(SQInteger j = nvargs - 1; j >= 0; j--) {
|
for(SQInteger j = nvargs - 1; j >= 0; j--) {
|
||||||
_vargsstack.push_back(v->_vargsstack[vargsbase+j]);
|
_vargsstack.push_back(v->_vargsstack[vargsbase+j]);
|
||||||
}
|
}
|
||||||
_ci._generator=NULL;
|
_ci._generator=nullptr;
|
||||||
for(SQInteger i=0;i<_ci._etraps;i++) {
|
for(SQInteger i=0;i<_ci._etraps;i++) {
|
||||||
_etraps.push_back(v->_etraps.top());
|
_etraps.push_back(v->_etraps.top());
|
||||||
v->_etraps.pop_back();
|
v->_etraps.pop_back();
|
||||||
@@ -204,7 +204,7 @@ void SQArray::Extend(const SQArray *a){
|
|||||||
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
|
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
|
||||||
{
|
{
|
||||||
SQUnsignedInteger nvars=_nlocalvarinfos;
|
SQUnsignedInteger nvars=_nlocalvarinfos;
|
||||||
const SQChar *res=NULL;
|
const SQChar *res=nullptr;
|
||||||
if(nvars>=nseq){
|
if(nvars>=nseq){
|
||||||
for(SQUnsignedInteger i=0;i<nvars;i++){
|
for(SQUnsignedInteger i=0;i<nvars;i++){
|
||||||
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
|
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
|
||||||
|
6
src/3rdparty/squirrel/squirrel/sqobject.h
vendored
6
src/3rdparty/squirrel/squirrel/sqobject.h
vendored
@@ -56,7 +56,7 @@ enum SQMetaMethod{
|
|||||||
|
|
||||||
struct SQRefCounted
|
struct SQRefCounted
|
||||||
{
|
{
|
||||||
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
|
SQRefCounted() { _uiRef = 0; _weakref = nullptr; }
|
||||||
virtual ~SQRefCounted();
|
virtual ~SQRefCounted();
|
||||||
SQWeakRef *GetWeakRef(SQObjectType type);
|
SQWeakRef *GetWeakRef(SQObjectType type);
|
||||||
SQUnsignedInteger _uiRef;
|
SQUnsignedInteger _uiRef;
|
||||||
@@ -152,7 +152,7 @@ struct SQObjectPtr : public SQObject
|
|||||||
{
|
{
|
||||||
SQ_OBJECT_RAWINIT()
|
SQ_OBJECT_RAWINIT()
|
||||||
_type=OT_NULL;
|
_type=OT_NULL;
|
||||||
_unVal.pUserPointer=NULL;
|
_unVal.pUserPointer=nullptr;
|
||||||
}
|
}
|
||||||
SQObjectPtr(const SQObjectPtr &o)
|
SQObjectPtr(const SQObjectPtr &o)
|
||||||
{
|
{
|
||||||
@@ -299,7 +299,7 @@ struct SQObjectPtr : public SQObject
|
|||||||
tOldType = _type;
|
tOldType = _type;
|
||||||
unOldVal = _unVal;
|
unOldVal = _unVal;
|
||||||
_type = OT_NULL;
|
_type = OT_NULL;
|
||||||
_unVal.pUserPointer = NULL;
|
_unVal.pUserPointer = nullptr;
|
||||||
__Release(tOldType,unOldVal);
|
__Release(tOldType,unOldVal);
|
||||||
}
|
}
|
||||||
inline SQObjectPtr& operator=(SQInteger i)
|
inline SQObjectPtr& operator=(SQInteger i)
|
||||||
|
44
src/3rdparty/squirrel/squirrel/sqstate.cpp
vendored
44
src/3rdparty/squirrel/squirrel/sqstate.cpp
vendored
@@ -79,12 +79,12 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
|
|||||||
{
|
{
|
||||||
SQInteger i=0;
|
SQInteger i=0;
|
||||||
SQTable *t=SQTable::Create(ss,0);
|
SQTable *t=SQTable::Create(ss,0);
|
||||||
while(funcz[i].name!=0){
|
while(funcz[i].name!=nullptr){
|
||||||
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
|
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
|
||||||
nc->_nparamscheck = funcz[i].nparamscheck;
|
nc->_nparamscheck = funcz[i].nparamscheck;
|
||||||
nc->_name = SQString::Create(ss,funcz[i].name);
|
nc->_name = SQString::Create(ss,funcz[i].name);
|
||||||
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
|
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
|
||||||
return NULL;
|
return nullptr;
|
||||||
t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
|
t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -93,15 +93,15 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
|
|||||||
|
|
||||||
SQSharedState::SQSharedState()
|
SQSharedState::SQSharedState()
|
||||||
{
|
{
|
||||||
_compilererrorhandler = NULL;
|
_compilererrorhandler = nullptr;
|
||||||
_printfunc = NULL;
|
_printfunc = nullptr;
|
||||||
_debuginfo = false;
|
_debuginfo = false;
|
||||||
_notifyallexceptions = false;
|
_notifyallexceptions = false;
|
||||||
_scratchpad=NULL;
|
_scratchpad=nullptr;
|
||||||
_scratchpadsize=0;
|
_scratchpadsize=0;
|
||||||
_collectable_free_processing = false;
|
_collectable_free_processing = false;
|
||||||
#ifndef NO_GARBAGE_COLLECTOR
|
#ifndef NO_GARBAGE_COLLECTOR
|
||||||
_gc_chain=NULL;
|
_gc_chain=nullptr;
|
||||||
#endif
|
#endif
|
||||||
sq_new(_stringtable,SQStringTable);
|
sq_new(_stringtable,SQStringTable);
|
||||||
sq_new(_metamethods,SQObjectPtrVec);
|
sq_new(_metamethods,SQObjectPtrVec);
|
||||||
@@ -189,7 +189,7 @@ SQSharedState::~SQSharedState()
|
|||||||
_refs_table.Finalize();
|
_refs_table.Finalize();
|
||||||
#ifndef NO_GARBAGE_COLLECTOR
|
#ifndef NO_GARBAGE_COLLECTOR
|
||||||
SQCollectable *t = _gc_chain;
|
SQCollectable *t = _gc_chain;
|
||||||
SQCollectable *nx = NULL;
|
SQCollectable *nx = nullptr;
|
||||||
if(t) {
|
if(t) {
|
||||||
t->_uiRef++;
|
t->_uiRef++;
|
||||||
while(t) {
|
while(t) {
|
||||||
@@ -299,7 +299,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
|||||||
EnqueueMarkObject(_instance_default_delegate,queue);
|
EnqueueMarkObject(_instance_default_delegate,queue);
|
||||||
EnqueueMarkObject(_weakref_default_delegate,queue);
|
EnqueueMarkObject(_weakref_default_delegate,queue);
|
||||||
|
|
||||||
SQCollectable *tchain=NULL;
|
SQCollectable *tchain=nullptr;
|
||||||
|
|
||||||
while (!queue.IsEmpty()) {
|
while (!queue.IsEmpty()) {
|
||||||
SQCollectable *q = queue.Pop();
|
SQCollectable *q = queue.Pop();
|
||||||
@@ -309,7 +309,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SQCollectable *t = _gc_chain;
|
SQCollectable *t = _gc_chain;
|
||||||
SQCollectable *nx = NULL;
|
SQCollectable *nx = nullptr;
|
||||||
if(t) {
|
if(t) {
|
||||||
t->_uiRef++;
|
t->_uiRef++;
|
||||||
while(t) {
|
while(t) {
|
||||||
@@ -340,7 +340,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
|||||||
#ifndef NO_GARBAGE_COLLECTOR
|
#ifndef NO_GARBAGE_COLLECTOR
|
||||||
void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
|
void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
|
||||||
{
|
{
|
||||||
c->_prev = NULL;
|
c->_prev = nullptr;
|
||||||
c->_next = *chain;
|
c->_next = *chain;
|
||||||
if(*chain) (*chain)->_prev = c;
|
if(*chain) (*chain)->_prev = c;
|
||||||
*chain = c;
|
*chain = c;
|
||||||
@@ -352,8 +352,8 @@ void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
|
|||||||
else *chain = c->_next;
|
else *chain = c->_next;
|
||||||
if(c->_next)
|
if(c->_next)
|
||||||
c->_next->_prev = c->_prev;
|
c->_next->_prev = c->_prev;
|
||||||
c->_next = NULL;
|
c->_next = nullptr;
|
||||||
c->_prev = NULL;
|
c->_prev = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -483,16 +483,16 @@ RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bo
|
|||||||
{
|
{
|
||||||
RefNode *ref;
|
RefNode *ref;
|
||||||
mainpos = ::HashObj(obj)&(_numofslots-1);
|
mainpos = ::HashObj(obj)&(_numofslots-1);
|
||||||
*prev = NULL;
|
*prev = nullptr;
|
||||||
for (ref = _buckets[mainpos]; ref; ) {
|
for (ref = _buckets[mainpos]; ref; ) {
|
||||||
if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
|
if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
|
||||||
break;
|
break;
|
||||||
*prev = ref;
|
*prev = ref;
|
||||||
ref = ref->next;
|
ref = ref->next;
|
||||||
}
|
}
|
||||||
if(ref == NULL && add) {
|
if(ref == nullptr && add) {
|
||||||
if(_numofslots == _slotused) {
|
if(_numofslots == _slotused) {
|
||||||
assert(_freelist == 0);
|
assert(_freelist == nullptr);
|
||||||
Resize(_numofslots*2);
|
Resize(_numofslots*2);
|
||||||
mainpos = ::HashObj(obj)&(_numofslots-1);
|
mainpos = ::HashObj(obj)&(_numofslots-1);
|
||||||
}
|
}
|
||||||
@@ -510,16 +510,16 @@ void RefTable::AllocNodes(SQUnsignedInteger size)
|
|||||||
RefNode *temp = nodes;
|
RefNode *temp = nodes;
|
||||||
SQUnsignedInteger n;
|
SQUnsignedInteger n;
|
||||||
for(n = 0; n < size - 1; n++) {
|
for(n = 0; n < size - 1; n++) {
|
||||||
bucks[n] = NULL;
|
bucks[n] = nullptr;
|
||||||
temp->refs = 0;
|
temp->refs = 0;
|
||||||
new (&temp->obj) SQObjectPtr;
|
new (&temp->obj) SQObjectPtr;
|
||||||
temp->next = temp+1;
|
temp->next = temp+1;
|
||||||
temp++;
|
temp++;
|
||||||
}
|
}
|
||||||
bucks[n] = NULL;
|
bucks[n] = nullptr;
|
||||||
temp->refs = 0;
|
temp->refs = 0;
|
||||||
new (&temp->obj) SQObjectPtr;
|
new (&temp->obj) SQObjectPtr;
|
||||||
temp->next = NULL;
|
temp->next = nullptr;
|
||||||
_freelist = nodes;
|
_freelist = nodes;
|
||||||
_nodes = nodes;
|
_nodes = nodes;
|
||||||
_buckets = bucks;
|
_buckets = bucks;
|
||||||
@@ -543,7 +543,7 @@ SQStringTable::SQStringTable()
|
|||||||
SQStringTable::~SQStringTable()
|
SQStringTable::~SQStringTable()
|
||||||
{
|
{
|
||||||
SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
|
SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
|
||||||
_strings = NULL;
|
_strings = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQStringTable::AllocNodes(SQInteger size)
|
void SQStringTable::AllocNodes(SQInteger size)
|
||||||
@@ -580,8 +580,8 @@ SQString::SQString(const SQChar *news, SQInteger len)
|
|||||||
_val[len] = '\0';
|
_val[len] = '\0';
|
||||||
_len = len;
|
_len = len;
|
||||||
_hash = ::_hashstr(news,(size_t)len);
|
_hash = ::_hashstr(news,(size_t)len);
|
||||||
_next = NULL;
|
_next = nullptr;
|
||||||
_sharedstate = NULL;
|
_sharedstate = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQStringTable::Resize(SQInteger size)
|
void SQStringTable::Resize(SQInteger size)
|
||||||
@@ -605,7 +605,7 @@ void SQStringTable::Resize(SQInteger size)
|
|||||||
void SQStringTable::Remove(SQString *bs)
|
void SQStringTable::Remove(SQString *bs)
|
||||||
{
|
{
|
||||||
SQString *s;
|
SQString *s;
|
||||||
SQString *prev=NULL;
|
SQString *prev=nullptr;
|
||||||
SQHash h = bs->_hash&(_numofslots - 1);
|
SQHash h = bs->_hash&(_numofslots - 1);
|
||||||
|
|
||||||
for (s = _strings[h]; s; ){
|
for (s = _strings[h]; s; ){
|
||||||
|
12
src/3rdparty/squirrel/squirrel/sqtable.cpp
vendored
12
src/3rdparty/squirrel/squirrel/sqtable.cpp
vendored
@@ -18,7 +18,7 @@ SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
|
|||||||
while(nInitialSize>pow2size)pow2size=pow2size<<1;
|
while(nInitialSize>pow2size)pow2size=pow2size<<1;
|
||||||
AllocNodes(pow2size);
|
AllocNodes(pow2size);
|
||||||
_usednodes = 0;
|
_usednodes = 0;
|
||||||
_delegate = NULL;
|
_delegate = nullptr;
|
||||||
INIT_CHAIN();
|
INIT_CHAIN();
|
||||||
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
|
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ void SQTable::AllocNodes(SQInteger nSize)
|
|||||||
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
|
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
|
||||||
for(SQInteger i=0;i<nSize;i++){
|
for(SQInteger i=0;i<nSize;i++){
|
||||||
new (&nodes[i]) _HashNode;
|
new (&nodes[i]) _HashNode;
|
||||||
nodes[i].next=NULL;
|
nodes[i].next=nullptr;
|
||||||
}
|
}
|
||||||
_numofnodes=nSize;
|
_numofnodes=nSize;
|
||||||
_nodes=nodes;
|
_nodes=nodes;
|
||||||
@@ -120,7 +120,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
|||||||
if (mp > n && (othern = &_nodes[mph]) != mp){
|
if (mp > n && (othern = &_nodes[mph]) != mp){
|
||||||
/* yes; move colliding node into free position */
|
/* yes; move colliding node into free position */
|
||||||
while (othern->next != mp){
|
while (othern->next != mp){
|
||||||
assert(othern->next != NULL);
|
assert(othern->next != nullptr);
|
||||||
othern = othern->next; /* find previous */
|
othern = othern->next; /* find previous */
|
||||||
}
|
}
|
||||||
othern->next = n; /* redo the chain with `n' in place of `mp' */
|
othern->next = n; /* redo the chain with `n' in place of `mp' */
|
||||||
@@ -129,7 +129,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
|||||||
n->next = mp->next;
|
n->next = mp->next;
|
||||||
mp->key = _null_;
|
mp->key = _null_;
|
||||||
mp->val = _null_;
|
mp->val = _null_;
|
||||||
mp->next = NULL; /* now `mp' is free */
|
mp->next = nullptr; /* now `mp' is free */
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
/* new node will go into free position */
|
/* new node will go into free position */
|
||||||
@@ -141,7 +141,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
|||||||
mp->key = key;
|
mp->key = key;
|
||||||
|
|
||||||
for (;;) { /* correct `firstfree' */
|
for (;;) { /* correct `firstfree' */
|
||||||
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
|
if (type(_firstfree->key) == OT_NULL && _firstfree->next == nullptr) {
|
||||||
mp->val = val;
|
mp->val = val;
|
||||||
_usednodes++;
|
_usednodes++;
|
||||||
return true; /* OK; table still has a free place */
|
return true; /* OK; table still has a free place */
|
||||||
@@ -190,7 +190,7 @@ void SQTable::_ClearNodes()
|
|||||||
void SQTable::Finalize()
|
void SQTable::Finalize()
|
||||||
{
|
{
|
||||||
_ClearNodes();
|
_ClearNodes();
|
||||||
SetDelegate(NULL);
|
SetDelegate(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQTable::Clear()
|
void SQTable::Clear()
|
||||||
|
8
src/3rdparty/squirrel/squirrel/sqtable.h
vendored
8
src/3rdparty/squirrel/squirrel/sqtable.h
vendored
@@ -27,7 +27,7 @@ struct SQTable : public SQDelegable
|
|||||||
private:
|
private:
|
||||||
struct _HashNode
|
struct _HashNode
|
||||||
{
|
{
|
||||||
_HashNode() { next = NULL; }
|
_HashNode() { next = nullptr; }
|
||||||
SQObjectPtr val;
|
SQObjectPtr val;
|
||||||
SQObjectPtr key;
|
SQObjectPtr key;
|
||||||
_HashNode *next;
|
_HashNode *next;
|
||||||
@@ -47,14 +47,14 @@ public:
|
|||||||
{
|
{
|
||||||
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
|
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
|
||||||
new (newtable) SQTable(ss, nInitialSize);
|
new (newtable) SQTable(ss, nInitialSize);
|
||||||
newtable->_delegate = NULL;
|
newtable->_delegate = nullptr;
|
||||||
return newtable;
|
return newtable;
|
||||||
}
|
}
|
||||||
void Finalize() override;
|
void Finalize() override;
|
||||||
SQTable *Clone();
|
SQTable *Clone();
|
||||||
~SQTable()
|
~SQTable()
|
||||||
{
|
{
|
||||||
SetDelegate(NULL);
|
SetDelegate(nullptr);
|
||||||
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
|
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
|
||||||
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
|
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
|
||||||
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
|
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
|
||||||
@@ -70,7 +70,7 @@ public:
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}while((n = n->next));
|
}while((n = n->next));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
|
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
|
||||||
void Remove(const SQObjectPtr &key);
|
void Remove(const SQObjectPtr &key);
|
||||||
|
6
src/3rdparty/squirrel/squirrel/squserdata.h
vendored
6
src/3rdparty/squirrel/squirrel/squserdata.h
vendored
@@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
struct SQUserData : SQDelegable
|
struct SQUserData : SQDelegable
|
||||||
{
|
{
|
||||||
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = 0;
|
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = nullptr; _hook = nullptr; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = nullptr;
|
||||||
}
|
}
|
||||||
~SQUserData()
|
~SQUserData()
|
||||||
{
|
{
|
||||||
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
|
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
|
||||||
SetDelegate(NULL);
|
SetDelegate(nullptr);
|
||||||
}
|
}
|
||||||
static SQUserData* Create(SQSharedState *ss, SQInteger size)
|
static SQUserData* Create(SQSharedState *ss, SQInteger size)
|
||||||
{
|
{
|
||||||
@@ -19,7 +19,7 @@ struct SQUserData : SQDelegable
|
|||||||
}
|
}
|
||||||
#ifndef NO_GARBAGE_COLLECTOR
|
#ifndef NO_GARBAGE_COLLECTOR
|
||||||
void EnqueueMarkObjectForChildren(SQGCMarkerQueue &queue);
|
void EnqueueMarkObjectForChildren(SQGCMarkerQueue &queue);
|
||||||
void Finalize(){SetDelegate(NULL);}
|
void Finalize(){SetDelegate(nullptr);}
|
||||||
#endif
|
#endif
|
||||||
void Release() {
|
void Release() {
|
||||||
if (_hook) _hook(_val,_size);
|
if (_hook) _hook(_val,_size);
|
||||||
|
2
src/3rdparty/squirrel/squirrel/squtils.h
vendored
2
src/3rdparty/squirrel/squirrel/squtils.h
vendored
@@ -18,7 +18,7 @@ template<typename T> class sqvector
|
|||||||
public:
|
public:
|
||||||
sqvector()
|
sqvector()
|
||||||
{
|
{
|
||||||
_vals = NULL;
|
_vals = nullptr;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_allocated = 0;
|
_allocated = 0;
|
||||||
}
|
}
|
||||||
|
30
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
30
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -33,7 +33,7 @@ void SQVM::ClearStack(SQInteger last_top)
|
|||||||
tOldType = o._type;
|
tOldType = o._type;
|
||||||
unOldVal = o._unVal;
|
unOldVal = o._unVal;
|
||||||
o._type = OT_NULL;
|
o._type = OT_NULL;
|
||||||
o._unVal.pUserPointer = NULL;
|
o._unVal.pUserPointer = nullptr;
|
||||||
__Release(tOldType,unOldVal);
|
__Release(tOldType,unOldVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ SQVM::SQVM(SQSharedState *ss)
|
|||||||
_suspended_target=-1;
|
_suspended_target=-1;
|
||||||
_suspended_root = SQFalse;
|
_suspended_root = SQFalse;
|
||||||
_suspended_traps=0;
|
_suspended_traps=0;
|
||||||
_foreignptr=NULL;
|
_foreignptr=nullptr;
|
||||||
_nnativecalls=0;
|
_nnativecalls=0;
|
||||||
_lasterror = _null_;
|
_lasterror = _null_;
|
||||||
_errorhandler = _null_;
|
_errorhandler = _null_;
|
||||||
@@ -115,12 +115,12 @@ SQVM::SQVM(SQSharedState *ss)
|
|||||||
_can_suspend = false;
|
_can_suspend = false;
|
||||||
_in_stackoverflow = false;
|
_in_stackoverflow = false;
|
||||||
_ops_till_suspend = 0;
|
_ops_till_suspend = 0;
|
||||||
_callsstack = NULL;
|
_callsstack = nullptr;
|
||||||
_callsstacksize = 0;
|
_callsstacksize = 0;
|
||||||
_alloccallsstacksize = 0;
|
_alloccallsstacksize = 0;
|
||||||
_top = 0;
|
_top = 0;
|
||||||
_stackbase = 0;
|
_stackbase = 0;
|
||||||
ci = NULL;
|
ci = nullptr;
|
||||||
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
|
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +379,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege
|
|||||||
|
|
||||||
if (!tailcall) {
|
if (!tailcall) {
|
||||||
CallInfo lc = {};
|
CallInfo lc = {};
|
||||||
lc._generator = NULL;
|
lc._generator = nullptr;
|
||||||
lc._etraps = 0;
|
lc._etraps = 0;
|
||||||
lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
|
lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
|
||||||
lc._target = (SQInt32) target;
|
lc._target = (SQInt32) target;
|
||||||
@@ -437,7 +437,7 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
|
|||||||
|
|
||||||
while (last_top > oldstackbase) _stack._vals[last_top--].Null();
|
while (last_top > oldstackbase) _stack._vals[last_top--].Null();
|
||||||
assert(oldstackbase >= _stackbase);
|
assert(oldstackbase >= _stackbase);
|
||||||
return broot?true:false;
|
return broot != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _RET_ON_FAIL(exp) { if(!exp) return false; }
|
#define _RET_ON_FAIL(exp) { if(!exp) return false; }
|
||||||
@@ -557,7 +557,7 @@ bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OT_NULL:
|
case OT_NULL:
|
||||||
_table(o1)->SetDelegate(NULL);
|
_table(o1)->SetDelegate(nullptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Raise_Error("using '%s' as delegate", GetTypeName(o2));
|
Raise_Error("using '%s' as delegate", GetTypeName(o2));
|
||||||
@@ -627,7 +627,7 @@ bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
|
|||||||
|
|
||||||
bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
|
bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
|
||||||
{
|
{
|
||||||
SQClass *base = NULL;
|
SQClass *base = nullptr;
|
||||||
SQObjectPtr attrs;
|
SQObjectPtr attrs;
|
||||||
if(baseclass != -1) {
|
if(baseclass != -1) {
|
||||||
if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error("trying to inherit from a %s",GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
|
if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error("trying to inherit from a %s",GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
|
||||||
@@ -653,7 +653,7 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes
|
|||||||
bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
|
bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
|
||||||
{
|
{
|
||||||
if(type(o1) == type(o2)) {
|
if(type(o1) == type(o2)) {
|
||||||
res = ((_rawval(o1) == _rawval(o2)?true:false));
|
res = ((_rawval(o1) == _rawval(o2)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
|
if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
|
||||||
@@ -708,7 +708,7 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn
|
|||||||
temp_reg = closure;
|
temp_reg = closure;
|
||||||
if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
|
if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
|
||||||
//call the handler if there are no calls in the stack, if not relies on the previous node
|
//call the handler if there are no calls in the stack, if not relies on the previous node
|
||||||
if(ci == NULL) CallErrorHandler(_lasterror);
|
if(ci == nullptr) CallErrorHandler(_lasterror);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
|
if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
|
||||||
@@ -1028,7 +1028,7 @@ common_call:
|
|||||||
case _OP_THROW: Raise_Error(TARGET); SQ_THROW();
|
case _OP_THROW: Raise_Error(TARGET); SQ_THROW();
|
||||||
case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
|
case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
|
||||||
case _OP_NEWSLOTA:
|
case _OP_NEWSLOTA:
|
||||||
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
|
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG) != 0;
|
||||||
if(type(STK(arg1)) == OT_CLASS) {
|
if(type(STK(arg1)) == OT_CLASS) {
|
||||||
if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
|
if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
|
||||||
Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
|
Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
|
||||||
@@ -1160,7 +1160,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb
|
|||||||
_top = stackbase + nargs;
|
_top = stackbase + nargs;
|
||||||
CallInfo lci = {};
|
CallInfo lci = {};
|
||||||
lci._closure = nclosure;
|
lci._closure = nclosure;
|
||||||
lci._generator = NULL;
|
lci._generator = nullptr;
|
||||||
lci._etraps = 0;
|
lci._etraps = 0;
|
||||||
lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
|
lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
|
||||||
lci._ncalls = 1;
|
lci._ncalls = 1;
|
||||||
@@ -1471,9 +1471,7 @@ bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr
|
|||||||
|
|
||||||
bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror,SQBool can_suspend)
|
bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror,SQBool can_suspend)
|
||||||
{
|
{
|
||||||
#ifdef WITH_ASSERT
|
[[maybe_unused]] SQInteger prevstackbase = _stackbase;
|
||||||
SQInteger prevstackbase = _stackbase;
|
|
||||||
#endif
|
|
||||||
switch(type(closure)) {
|
switch(type(closure)) {
|
||||||
case OT_CLOSURE: {
|
case OT_CLOSURE: {
|
||||||
assert(!can_suspend || this->_can_suspend);
|
assert(!can_suspend || this->_can_suspend);
|
||||||
@@ -1504,11 +1502,9 @@ bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObj
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef WITH_ASSERT
|
|
||||||
if(!_suspended) {
|
if(!_suspended) {
|
||||||
assert(_stackbase == prevstackbase);
|
assert(_stackbase == prevstackbase);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -334,6 +334,7 @@ add_files(
|
|||||||
rail_cmd.cpp
|
rail_cmd.cpp
|
||||||
rail_gui.cpp
|
rail_gui.cpp
|
||||||
rail_gui.h
|
rail_gui.h
|
||||||
|
rail_gui_type.h
|
||||||
rail_map.h
|
rail_map.h
|
||||||
rail_type.h
|
rail_type.h
|
||||||
random_access_file.cpp
|
random_access_file.cpp
|
||||||
@@ -517,6 +518,7 @@ add_files(
|
|||||||
viewport_type.h
|
viewport_type.h
|
||||||
void_cmd.cpp
|
void_cmd.cpp
|
||||||
void_map.h
|
void_map.h
|
||||||
|
walltime_func.h
|
||||||
water.h
|
water.h
|
||||||
water_cmd.cpp
|
water_cmd.cpp
|
||||||
water_map.h
|
water_map.h
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
static bool CheckAPIVersion(const char *api_version)
|
static bool CheckAPIVersion(const char *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", "1.12" };
|
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" };
|
||||||
return versions.find(api_version) != versions.end();
|
return versions.find(api_version) != versions.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
|||||||
{
|
{
|
||||||
/* Get the AIInfo */
|
/* Get the AIInfo */
|
||||||
SQUserPointer instance = nullptr;
|
SQUserPointer instance = nullptr;
|
||||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, nullptr)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
||||||
AIInfo *info = (AIInfo *)instance;
|
AIInfo *info = (AIInfo *)instance;
|
||||||
|
|
||||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||||
@@ -107,7 +107,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
|||||||
{
|
{
|
||||||
/* Get the AIInfo */
|
/* Get the AIInfo */
|
||||||
SQUserPointer instance;
|
SQUserPointer instance;
|
||||||
sq_getinstanceup(vm, 2, &instance, 0);
|
sq_getinstanceup(vm, 2, &instance, nullptr);
|
||||||
AIInfo *info = (AIInfo *)instance;
|
AIInfo *info = (AIInfo *)instance;
|
||||||
info->api_version = nullptr;
|
info->api_version = nullptr;
|
||||||
|
|
||||||
|
@@ -207,7 +207,7 @@ void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteS
|
|||||||
|
|
||||||
const Aircraft *w = v->Next()->Next();
|
const Aircraft *w = v->Next()->Next();
|
||||||
if (is_custom_sprite(v->spritenum)) {
|
if (is_custom_sprite(v->spritenum)) {
|
||||||
GetCustomRotorSprite(v, false, image_type, result);
|
GetCustomRotorSprite(v, image_type, result);
|
||||||
if (result->IsValid()) return;
|
if (result->IsValid()) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1058,7 +1058,7 @@ static bool AircraftController(Aircraft *v)
|
|||||||
if (count == 0) return false;
|
if (count == 0) return false;
|
||||||
|
|
||||||
/* If the plane will be a few subpixels away from the destination after
|
/* If the plane will be a few subpixels away from the destination after
|
||||||
* this movement loop, start nudging him towards the exact position for
|
* this movement loop, start nudging it towards the exact position for
|
||||||
* the whole loop. Otherwise, heavily depending on the speed of the plane,
|
* the whole loop. Otherwise, heavily depending on the speed of the plane,
|
||||||
* it is possible we totally overshoot the target, causing the plane to
|
* it is possible we totally overshoot the target, causing the plane to
|
||||||
* make a loop, and trying again, and again, and again .. */
|
* make a loop, and trying again, and again, and again .. */
|
||||||
|
@@ -99,7 +99,7 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
|
|||||||
if (helicopter) {
|
if (helicopter) {
|
||||||
const Aircraft *a = Aircraft::From(v);
|
const Aircraft *a = Aircraft::From(v);
|
||||||
VehicleSpriteSeq rotor_seq;
|
VehicleSpriteSeq rotor_seq;
|
||||||
GetCustomRotorSprite(a, true, image_type, &rotor_seq);
|
GetCustomRotorSprite(a, image_type, &rotor_seq);
|
||||||
if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
|
if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
|
||||||
heli_offs = ScaleGUITrad(5);
|
heli_offs = ScaleGUITrad(5);
|
||||||
rotor_seq.Draw(x, y + y_offs - heli_offs, PAL_NONE, false);
|
rotor_seq.Draw(x, y + y_offs - heli_offs, PAL_NONE, false);
|
||||||
|
@@ -483,7 +483,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_AP_AIRPORT_LIST: {
|
case WID_AP_AIRPORT_LIST: {
|
||||||
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height;
|
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->GetWidget<NWidgetBase>(widget)->pos_y) / this->line_height;
|
||||||
if (num_clicked >= this->vscroll->GetCount()) break;
|
if (num_clicked >= this->vscroll->GetCount()) 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);
|
||||||
|
@@ -614,8 +614,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
|||||||
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
|
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
|
||||||
|
|
||||||
/* Sell wagon */
|
/* Sell wagon */
|
||||||
CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
|
[[maybe_unused]] CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
|
||||||
(void)ret; // assert only
|
|
||||||
assert(ret.Succeeded());
|
assert(ret.Succeeded());
|
||||||
new_vehs[i] = nullptr;
|
new_vehs[i] = nullptr;
|
||||||
|
|
||||||
@@ -668,8 +667,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
|||||||
assert(Train::From(old_head)->GetNextUnit() == nullptr);
|
assert(Train::From(old_head)->GetNextUnit() == nullptr);
|
||||||
|
|
||||||
for (int i = num_units - 1; i > 0; i--) {
|
for (int i = num_units - 1; i > 0; i--) {
|
||||||
CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
|
[[maybe_unused]] CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
|
||||||
(void)ret; // assert only
|
|
||||||
assert(ret.Succeeded());
|
assert(ret.Succeeded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -379,11 +379,14 @@ public:
|
|||||||
const Group *g = Group::GetIfValid(this->sel_group);
|
const Group *g = Group::GetIfValid(this->sel_group);
|
||||||
if (g != nullptr) {
|
if (g != nullptr) {
|
||||||
remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
|
remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
|
||||||
|
SetDParam(0, STR_GROUP_NAME);
|
||||||
|
SetDParam(1, sel_group);
|
||||||
} else {
|
} else {
|
||||||
const Company *c = Company::Get(_local_company);
|
const Company *c = Company::Get(_local_company);
|
||||||
remove_wagon = c->settings.renew_keep_length;
|
remove_wagon = c->settings.renew_keep_length;
|
||||||
|
SetDParam(0, STR_GROUP_DEFAULT_TRAINS + this->window_number);
|
||||||
}
|
}
|
||||||
SetDParam(0, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
SetDParam(2, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +544,7 @@ public:
|
|||||||
DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
|
DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
|
||||||
} else {
|
} else {
|
||||||
// toggle renew_keep_length
|
// toggle renew_keep_length
|
||||||
DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING);
|
DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -642,6 +645,20 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
|
||||||
|
{
|
||||||
|
if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false;
|
||||||
|
|
||||||
|
if (Group::IsValidID(this->sel_group)) {
|
||||||
|
uint64 params[1];
|
||||||
|
params[0] = STR_REPLACE_REMOVE_WAGON_HELP;
|
||||||
|
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond);
|
||||||
|
} else {
|
||||||
|
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, 0, nullptr, close_cond);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void OnResize() override
|
void OnResize() override
|
||||||
{
|
{
|
||||||
this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
|
this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#ifndef BITMAP_TYPE_HPP
|
#ifndef BITMAP_TYPE_HPP
|
||||||
#define BITMAP_TYPE_HPP
|
#define BITMAP_TYPE_HPP
|
||||||
|
|
||||||
|
#include "tilearea_type.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/** Represents a tile area containing containing individually set tiles.
|
/** Represents a tile area containing containing individually set tiles.
|
||||||
|
@@ -247,7 +247,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (fast_path || (src_px->a == 255 && (sprite_flags & SF_NO_ANIM))) {
|
if (fast_path || (src_px->a == 255 && (sprite_flags & BSF_NO_ANIM))) {
|
||||||
do {
|
do {
|
||||||
*anim++ = 0;
|
*anim++ = 0;
|
||||||
Colour c = *src_px;
|
Colour c = *src_px;
|
||||||
@@ -317,7 +317,7 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
|
|||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
|
|
||||||
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
||||||
if (!(sprite_flags & SF_NO_REMAP)) {
|
if (!(sprite_flags & BSF_NO_REMAP)) {
|
||||||
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, false>(bp, zoom);
|
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, false>(bp, zoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -328,14 +328,14 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case BM_COLOUR_REMAP:
|
case BM_COLOUR_REMAP:
|
||||||
if (!(sprite_flags & SF_NO_REMAP)) {
|
if (!(sprite_flags & BSF_NO_REMAP)) {
|
||||||
Draw<BM_COLOUR_REMAP, false>(bp, zoom);
|
Draw<BM_COLOUR_REMAP, false>(bp, zoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
|
||||||
case BM_NORMAL:
|
case BM_NORMAL:
|
||||||
if ((sprite_flags & (SF_NO_ANIM | SF_TRANSLUCENT)) == SF_NO_ANIM &&
|
if ((sprite_flags & (BSF_NO_ANIM | BSF_TRANSLUCENT)) == BSF_NO_ANIM &&
|
||||||
bp->skip_left == 0 && bp->width == UnScaleByZoom(bp->sprite_width, zoom)) {
|
bp->skip_left == 0 && bp->width == UnScaleByZoom(bp->sprite_width, zoom)) {
|
||||||
Draw<BM_NORMAL, true>(bp, zoom);
|
Draw<BM_NORMAL, true>(bp, zoom);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -155,6 +155,7 @@ bmno_full_transparency:
|
|||||||
|
|
||||||
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
|
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
|
||||||
if (src->a == 0) {
|
if (src->a == 0) {
|
||||||
|
/* Complete transparency. */
|
||||||
} else if (src->a == 255) {
|
} else if (src->a == 255) {
|
||||||
*anim = *(const uint16*) src_mv;
|
*anim = *(const uint16*) src_mv;
|
||||||
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src;
|
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src;
|
||||||
@@ -197,7 +198,7 @@ bmno_full_transparency:
|
|||||||
m_colour = r == 0 ? m_colour : cmap; \
|
m_colour = r == 0 ? m_colour : cmap; \
|
||||||
m_colour = m != 0 ? m_colour : srcm; \
|
m_colour = m != 0 ? m_colour : srcm; \
|
||||||
}
|
}
|
||||||
#ifdef _SQ64
|
#ifdef POINTER_IS_64BIT
|
||||||
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
||||||
uint64 dsts;
|
uint64 dsts;
|
||||||
if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
|
if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
|
||||||
@@ -441,35 +442,35 @@ bm_normal:
|
|||||||
if (bp->skip_left != 0 || bp->width <= MARGIN_NORMAL_THRESHOLD) {
|
if (bp->skip_left != 0 || bp->width <= MARGIN_NORMAL_THRESHOLD) {
|
||||||
const BlockType bt_last = (BlockType) (bp->width & 1);
|
const BlockType bt_last = (BlockType) (bp->width & 1);
|
||||||
if (bt_last == BT_EVEN) {
|
if (bt_last == BT_EVEN) {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_SKIP, BT_EVEN, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_SKIP, BT_EVEN, true, false>(bp, zoom);
|
||||||
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_EVEN, true, true>(bp, zoom);
|
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_EVEN, true, true>(bp, zoom);
|
||||||
} else {
|
} else {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, false>(bp, zoom);
|
||||||
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
|
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef _SQ64
|
#ifdef POINTER_IS_64BIT
|
||||||
if (sprite_flags & SF_TRANSLUCENT) {
|
if (sprite_flags & BSF_TRANSLUCENT) {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
||||||
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
||||||
} else {
|
} else {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false, false>(bp, zoom);
|
||||||
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false, true>(bp, zoom);
|
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false, true>(bp, zoom);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
||||||
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BM_COLOUR_REMAP:
|
case BM_COLOUR_REMAP:
|
||||||
if (sprite_flags & SF_NO_REMAP) goto bm_normal;
|
if (sprite_flags & BSF_NO_REMAP) goto bm_normal;
|
||||||
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
|
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true, false>(bp, zoom);
|
||||||
else Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true, true>(bp, zoom);
|
else Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true, true>(bp, zoom);
|
||||||
} else {
|
} else {
|
||||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
if (sprite_flags & BSF_NO_ANIM) Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
||||||
else Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
else Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -478,7 +479,7 @@ bm_normal:
|
|||||||
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
|
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
|
||||||
|
|
||||||
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
||||||
if (!(sprite_flags & SF_NO_REMAP)) {
|
if (!(sprite_flags & BSF_NO_REMAP)) {
|
||||||
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, RM_NONE, BT_NONE, true, true>(bp, zoom);
|
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, RM_NONE, BT_NONE, true, true>(bp, zoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -313,7 +313,7 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
|||||||
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
|
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlitterSpriteFlags flags = SF_NO_REMAP | SF_NO_ANIM;
|
BlitterSpriteFlags flags = BSF_NO_REMAP | BSF_NO_ANIM;
|
||||||
|
|
||||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||||
const SpriteLoader::Sprite *src_orig = &sprite[z];
|
const SpriteLoader::Sprite *src_orig = &sprite[z];
|
||||||
@@ -354,11 +354,11 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
|||||||
|
|
||||||
if (a != 0) {
|
if (a != 0) {
|
||||||
dst_px->a = a;
|
dst_px->a = a;
|
||||||
if (a != 0 && a != 255) flags |= SF_TRANSLUCENT;
|
if (a != 0 && a != 255) flags |= BSF_TRANSLUCENT;
|
||||||
*dst_n = src->m;
|
*dst_n = src->m;
|
||||||
if (src->m != 0) {
|
if (src->m != 0) {
|
||||||
flags &= ~SF_NO_REMAP;
|
flags &= ~BSF_NO_REMAP;
|
||||||
if (src->m >= PALETTE_ANIM_START) flags &= ~SF_NO_ANIM;
|
if (src->m >= PALETTE_ANIM_START) flags &= ~BSF_NO_ANIM;
|
||||||
|
|
||||||
/* Get brightest value */
|
/* Get brightest value */
|
||||||
uint8 rgb_max = std::max({ src->r, src->g, src->b });
|
uint8 rgb_max = std::max({ src->r, src->g, src->b });
|
||||||
|
@@ -129,10 +129,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Store sprite flags. */
|
/* Store sprite flags. */
|
||||||
sd.flags = SF_NONE;
|
sd.flags = BSF_NONE;
|
||||||
if (has_translucency) sd.flags |= SF_TRANSLUCENT;
|
if (has_translucency) sd.flags |= BSF_TRANSLUCENT;
|
||||||
if (!has_remap) sd.flags |= SF_NO_REMAP;
|
if (!has_remap) sd.flags |= BSF_NO_REMAP;
|
||||||
if (!has_anim) sd.flags |= SF_NO_ANIM;
|
if (!has_anim) sd.flags |= BSF_NO_ANIM;
|
||||||
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
|
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
|
||||||
|
|
||||||
return dst_sprite;
|
return dst_sprite;
|
||||||
|
@@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
|
|||||||
|
|
||||||
static inline void LoadUint64(const uint64 value, __m128i &into)
|
static inline void LoadUint64(const uint64 value, __m128i &into)
|
||||||
{
|
{
|
||||||
#ifdef _SQ64
|
#ifdef POINTER_IS_64BIT
|
||||||
into = _mm_cvtsi64_si128(value);
|
into = _mm_cvtsi64_si128(value);
|
||||||
#else
|
#else
|
||||||
#if (SSE_VERSION >= 4)
|
#if (SSE_VERSION >= 4)
|
||||||
@@ -303,7 +303,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
m_colour = r == 0 ? m_colour : cmap; \
|
m_colour = r == 0 ? m_colour : cmap; \
|
||||||
m_colour = m != 0 ? m_colour : srcm; \
|
m_colour = m != 0 ? m_colour : srcm; \
|
||||||
}
|
}
|
||||||
#ifdef _SQ64
|
#ifdef POINTER_IS_64BIT
|
||||||
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
||||||
uint64 remapped_src = 0;
|
uint64 remapped_src = 0;
|
||||||
CMOV_REMAP(c0, 0, srcs, mvX2);
|
CMOV_REMAP(c0, 0, srcs, mvX2);
|
||||||
@@ -499,7 +499,7 @@ bm_normal:
|
|||||||
case BT_ODD: Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true>(bp, zoom); return;
|
case BT_ODD: Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true>(bp, zoom); return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & SF_TRANSLUCENT) {
|
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & BSF_TRANSLUCENT) {
|
||||||
Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom);
|
Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom);
|
||||||
} else {
|
} else {
|
||||||
Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false>(bp, zoom);
|
Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, false>(bp, zoom);
|
||||||
@@ -509,7 +509,7 @@ bm_normal:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BM_COLOUR_REMAP:
|
case BM_COLOUR_REMAP:
|
||||||
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & SF_NO_REMAP) goto bm_normal;
|
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & BSF_NO_REMAP) goto bm_normal;
|
||||||
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
|
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
|
||||||
Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true>(bp, zoom); return;
|
Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE, true>(bp, zoom); return;
|
||||||
} else {
|
} else {
|
||||||
@@ -520,7 +520,7 @@ bm_normal:
|
|||||||
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true>(bp, zoom); return;
|
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true>(bp, zoom); return;
|
||||||
|
|
||||||
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
case BM_COLOUR_REMAP_WITH_BRIGHTNESS:
|
||||||
if (!(((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & SF_NO_REMAP)) {
|
if (!(((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags & BSF_NO_REMAP)) {
|
||||||
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, RM_NONE, BT_NONE, true>(bp, zoom);
|
Draw<BM_COLOUR_REMAP_WITH_BRIGHTNESS, RM_NONE, BT_NONE, true>(bp, zoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -33,10 +33,10 @@ enum BlitterMode {
|
|||||||
* - heavy branching (remap lookups and animation buffer handling).
|
* - heavy branching (remap lookups and animation buffer handling).
|
||||||
*/
|
*/
|
||||||
enum BlitterSpriteFlags {
|
enum BlitterSpriteFlags {
|
||||||
SF_NONE = 0,
|
BSF_NONE = 0,
|
||||||
SF_TRANSLUCENT = 1 << 1, ///< The sprite has at least 1 translucent pixel.
|
BSF_TRANSLUCENT = 1 << 1, ///< The sprite has at least 1 translucent pixel.
|
||||||
SF_NO_REMAP = 1 << 2, ///< The sprite has no remappable colour pixel.
|
BSF_NO_REMAP = 1 << 2, ///< The sprite has no remappable colour pixel.
|
||||||
SF_NO_ANIM = 1 << 3, ///< The sprite has no palette animated pixel.
|
BSF_NO_ANIM = 1 << 3, ///< The sprite has no palette animated pixel.
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(BlitterSpriteFlags);
|
DECLARE_ENUM_AS_BIT_SET(BlitterSpriteFlags);
|
||||||
|
|
||||||
|
@@ -16,14 +16,14 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
template <typename SetPixelT>
|
template <typename SetPixelT>
|
||||||
void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
|
void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
|
||||||
{
|
{
|
||||||
int dy;
|
int dy;
|
||||||
int dx;
|
int dx;
|
||||||
int stepx;
|
int stepx;
|
||||||
int stepy;
|
int stepy;
|
||||||
|
|
||||||
dy = (y2 - y) * 2;
|
dy = (y2 - y1) * 2;
|
||||||
if (dy < 0) {
|
if (dy < 0) {
|
||||||
dy = -dy;
|
dy = -dy;
|
||||||
stepy = -1;
|
stepy = -1;
|
||||||
@@ -31,7 +31,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
stepy = 1;
|
stepy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = (x2 - x) * 2;
|
dx = (x2 - x1) * 2;
|
||||||
if (dx < 0) {
|
if (dx < 0) {
|
||||||
dx = -dx;
|
dx = -dx;
|
||||||
stepx = -1;
|
stepx = -1;
|
||||||
@@ -41,7 +41,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
|
|
||||||
if (dx == 0 && dy == 0) {
|
if (dx == 0 && dy == 0) {
|
||||||
/* The algorithm below cannot handle this special case; make it work at least for line width 1 */
|
/* The algorithm below cannot handle this special case; make it work at least for line width 1 */
|
||||||
if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) set_pixel(x, y);
|
if (x1 >= 0 && x1 < screen_width && y1 >= 0 && y1 < screen_height) set_pixel(x1, y1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +67,14 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
int dash_count = 0;
|
int dash_count = 0;
|
||||||
if (dx > dy) {
|
if (dx > dy) {
|
||||||
if (stepx < 0) {
|
if (stepx < 0) {
|
||||||
std::swap(x, x2);
|
std::swap(x1, x2);
|
||||||
std::swap(y, y2);
|
std::swap(y1, y2);
|
||||||
stepy = -stepy;
|
stepy = -stepy;
|
||||||
}
|
}
|
||||||
if (x2 < 0 || x >= screen_width) return;
|
if (x2 < 0 || x1 >= screen_width) return;
|
||||||
|
|
||||||
int y_low = y;
|
int y_low = y1;
|
||||||
int y_high = y;
|
int y_high = y1;
|
||||||
int frac_low = dy - frac_diff / 2;
|
int frac_low = dy - frac_diff / 2;
|
||||||
int frac_high = dy + frac_diff / 2;
|
int frac_high = dy + frac_diff / 2;
|
||||||
|
|
||||||
@@ -87,10 +87,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
y_high += stepy;
|
y_high += stepy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x < 0) {
|
if (x1 < 0) {
|
||||||
dash_count = (-x) % (dash + gap);
|
dash_count = (-x1) % (dash + gap);
|
||||||
auto adjust_frac = [&](int64 frac, int &y_bound) -> int {
|
auto adjust_frac = [&](int64 frac, int &y_bound) -> int {
|
||||||
frac -= ((int64) dy) * ((int64) x);
|
frac -= ((int64) dy) * ((int64) x1);
|
||||||
if (frac >= 0) {
|
if (frac >= 0) {
|
||||||
int quotient = frac / dx;
|
int quotient = frac / dx;
|
||||||
int remainder = frac % dx;
|
int remainder = frac % dx;
|
||||||
@@ -101,17 +101,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
};
|
};
|
||||||
frac_low = adjust_frac(frac_low, y_low);
|
frac_low = adjust_frac(frac_low, y_low);
|
||||||
frac_high = adjust_frac(frac_high, y_high);
|
frac_high = adjust_frac(frac_high, y_high);
|
||||||
x = 0;
|
x1 = 0;
|
||||||
}
|
}
|
||||||
x2++;
|
x2++;
|
||||||
if (x2 > screen_width) {
|
if (x2 > screen_width) {
|
||||||
x2 = screen_width;
|
x2 = screen_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x != x2) {
|
while (x1 != x2) {
|
||||||
if (dash_count < dash) {
|
if (dash_count < dash) {
|
||||||
for (int y = y_low; y != y_high; y += stepy) {
|
for (int y = y_low; y != y_high; y += stepy) {
|
||||||
if (y >= 0 && y < screen_height) set_pixel(x, y);
|
if (y >= 0 && y < screen_height) set_pixel(x1, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frac_low >= 0) {
|
if (frac_low >= 0) {
|
||||||
@@ -122,21 +122,21 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
y_high += stepy;
|
y_high += stepy;
|
||||||
frac_high -= dx;
|
frac_high -= dx;
|
||||||
}
|
}
|
||||||
x++;
|
x1++;
|
||||||
frac_low += dy;
|
frac_low += dy;
|
||||||
frac_high += dy;
|
frac_high += dy;
|
||||||
if (++dash_count >= dash + gap) dash_count = 0;
|
if (++dash_count >= dash + gap) dash_count = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (stepy < 0) {
|
if (stepy < 0) {
|
||||||
std::swap(x, x2);
|
std::swap(x1, x2);
|
||||||
std::swap(y, y2);
|
std::swap(y1, y2);
|
||||||
stepx = -stepx;
|
stepx = -stepx;
|
||||||
}
|
}
|
||||||
if (y2 < 0 || y >= screen_height) return;
|
if (y2 < 0 || y1 >= screen_height) return;
|
||||||
|
|
||||||
int x_low = x;
|
int x_low = x1;
|
||||||
int x_high = x;
|
int x_high = x1;
|
||||||
int frac_low = dx - frac_diff / 2;
|
int frac_low = dx - frac_diff / 2;
|
||||||
int frac_high = dx + frac_diff / 2;
|
int frac_high = dx + frac_diff / 2;
|
||||||
|
|
||||||
@@ -149,10 +149,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
x_high += stepx;
|
x_high += stepx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y < 0) {
|
if (y1 < 0) {
|
||||||
dash_count = (-y) % (dash + gap);
|
dash_count = (-y1) % (dash + gap);
|
||||||
auto adjust_frac = [&](int64 frac, int &x_bound) -> int {
|
auto adjust_frac = [&](int64 frac, int &x_bound) -> int {
|
||||||
frac -= ((int64) dx) * ((int64) y);
|
frac -= ((int64) dx) * ((int64) y1);
|
||||||
if (frac >= 0) {
|
if (frac >= 0) {
|
||||||
int quotient = frac / dy;
|
int quotient = frac / dy;
|
||||||
int remainder = frac % dy;
|
int remainder = frac % dy;
|
||||||
@@ -163,17 +163,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
};
|
};
|
||||||
frac_low = adjust_frac(frac_low, x_low);
|
frac_low = adjust_frac(frac_low, x_low);
|
||||||
frac_high = adjust_frac(frac_high, x_high);
|
frac_high = adjust_frac(frac_high, x_high);
|
||||||
y = 0;
|
y1 = 0;
|
||||||
}
|
}
|
||||||
y2++;
|
y2++;
|
||||||
if (y2 > screen_height) {
|
if (y2 > screen_height) {
|
||||||
y2 = screen_height;
|
y2 = screen_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (y != y2) {
|
while (y1 != y2) {
|
||||||
if (dash_count < dash) {
|
if (dash_count < dash) {
|
||||||
for (int x = x_low; x != x_high; x += stepx) {
|
for (int x = x_low; x != x_high; x += stepx) {
|
||||||
if (x >= 0 && x < screen_width) set_pixel(x, y);
|
if (x >= 0 && x < screen_width) set_pixel(x, y1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frac_low >= 0) {
|
if (frac_low >= 0) {
|
||||||
@@ -184,7 +184,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
|||||||
x_high += stepx;
|
x_high += stepx;
|
||||||
frac_high -= dy;
|
frac_high -= dy;
|
||||||
}
|
}
|
||||||
y++;
|
y1++;
|
||||||
frac_low += dx;
|
frac_low += dx;
|
||||||
frac_high += dx;
|
frac_high += dx;
|
||||||
if (++dash_count >= dash + gap) dash_count = 0;
|
if (++dash_count >= dash + gap) dash_count = 0;
|
||||||
|
@@ -91,7 +91,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the requested blitter and return his class.
|
* Find the requested blitter and return its class.
|
||||||
* @param name the blitter to select.
|
* @param name the blitter to select.
|
||||||
* @post Sets the blitter so GetCurrentBlitter() returns it too.
|
* @post Sets the blitter so GetCurrentBlitter() returns it too.
|
||||||
*/
|
*/
|
||||||
|
@@ -1338,8 +1338,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Collect available cargo types for filtering. */
|
/* Collect available cargo types for filtering. */
|
||||||
const CargoSpec *cs;
|
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||||
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
|
|
||||||
this->cargo_filter[filter_items] = cs->Index();
|
this->cargo_filter[filter_items] = cs->Index();
|
||||||
this->cargo_filter_texts[filter_items] = cs->name;
|
this->cargo_filter_texts[filter_items] = cs->name;
|
||||||
filter_items++;
|
filter_items++;
|
||||||
@@ -1789,7 +1788,10 @@ struct BuildVehicleWindow : BuildVehicleWindowBase {
|
|||||||
this->GenerateBuildList();
|
this->GenerateBuildList();
|
||||||
this->vscroll->SetCount((uint)this->eng_list.size());
|
this->vscroll->SetCount((uint)this->eng_list.size());
|
||||||
|
|
||||||
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END);
|
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WIDGET_LIST_END);
|
||||||
|
|
||||||
|
/* Disable renaming engines in network games if you are not the server. */
|
||||||
|
this->SetWidgetDisabledState(WID_BV_RENAME, this->sel_engine == INVALID_ENGINE || (_networking && !_network_server));
|
||||||
|
|
||||||
/* disable renaming engines in network games if you are not the server */
|
/* disable renaming engines in network games if you are not the server */
|
||||||
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !(_network_server || _network_settings_access));
|
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !(_network_server || _network_settings_access));
|
||||||
@@ -2110,8 +2112,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase {
|
|||||||
filter_items++;
|
filter_items++;
|
||||||
|
|
||||||
/* Collect available cargo types for filtering. */
|
/* Collect available cargo types for filtering. */
|
||||||
const CargoSpec *cs;
|
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||||
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
|
|
||||||
state.cargo_filter[filter_items] = cs->Index();
|
state.cargo_filter[filter_items] = cs->Index();
|
||||||
state.cargo_filter_texts[filter_items] = cs->name;
|
state.cargo_filter_texts[filter_items] = cs->name;
|
||||||
filter_items++;
|
filter_items++;
|
||||||
|
@@ -61,6 +61,7 @@ enum CargoType {
|
|||||||
CT_PLASTIC = 10,
|
CT_PLASTIC = 10,
|
||||||
CT_FIZZY_DRINKS = 11,
|
CT_FIZZY_DRINKS = 11,
|
||||||
|
|
||||||
|
NUM_ORIGINAL_CARGO = 12,
|
||||||
NUM_CARGO = 64, ///< Maximal number of cargo types in a game.
|
NUM_CARGO = 64, ///< Maximal number of cargo types in a game.
|
||||||
|
|
||||||
CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting.
|
CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting.
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
#include "core/multimap.hpp"
|
#include "core/multimap.hpp"
|
||||||
|
#include "saveload/saveload_common.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
/** Unique identifier for a single cargo packet. */
|
/** Unique identifier for a single cargo packet. */
|
||||||
@@ -33,7 +34,13 @@ struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
|
|||||||
|
|
||||||
template <class Tinst, class Tcont> class CargoList;
|
template <class Tinst, class Tcont> class CargoList;
|
||||||
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
|
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
|
||||||
extern const struct SaveLoad *GetCargoPacketDesc();
|
extern SaveLoadTable GetCargoPacketDesc();
|
||||||
|
|
||||||
|
namespace upstream_sl {
|
||||||
|
extern upstream_sl::SaveLoadTable GetCargoPacketDesc();
|
||||||
|
class SlVehicleCommon;
|
||||||
|
class SlStationGoods;
|
||||||
|
}
|
||||||
|
|
||||||
typedef uint32 TileOrStationID;
|
typedef uint32 TileOrStationID;
|
||||||
|
|
||||||
@@ -68,7 +75,8 @@ private:
|
|||||||
friend class VehicleCargoList;
|
friend class VehicleCargoList;
|
||||||
friend class StationCargoList;
|
friend class StationCargoList;
|
||||||
/** We want this to be saved, right? */
|
/** We want this to be saved, right? */
|
||||||
friend const struct SaveLoad *GetCargoPacketDesc();
|
friend SaveLoadTable GetCargoPacketDesc();
|
||||||
|
friend upstream_sl::SaveLoadTable upstream_sl::GetCargoPacketDesc();
|
||||||
friend void Load_CPDP();
|
friend void Load_CPDP();
|
||||||
public:
|
public:
|
||||||
/** Maximum number of items in a single cargo packet. */
|
/** Maximum number of items in a single cargo packet. */
|
||||||
@@ -339,10 +347,11 @@ protected:
|
|||||||
public:
|
public:
|
||||||
/** The station cargo list needs to control the unloading. */
|
/** The station cargo list needs to control the unloading. */
|
||||||
friend class StationCargoList;
|
friend class StationCargoList;
|
||||||
|
friend upstream_sl::SlVehicleCommon;
|
||||||
/** The super class ought to know what it's doing. */
|
/** The super class ought to know what it's doing. */
|
||||||
friend class CargoList<VehicleCargoList, CargoPacketList>;
|
friend class CargoList<VehicleCargoList, CargoPacketList>;
|
||||||
/** The vehicles have a cargo list (and we want that saved). */
|
/** The vehicles have a cargo list (and we want that saved). */
|
||||||
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
|
friend SaveLoadTable GetVehicleDescription(VehicleType vt);
|
||||||
|
|
||||||
friend class CargoShift;
|
friend class CargoShift;
|
||||||
friend class CargoTransfer;
|
friend class CargoTransfer;
|
||||||
@@ -493,7 +502,8 @@ public:
|
|||||||
/** The super class ought to know what it's doing. */
|
/** The super class ought to know what it's doing. */
|
||||||
friend class CargoList<StationCargoList, StationCargoPacketMap>;
|
friend class CargoList<StationCargoList, StationCargoPacketMap>;
|
||||||
/** The stations, via GoodsEntry, have a CargoList. */
|
/** The stations, via GoodsEntry, have a CargoList. */
|
||||||
friend const struct SaveLoad *GetGoodsDesc();
|
friend SaveLoadTable GetGoodsDesc();
|
||||||
|
friend upstream_sl::SlStationGoods;
|
||||||
|
|
||||||
friend class CargoLoad;
|
friend class CargoLoad;
|
||||||
friend class CargoTransfer;
|
friend class CargoTransfer;
|
||||||
|
@@ -77,6 +77,28 @@ void SetupCargoForClimate(LandscapeID l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cargo ID of a default cargo, if present.
|
||||||
|
* @param l Landscape
|
||||||
|
* @param ct Default cargo type.
|
||||||
|
* @return ID number if the cargo exists, else #CT_INVALID
|
||||||
|
*/
|
||||||
|
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct)
|
||||||
|
{
|
||||||
|
assert(l < lengthof(_default_climate_cargo));
|
||||||
|
|
||||||
|
if (ct == CT_INVALID) return CT_INVALID;
|
||||||
|
|
||||||
|
assert(ct < lengthof(_default_climate_cargo[0]));
|
||||||
|
CargoLabel cl = _default_climate_cargo[l][ct];
|
||||||
|
/* Bzzt: check if cl is just an index into the cargo table */
|
||||||
|
if (cl < lengthof(_default_cargo)) {
|
||||||
|
cl = _default_cargo[cl].label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetCargoIDByLabel(cl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cargo ID by cargo label.
|
* Get the cargo ID by cargo label.
|
||||||
* @param cl Cargo type to get.
|
* @param cl Cargo type to get.
|
||||||
@@ -127,8 +149,8 @@ SpriteID CargoSpec::GetCargoIcon() const
|
|||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
||||||
uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array.
|
span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
|
||||||
|
|
||||||
/** Sort cargo specifications by their name. */
|
/** Sort cargo specifications by their name. */
|
||||||
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
||||||
@@ -174,13 +196,16 @@ void InitializeSortedCargoSpecs()
|
|||||||
/* Sort cargo specifications by cargo class and name. */
|
/* Sort cargo specifications by cargo class and name. */
|
||||||
std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);
|
std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);
|
||||||
|
|
||||||
|
/* Count the number of standard cargos and fill the mask. */
|
||||||
_standard_cargo_mask = 0;
|
_standard_cargo_mask = 0;
|
||||||
|
uint8 nb_standard_cargo = 0;
|
||||||
_sorted_standard_cargo_specs_size = 0;
|
|
||||||
for (const auto &cargo : _sorted_cargo_specs) {
|
for (const auto &cargo : _sorted_cargo_specs) {
|
||||||
if (cargo->classes & CC_SPECIAL) break;
|
if (cargo->classes & CC_SPECIAL) break;
|
||||||
_sorted_standard_cargo_specs_size++;
|
nb_standard_cargo++;
|
||||||
SetBit(_standard_cargo_mask, cargo->Index());
|
SetBit(_standard_cargo_mask, cargo->Index());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */
|
||||||
|
_sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
#include "strings_type.h"
|
#include "strings_type.h"
|
||||||
#include "landscape_type.h"
|
#include "landscape_type.h"
|
||||||
|
#include "core/bitmath_func.hpp"
|
||||||
|
#include "core/span_type.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/** Globally unique label of a cargo type. */
|
/** Globally unique label of a cargo type. */
|
||||||
@@ -186,10 +188,11 @@ extern CargoTypes _standard_cargo_mask;
|
|||||||
void SetupCargoForClimate(LandscapeID l);
|
void SetupCargoForClimate(LandscapeID l);
|
||||||
CargoID GetCargoIDByLabel(CargoLabel cl);
|
CargoID GetCargoIDByLabel(CargoLabel cl);
|
||||||
CargoID GetCargoIDByBitnum(uint8 bitnum);
|
CargoID GetCargoIDByBitnum(uint8 bitnum);
|
||||||
|
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct);
|
||||||
|
|
||||||
void InitializeSortedCargoSpecs();
|
void InitializeSortedCargoSpecs();
|
||||||
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
|
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
|
||||||
extern uint8 _sorted_standard_cargo_specs_size;
|
extern span<const CargoSpec *> _sorted_standard_cargo_specs;
|
||||||
|
|
||||||
uint ConvertCargoQuantityToDisplayQuantity(CargoID cargo, uint quantity);
|
uint ConvertCargoQuantityToDisplayQuantity(CargoID cargo, uint quantity);
|
||||||
uint ConvertDisplayQuantityToCargoQuantity(CargoID cargo, uint quantity);
|
uint ConvertDisplayQuantityToCargoQuantity(CargoID cargo, uint quantity);
|
||||||
@@ -205,13 +208,6 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
|
|||||||
return (CargoSpec::Get(c)->classes & cc) != 0;
|
return (CargoSpec::Get(c)->classes & cc) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits)
|
using SetCargoBitIterator = SetBitIterator<CargoID, CargoTypes>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped.
|
|
||||||
* @param var Reference getting the cargospec.
|
|
||||||
* @see CargoSpec
|
|
||||||
*/
|
|
||||||
#define FOR_ALL_SORTED_STANDARD_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_standard_cargo_specs_size && (var = _sorted_cargo_specs[index], true); index++)
|
|
||||||
|
|
||||||
#endif /* CARGOTYPE_H */
|
#endif /* CARGOTYPE_H */
|
||||||
|
@@ -189,8 +189,8 @@ static const CheatEntry _cheats_ui[] = {
|
|||||||
{CNM_LOCAL_ONLY, SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
|
{CNM_LOCAL_ONLY, SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
|
||||||
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.map_height_limit, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
|
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.map_height_limit, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
|
||||||
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_date_ymd.year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
|
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_date_ymd.year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
|
||||||
{CNM_ALL, SLF_NOT_IN_SAVE, STR_CHEAT_INFLATION_COST, &_economy.inflation_prices, &_extra_cheats.inflation_cost.been_used, nullptr },
|
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_COST, &_economy.inflation_prices, &_extra_cheats.inflation_cost.been_used, nullptr },
|
||||||
{CNM_ALL, SLF_NOT_IN_SAVE, STR_CHEAT_INFLATION_INCOME, &_economy.inflation_payment, &_extra_cheats.inflation_income.been_used, nullptr },
|
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_INCOME, &_economy.inflation_payment, &_extra_cheats.inflation_income.been_used, nullptr },
|
||||||
{CNM_ALL, SLE_BOOL, STR_CHEAT_STATION_RATING, &_extra_cheats.station_rating.value, &_extra_cheats.station_rating.been_used, nullptr },
|
{CNM_ALL, SLE_BOOL, STR_CHEAT_STATION_RATING, &_extra_cheats.station_rating.value, &_extra_cheats.station_rating.been_used, nullptr },
|
||||||
{CNM_ALL, SLE_BOOL, STR_CHEAT_TOWN_RATING, &_extra_cheats.town_rating.value, &_extra_cheats.town_rating.been_used, nullptr },
|
{CNM_ALL, SLE_BOOL, STR_CHEAT_TOWN_RATING, &_extra_cheats.town_rating.value, &_extra_cheats.town_rating.been_used, nullptr },
|
||||||
};
|
};
|
||||||
@@ -261,7 +261,7 @@ struct CheatWindow : Window {
|
|||||||
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
|
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
|
||||||
|
|
||||||
switch (ce->type) {
|
switch (ce->type) {
|
||||||
case SLF_NOT_IN_SAVE: {
|
case SLF_ALLOW_CONTROL: {
|
||||||
/* Change inflation factors */
|
/* Change inflation factors */
|
||||||
|
|
||||||
/* Draw [<][>] boxes for settings of an integer-type */
|
/* Draw [<][>] boxes for settings of an integer-type */
|
||||||
@@ -324,7 +324,7 @@ struct CheatWindow : Window {
|
|||||||
if (!IsCheatAllowed(ce->mode)) continue;
|
if (!IsCheatAllowed(ce->mode)) continue;
|
||||||
lines++;
|
lines++;
|
||||||
switch (ce->type) {
|
switch (ce->type) {
|
||||||
case SLF_NOT_IN_SAVE:
|
case SLF_ALLOW_CONTROL:
|
||||||
/* Change inflation factors */
|
/* Change inflation factors */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -401,16 +401,16 @@ struct CheatWindow : Window {
|
|||||||
SetDParam(0, value);
|
SetDParam(0, value);
|
||||||
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MONEY_QUERY_CAPT, 20, this, CS_NUMERAL_SIGNED, QSF_ACCEPT_UNCHANGED);
|
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MONEY_QUERY_CAPT, 20, this, CS_NUMERAL_SIGNED, QSF_ACCEPT_UNCHANGED);
|
||||||
return;
|
return;
|
||||||
} else if (ce->type == SLF_NOT_IN_SAVE && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
|
} else if (ce->type == SLF_ALLOW_CONTROL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
|
||||||
clicked_widget = btn;
|
clicked_widget = btn;
|
||||||
uint64 val = (uint64)ReadValue(ce->variable, SLE_UINT64);
|
uint64 val = (uint64)ReadValue(ce->variable, SLE_UINT64);
|
||||||
SetDParam(0, val * 1000 >> 16);
|
SetDParam(0, val * 1000 >> 16);
|
||||||
SetDParam(1, 3);
|
SetDParam(1, 3);
|
||||||
StringID str = (btn == CHT_INFLATION_COST) ? STR_CHEAT_INFLATION_COST_QUERY_CAPT : STR_CHEAT_INFLATION_INCOME_QUERY_CAPT;
|
StringID str = (btn == CHT_INFLATION_COST) ? STR_CHEAT_INFLATION_COST_QUERY_CAPT : STR_CHEAT_INFLATION_INCOME_QUERY_CAPT;
|
||||||
char *saved = _settings_game.locale.digit_group_separator;
|
std::string saved = std::move(_settings_game.locale.digit_group_separator);
|
||||||
_settings_game.locale.digit_group_separator = const_cast<char*>("");
|
_settings_game.locale.digit_group_separator = "";
|
||||||
ShowQueryString(STR_JUST_DECIMAL, str, 12, this, CS_NUMERAL_DECIMAL, QSF_ACCEPT_UNCHANGED);
|
ShowQueryString(STR_JUST_DECIMAL, str, 12, this, CS_NUMERAL_DECIMAL, QSF_ACCEPT_UNCHANGED);
|
||||||
_settings_game.locale.digit_group_separator = saved;
|
_settings_game.locale.digit_group_separator = std::move(saved);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +420,7 @@ struct CheatWindow : Window {
|
|||||||
if (!_networking) *ce->been_used = true;
|
if (!_networking) *ce->been_used = true;
|
||||||
|
|
||||||
switch (ce->type) {
|
switch (ce->type) {
|
||||||
case SLF_NOT_IN_SAVE: {
|
case SLF_ALLOW_CONTROL: {
|
||||||
/* Change inflation factors */
|
/* Change inflation factors */
|
||||||
uint64 value = (uint64)ReadValue(ce->variable, SLE_UINT64) + (((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1) << 16);
|
uint64 value = (uint64)ReadValue(ce->variable, SLE_UINT64) + (((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1) << 16);
|
||||||
value = Clamp<uint64>(value, 1 << 16, MAX_INFLATION);
|
value = Clamp<uint64>(value, 1 << 16, MAX_INFLATION);
|
||||||
@@ -468,7 +468,7 @@ struct CheatWindow : Window {
|
|||||||
|
|
||||||
const CheatEntry *ce = &_cheats_ui[clicked_widget];
|
const CheatEntry *ce = &_cheats_ui[clicked_widget];
|
||||||
|
|
||||||
if (ce->type == SLF_NOT_IN_SAVE) {
|
if (ce->type == SLF_ALLOW_CONTROL) {
|
||||||
char tmp_buffer[32];
|
char tmp_buffer[32];
|
||||||
strecpy(tmp_buffer, str, lastof(tmp_buffer));
|
strecpy(tmp_buffer, str, lastof(tmp_buffer));
|
||||||
str_replace_wchar(tmp_buffer, lastof(tmp_buffer), GetDecimalSeparatorChar(), '.');
|
str_replace_wchar(tmp_buffer, lastof(tmp_buffer), GetDecimalSeparatorChar(), '.');
|
||||||
|
@@ -28,12 +28,9 @@ struct Cheats {
|
|||||||
Cheat switch_company; ///< change to another company
|
Cheat switch_company; ///< change to another company
|
||||||
Cheat money; ///< get rich or poor
|
Cheat money; ///< get rich or poor
|
||||||
Cheat crossing_tunnels; ///< allow tunnels that cross each other
|
Cheat crossing_tunnels; ///< allow tunnels that cross each other
|
||||||
Cheat dummy1; ///< empty cheat (build while in pause mode)
|
|
||||||
Cheat no_jetcrash; ///< no jet will crash on small airports anymore
|
Cheat no_jetcrash; ///< no jet will crash on small airports anymore
|
||||||
Cheat dummy2; ///< empty cheat (change the climate of the map)
|
|
||||||
Cheat change_date; ///< changes date ingame
|
Cheat change_date; ///< changes date ingame
|
||||||
Cheat setup_prod; ///< setup raw-material production in game
|
Cheat setup_prod; ///< setup raw-material production in game
|
||||||
Cheat dummy3; ///< empty cheat (enable running el-engines on normal rail)
|
|
||||||
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
|
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -303,7 +303,7 @@ static const Command _command_proc_table[] = {
|
|||||||
DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNALS
|
DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNALS
|
||||||
DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS
|
DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS
|
||||||
DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND
|
DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND
|
||||||
DEF_CMD(CmdBuildObject, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT
|
DEF_CMD(CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT
|
||||||
DEF_CMD(CmdPurchaseLandArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_PURCHASE_LAND_AREA
|
DEF_CMD(CmdPurchaseLandArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_PURCHASE_LAND_AREA
|
||||||
DEF_CMD(CmdBuildObjectArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT_AREA
|
DEF_CMD(CmdBuildObjectArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT_AREA
|
||||||
DEF_CMD(CmdBuildHouse, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_HOUSE
|
DEF_CMD(CmdBuildHouse, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_HOUSE
|
||||||
@@ -538,6 +538,7 @@ enum CommandLogEntryFlag : uint16 {
|
|||||||
DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag)
|
DECLARE_ENUM_AS_BIT_SET(CommandLogEntryFlag)
|
||||||
|
|
||||||
struct CommandLogEntry {
|
struct CommandLogEntry {
|
||||||
|
std::string text;
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
uint32 p1;
|
uint32 p1;
|
||||||
uint32 p2;
|
uint32 p2;
|
||||||
@@ -552,8 +553,8 @@ struct CommandLogEntry {
|
|||||||
|
|
||||||
CommandLogEntry() { }
|
CommandLogEntry() { }
|
||||||
|
|
||||||
CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags)
|
CommandLogEntry(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, std::string text)
|
||||||
: tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
|
: text(text), tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
|
||||||
current_company(_current_company), local_company(_local_company), log_flags(log_flags) { }
|
current_company(_current_company), local_company(_local_company), log_flags(log_flags) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -609,11 +610,8 @@ static void DumpSubCommandLog(char *&buffer, const char *last, const CommandLog
|
|||||||
|
|
||||||
switch (entry.cmd & CMD_ID_MASK) {
|
switch (entry.cmd & CMD_ID_MASK) {
|
||||||
case CMD_CHANGE_SETTING:
|
case CMD_CHANGE_SETTING:
|
||||||
buffer += seprintf(buffer, last, " [%s]", GetSettingNameByIndex(entry.p1));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_CHANGE_COMPANY_SETTING:
|
case CMD_CHANGE_COMPANY_SETTING:
|
||||||
buffer += seprintf(buffer, last, " [%s]", GetCompanySettingNameByIndex(entry.p1));
|
buffer += seprintf(buffer, last, " [%s]", entry.text.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +806,7 @@ Money GetAvailableMoneyForCommand()
|
|||||||
return Company::Get(company)->money;
|
return Company::Get(company)->money;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags)
|
static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, CommandLogEntryFlag log_flags, const char *text)
|
||||||
{
|
{
|
||||||
if (res.Failed()) log_flags |= CLEF_CMD_FAILED;
|
if (res.Failed()) log_flags |= CLEF_CMD_FAILED;
|
||||||
if (_generating_world) log_flags |= CLEF_GENERATING_WORLD;
|
if (_generating_world) log_flags |= CLEF_GENERATING_WORLD;
|
||||||
@@ -826,7 +824,16 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags);
|
|
||||||
|
std::string str;
|
||||||
|
switch (cmd & CMD_ID_MASK) {
|
||||||
|
case CMD_CHANGE_SETTING:
|
||||||
|
case CMD_CHANGE_COMPANY_SETTING:
|
||||||
|
if (text != nullptr) str.assign(text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags, std::move(str));
|
||||||
cmd_log.next = (cmd_log.next + 1) % cmd_log.log.size();
|
cmd_log.next = (cmd_log.next + 1) % cmd_log.log.size();
|
||||||
cmd_log.count++;
|
cmd_log.count++;
|
||||||
}
|
}
|
||||||
@@ -891,7 +898,7 @@ bool DoCommandPEx(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd, C
|
|||||||
if (my_cmd) log_flags |= CLEF_MY_CMD;
|
if (my_cmd) log_flags |= CLEF_MY_CMD;
|
||||||
if (binary_length > 0) log_flags |= CLEF_BINARY;
|
if (binary_length > 0) log_flags |= CLEF_BINARY;
|
||||||
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
|
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
|
||||||
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags);
|
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
|
||||||
|
|
||||||
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
|
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
|
||||||
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
|
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
|
||||||
@@ -937,7 +944,7 @@ CommandCost DoCommandPScript(TileIndex tile, uint32 p1, uint32 p2, uint64 p3, ui
|
|||||||
if (my_cmd) log_flags |= CLEF_MY_CMD;
|
if (my_cmd) log_flags |= CLEF_MY_CMD;
|
||||||
if (binary_length > 0) log_flags |= CLEF_BINARY;
|
if (binary_length > 0) log_flags |= CLEF_BINARY;
|
||||||
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
|
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
|
||||||
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags);
|
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
|
||||||
|
|
||||||
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
|
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
|
||||||
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
|
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
|
||||||
|
@@ -103,28 +103,30 @@ struct CompanyProperties {
|
|||||||
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.
|
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
||||||
|
|
||||||
|
Livery livery[LS_END];
|
||||||
|
|
||||||
|
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
|
||||||
|
CompanySettings settings; ///< settings specific for each company
|
||||||
|
|
||||||
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
|
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
|
||||||
CompanyProperties()
|
CompanyProperties()
|
||||||
: name_2(0), name_1(0), president_name_1(0), president_name_2(0),
|
: name_2(0), name_1(0), president_name_1(0), president_name_2(0),
|
||||||
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
|
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
|
||||||
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
|
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
|
||||||
months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
|
months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
|
||||||
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false) {}
|
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
|
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
|
||||||
Company(uint16 name_1 = 0, bool is_ai = false);
|
Company(uint16 name_1 = 0, bool is_ai = false);
|
||||||
~Company();
|
~Company();
|
||||||
|
|
||||||
Livery livery[LS_END];
|
|
||||||
RailTypes avail_railtypes; ///< Rail types available to this company.
|
RailTypes avail_railtypes; ///< Rail types available to this company.
|
||||||
RoadTypes avail_roadtypes; ///< Road types available to this company.
|
RoadTypes avail_roadtypes; ///< Road types available to this company.
|
||||||
|
|
||||||
class AIInstance *ai_instance;
|
class AIInstance *ai_instance;
|
||||||
class AIInfo *ai_info;
|
class AIInfo *ai_info;
|
||||||
|
|
||||||
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
|
|
||||||
CompanySettings settings; ///< settings specific for each company
|
|
||||||
GroupStatistics group_all[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the ALL_GROUP group.
|
GroupStatistics group_all[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the ALL_GROUP group.
|
||||||
GroupStatistics group_default[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the DEFAULT_GROUP group.
|
GroupStatistics group_default[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the DEFAULT_GROUP group.
|
||||||
|
|
||||||
|
@@ -393,8 +393,7 @@ set_name:;
|
|||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
if (c->is_ai) {
|
if (c->is_ai) {
|
||||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
|
||||||
cni->FillData(c);
|
|
||||||
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
|
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
|
||||||
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
|
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
|
||||||
SetDParamStr(2, cni->company_name);
|
SetDParamStr(2, cni->company_name);
|
||||||
@@ -782,21 +781,19 @@ void CompaniesYearlyLoop()
|
|||||||
* @param c the current company.
|
* @param c the current company.
|
||||||
* @param other the other company (use \c nullptr if not relevant).
|
* @param other the other company (use \c nullptr if not relevant).
|
||||||
*/
|
*/
|
||||||
void CompanyNewsInformation::FillData(const Company *c, const Company *other)
|
CompanyNewsInformation::CompanyNewsInformation(const Company *c, const Company *other)
|
||||||
{
|
{
|
||||||
SetDParam(0, c->index);
|
SetDParam(0, c->index);
|
||||||
GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
|
this->company_name = GetString(STR_COMPANY_NAME);
|
||||||
|
|
||||||
if (other == nullptr) {
|
if (other != nullptr) {
|
||||||
*this->other_company_name = '\0';
|
|
||||||
} else {
|
|
||||||
SetDParam(0, other->index);
|
SetDParam(0, other->index);
|
||||||
GetString(this->other_company_name, STR_COMPANY_NAME, lastof(this->other_company_name));
|
this->other_company_name = GetString(STR_COMPANY_NAME);
|
||||||
c = other;
|
c = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDParam(0, c->index);
|
SetDParam(0, c->index);
|
||||||
GetString(this->president_name, STR_PRESIDENT_NAME_MANAGER, lastof(this->president_name));
|
this->president_name = GetString(STR_PRESIDENT_NAME_MANAGER);
|
||||||
|
|
||||||
this->colour = c->colour;
|
this->colour = c->colour;
|
||||||
this->face = c->face;
|
this->face = c->face;
|
||||||
@@ -870,7 +867,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
if (client_id == _network_own_client_id) {
|
if (client_id == _network_own_client_id) {
|
||||||
assert(_local_company == COMPANY_SPECTATOR);
|
assert(_local_company == COMPANY_SPECTATOR);
|
||||||
SetLocalCompany(c->index);
|
SetLocalCompany(c->index);
|
||||||
if (!StrEmpty(_settings_client.network.default_company_pass)) {
|
if (!_settings_client.network.default_company_pass.empty()) {
|
||||||
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
|
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -921,8 +918,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
|
|
||||||
/* Delete any open window of the company */
|
/* Delete any open window of the company */
|
||||||
DeleteCompanyWindows(c->index);
|
DeleteCompanyWindows(c->index);
|
||||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
|
||||||
cni->FillData(c);
|
|
||||||
|
|
||||||
/* Show the bankrupt news */
|
/* Show the bankrupt news */
|
||||||
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
|
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
|
||||||
|
@@ -838,11 +838,11 @@ public:
|
|||||||
|
|
||||||
case WID_SCL_PRI_COL_DROPDOWN: {
|
case WID_SCL_PRI_COL_DROPDOWN: {
|
||||||
this->square = GetSpriteSize(SPR_SQUARE);
|
this->square = GetSpriteSize(SPR_SQUARE);
|
||||||
int padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
|
int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
|
||||||
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
|
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
|
||||||
size->width = std::max(size->width, GetStringBoundingBox(*id).width + padding);
|
size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding);
|
||||||
}
|
}
|
||||||
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + padding);
|
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + string_padding);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,7 +111,7 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
|||||||
* characters and (when applicable) assign it to the console buffer */
|
* characters and (when applicable) assign it to the console buffer */
|
||||||
str = stredup(string);
|
str = stredup(string);
|
||||||
str_strip_colours(str);
|
str_strip_colours(str);
|
||||||
str_validate(str, str + strlen(str));
|
StrMakeValidInPlace(str);
|
||||||
|
|
||||||
if (_network_dedicated) {
|
if (_network_dedicated) {
|
||||||
NetworkAdminConsole("console", str);
|
NetworkAdminConsole("console", str);
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
#include "landscape.h"
|
#include "landscape.h"
|
||||||
#include "saveload/saveload.h"
|
#include "saveload/saveload.h"
|
||||||
|
#include "network/core/game_info.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "network/network_func.h"
|
#include "network/network_func.h"
|
||||||
#include "network/network_base.h"
|
#include "network/network_base.h"
|
||||||
@@ -53,11 +54,14 @@
|
|||||||
#include "linkgraph/linkgraphjob.h"
|
#include "linkgraph/linkgraphjob.h"
|
||||||
#include "base_media_base.h"
|
#include "base_media_base.h"
|
||||||
#include "debug_settings.h"
|
#include "debug_settings.h"
|
||||||
|
#include "walltime_func.h"
|
||||||
#include "debug_desync.h"
|
#include "debug_desync.h"
|
||||||
#include "scope_info.h"
|
#include "scope_info.h"
|
||||||
#include "event_logs.h"
|
#include "event_logs.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/* scriptfile handling */
|
/* scriptfile handling */
|
||||||
@@ -548,7 +552,7 @@ DEF_CONSOLE_CMD(ConClearBuffer)
|
|||||||
* Network Core Console Commands
|
* Network Core Console Commands
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
static bool ConKickOrBan(const char *argv, bool ban, const char *reason)
|
static bool ConKickOrBan(const char *argv, bool ban, const std::string &reason)
|
||||||
{
|
{
|
||||||
uint n;
|
uint n;
|
||||||
|
|
||||||
@@ -602,7 +606,7 @@ DEF_CONSOLE_CMD(ConKick)
|
|||||||
if (argc != 2 && argc != 3) return false;
|
if (argc != 2 && argc != 3) return false;
|
||||||
|
|
||||||
/* No reason supplied for kicking */
|
/* No reason supplied for kicking */
|
||||||
if (argc == 2) return ConKickOrBan(argv[1], false, nullptr);
|
if (argc == 2) return ConKickOrBan(argv[1], false, {});
|
||||||
|
|
||||||
/* Reason for kicking supplied */
|
/* Reason for kicking supplied */
|
||||||
size_t kick_message_length = strlen(argv[2]);
|
size_t kick_message_length = strlen(argv[2]);
|
||||||
@@ -626,7 +630,7 @@ DEF_CONSOLE_CMD(ConBan)
|
|||||||
if (argc != 2 && argc != 3) return false;
|
if (argc != 2 && argc != 3) return false;
|
||||||
|
|
||||||
/* No reason supplied for kicking */
|
/* No reason supplied for kicking */
|
||||||
if (argc == 2) return ConKickOrBan(argv[1], true, nullptr);
|
if (argc == 2) return ConKickOrBan(argv[1], true, {});
|
||||||
|
|
||||||
/* Reason for kicking supplied */
|
/* Reason for kicking supplied */
|
||||||
size_t kick_message_length = strlen(argv[2]);
|
size_t kick_message_length = strlen(argv[2]);
|
||||||
@@ -787,13 +791,14 @@ DEF_CONSOLE_CMD(ConServerInfo)
|
|||||||
{
|
{
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
|
IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
|
||||||
IConsoleHelp("You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
|
IConsoleHelp("You can change these values by modifying settings 'network.max_clients' and 'network.max_companies'");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %2d/%2d", _network_game_info.clients_on, _settings_client.network.max_clients);
|
IConsolePrintF(CC_DEFAULT, "Invite code: %s", _network_server_invite_code.c_str());
|
||||||
IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
|
IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %3d/%3d", _network_game_info.clients_on, _settings_client.network.max_clients);
|
||||||
IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
|
IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %3d/%3d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
|
||||||
|
IConsolePrintF(CC_DEFAULT, "Current spectators: %3d", NetworkSpectatorCount());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -818,7 +823,7 @@ DEF_CONSOLE_CMD(ConClientNickChange)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *client_name = argv[2];
|
std::string client_name(argv[2]);
|
||||||
StrTrimInPlace(client_name);
|
StrTrimInPlace(client_name);
|
||||||
if (!NetworkIsValidClientName(client_name)) {
|
if (!NetworkIsValidClientName(client_name)) {
|
||||||
IConsoleError("Cannot give a client an empty name");
|
IConsoleError("Cannot give a client an empty name");
|
||||||
@@ -853,11 +858,6 @@ DEF_CONSOLE_CMD(ConJoinCompany)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (company_id == COMPANY_SPECTATOR && NetworkMaxSpectatorsReached()) {
|
|
||||||
IConsoleError("Cannot join spectators, maximum number of spectators reached.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
|
if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
|
||||||
IConsoleError("Cannot join AI company.");
|
IConsoleError("Cannot join AI company.");
|
||||||
return true;
|
return true;
|
||||||
@@ -1018,16 +1018,15 @@ DEF_CONSOLE_CMD(ConNetworkReconnect)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrEmpty(_settings_client.network.last_host)) {
|
if (_settings_client.network.last_joined.empty()) {
|
||||||
IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
|
IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't resolve the address first, just print it directly as it comes from the config file. */
|
/* Don't resolve the address first, just print it directly as it comes from the config file. */
|
||||||
IConsolePrintF(CC_DEFAULT, "Reconnecting to %s:%d...", _settings_client.network.last_host, _settings_client.network.last_port);
|
IConsolePrintF(CC_DEFAULT, "Reconnecting to %s ...", _settings_client.network.last_joined.c_str());
|
||||||
|
|
||||||
NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, playas);
|
return NetworkClientConnectGame(_settings_client.network.last_joined, playas);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_CONSOLE_CMD(ConNetworkConnect)
|
DEF_CONSOLE_CMD(ConNetworkConnect)
|
||||||
@@ -1040,37 +1039,8 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2) return false;
|
if (argc < 2) return false;
|
||||||
if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
|
|
||||||
|
|
||||||
const char *port = nullptr;
|
return NetworkClientConnectGame(argv[1], COMPANY_NEW_COMPANY);
|
||||||
const char *company = nullptr;
|
|
||||||
char *ip = argv[1];
|
|
||||||
/* Default settings: default port and new company */
|
|
||||||
uint16 rport = NETWORK_DEFAULT_PORT;
|
|
||||||
CompanyID join_as = COMPANY_NEW_COMPANY;
|
|
||||||
|
|
||||||
ParseGameConnectionString(&company, &port, ip);
|
|
||||||
|
|
||||||
IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip);
|
|
||||||
if (company != nullptr) {
|
|
||||||
join_as = (CompanyID)atoi(company);
|
|
||||||
IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as);
|
|
||||||
|
|
||||||
/* From a user pov 0 is a new company, internally it's different and all
|
|
||||||
* companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
|
|
||||||
if (join_as != COMPANY_SPECTATOR) {
|
|
||||||
if (join_as > MAX_COMPANIES) return false;
|
|
||||||
join_as--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (port != nullptr) {
|
|
||||||
rport = atoi(port);
|
|
||||||
IConsolePrintF(CC_DEFAULT, " port: %s", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkClientConnectGame(ip, rport, join_as);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
@@ -1516,10 +1486,9 @@ DEF_CONSOLE_CMD(ConGetSysDate)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t t;
|
char buffer[lengthof("2000-01-02 03:04:05")];
|
||||||
time(&t);
|
LocalTime::Format(buffer, lastof(buffer), "%Y-%m-%d %H:%M:%S");
|
||||||
auto timeinfo = localtime(&t);
|
IConsolePrintF(CC_DEFAULT, "System Date: %s", buffer);
|
||||||
IConsolePrintF(CC_DEFAULT, "System Date: %04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1817,7 +1786,7 @@ DEF_CONSOLE_CMD(ConCompanies)
|
|||||||
if (c->is_ai) {
|
if (c->is_ai) {
|
||||||
password_state = "AI";
|
password_state = "AI";
|
||||||
} else if (_network_server) {
|
} else if (_network_server) {
|
||||||
password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected";
|
password_state = _network_company_states[c->index].password.empty() ? "unprotected" : "protected";
|
||||||
}
|
}
|
||||||
|
|
||||||
char colour[512];
|
char colour[512];
|
||||||
@@ -1919,7 +1888,7 @@ DEF_CONSOLE_CMD(ConCompanyPassword)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CompanyID company_id;
|
CompanyID company_id;
|
||||||
const char *password;
|
std::string password;
|
||||||
const char *errormsg;
|
const char *errormsg;
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
@@ -1941,10 +1910,10 @@ DEF_CONSOLE_CMD(ConCompanyPassword)
|
|||||||
|
|
||||||
password = NetworkChangeCompanyPassword(company_id, password);
|
password = NetworkChangeCompanyPassword(company_id, password);
|
||||||
|
|
||||||
if (StrEmpty(password)) {
|
if (password.empty()) {
|
||||||
IConsolePrintF(CC_WARNING, "Company password cleared");
|
IConsolePrintF(CC_WARNING, "Company password cleared");
|
||||||
} else {
|
} else {
|
||||||
IConsolePrintF(CC_WARNING, "Company password changed to: %s", password);
|
IConsolePrintF(CC_WARNING, "Company password changed to: %s", password.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1997,7 +1966,7 @@ DEF_CONSOLE_CMD(ConCompanyPasswordHashes)
|
|||||||
char colour[512];
|
char colour[512];
|
||||||
GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
|
GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
|
||||||
IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Hash: '%s'",
|
IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Hash: '%s'",
|
||||||
c->index + 1, colour, company_name, _network_company_states[c->index].password);
|
c->index + 1, colour, company_name, _network_company_states[c->index].password.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2048,7 +2017,7 @@ static void OutputContentState(const ContentInfo *const ci)
|
|||||||
|
|
||||||
char buf[sizeof(ci->md5sum) * 2 + 1];
|
char buf[sizeof(ci->md5sum) * 2 + 1];
|
||||||
md5sumToString(buf, lastof(buf), ci->md5sum);
|
md5sumToString(buf, lastof(buf), ci->md5sum);
|
||||||
IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, buf);
|
IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name.c_str(), ci->unique_id, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_CONSOLE_CMD(ConContent)
|
DEF_CONSOLE_CMD(ConContent)
|
||||||
@@ -2118,7 +2087,7 @@ DEF_CONSOLE_CMD(ConContent)
|
|||||||
if (strcasecmp(argv[1], "state") == 0) {
|
if (strcasecmp(argv[1], "state") == 0) {
|
||||||
IConsolePrintF(CC_WHITE, "id, type, state, name");
|
IConsolePrintF(CC_WHITE, "id, type, state, name");
|
||||||
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
||||||
if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue;
|
if (argc > 2 && strcasestr((*iter)->name.c_str(), argv[2]) == nullptr) continue;
|
||||||
OutputContentState(*iter);
|
OutputContentState(*iter);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2207,6 +2176,71 @@ DEF_CONSOLE_CMD(ConNewGRFReload)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_CONSOLE_CMD(ConListDirs)
|
||||||
|
{
|
||||||
|
struct SubdirNameMap {
|
||||||
|
Subdirectory subdir; ///< Index of subdirectory type
|
||||||
|
const char *name; ///< UI name for the directory
|
||||||
|
bool default_only; ///< Whether only the default (first existing) directory for this is interesting
|
||||||
|
};
|
||||||
|
static const SubdirNameMap subdir_name_map[] = {
|
||||||
|
/* Game data directories */
|
||||||
|
{ BASESET_DIR, "baseset", false },
|
||||||
|
{ NEWGRF_DIR, "newgrf", false },
|
||||||
|
{ AI_DIR, "ai", false },
|
||||||
|
{ AI_LIBRARY_DIR, "ailib", false },
|
||||||
|
{ GAME_DIR, "gs", false },
|
||||||
|
{ GAME_LIBRARY_DIR, "gslib", false },
|
||||||
|
{ SCENARIO_DIR, "scenario", false },
|
||||||
|
{ HEIGHTMAP_DIR, "heightmap", false },
|
||||||
|
/* Default save locations for user data */
|
||||||
|
{ SAVE_DIR, "save", true },
|
||||||
|
{ AUTOSAVE_DIR, "autosave", true },
|
||||||
|
{ SCREENSHOT_DIR, "screenshot", true },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
IConsoleHelp("List all search paths or default directories for various categories.");
|
||||||
|
IConsoleHelp("Usage: list_dirs <category>");
|
||||||
|
std::string cats = subdir_name_map[0].name;
|
||||||
|
bool first = true;
|
||||||
|
for (const SubdirNameMap &sdn : subdir_name_map) {
|
||||||
|
if (!first) cats = cats + ", " + sdn.name;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
IConsolePrintF(CC_WARNING, "Valid categories: %s", cats.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> seen_dirs;
|
||||||
|
for (const SubdirNameMap &sdn : subdir_name_map) {
|
||||||
|
if (strcasecmp(argv[1], sdn.name) != 0) continue;
|
||||||
|
bool found = false;
|
||||||
|
for (Searchpath sp : _valid_searchpaths) {
|
||||||
|
/* Get the directory */
|
||||||
|
std::string path = FioGetDirectory(sp, sdn.subdir);
|
||||||
|
/* Check it hasn't already been listed */
|
||||||
|
if (seen_dirs.find(path) != seen_dirs.end()) continue;
|
||||||
|
seen_dirs.insert(path);
|
||||||
|
/* Check if exists and mark found */
|
||||||
|
bool exists = FileExists(path);
|
||||||
|
found |= exists;
|
||||||
|
/* Print */
|
||||||
|
if (!sdn.default_only || exists) {
|
||||||
|
IConsolePrintF(exists ? CC_DEFAULT : CC_INFO, "%s %s", path.c_str(), exists ? "[ok]" : "[not found]");
|
||||||
|
if (sdn.default_only) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
IConsolePrintF(CC_ERROR, "No directories exist for category %s", argv[1]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConsolePrintF(CC_ERROR, "Invalid category name: %s", argv[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DEF_CONSOLE_CMD(ConResetBlockedHeliports)
|
DEF_CONSOLE_CMD(ConResetBlockedHeliports)
|
||||||
{
|
{
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
@@ -3420,6 +3454,7 @@ void IConsoleStdLibRegister()
|
|||||||
IConsole::CmdRegister("list_settings", ConListSettings);
|
IConsole::CmdRegister("list_settings", ConListSettings);
|
||||||
IConsole::CmdRegister("gamelog", ConGamelogPrint);
|
IConsole::CmdRegister("gamelog", ConGamelogPrint);
|
||||||
IConsole::CmdRegister("rescan_newgrf", ConRescanNewGRF);
|
IConsole::CmdRegister("rescan_newgrf", ConRescanNewGRF);
|
||||||
|
IConsole::CmdRegister("list_dirs", ConListDirs);
|
||||||
|
|
||||||
IConsole::AliasRegister("dir", "ls");
|
IConsole::AliasRegister("dir", "ls");
|
||||||
IConsole::AliasRegister("del", "rm %+");
|
IConsole::AliasRegister("del", "rm %+");
|
||||||
@@ -3499,10 +3534,8 @@ void IConsoleStdLibRegister()
|
|||||||
IConsole::AliasRegister("name", "setting client_name %+");
|
IConsole::AliasRegister("name", "setting client_name %+");
|
||||||
IConsole::AliasRegister("server_name", "setting server_name %+");
|
IConsole::AliasRegister("server_name", "setting server_name %+");
|
||||||
IConsole::AliasRegister("server_port", "setting server_port %+");
|
IConsole::AliasRegister("server_port", "setting server_port %+");
|
||||||
IConsole::AliasRegister("server_advertise", "setting server_advertise %+");
|
|
||||||
IConsole::AliasRegister("max_clients", "setting max_clients %+");
|
IConsole::AliasRegister("max_clients", "setting max_clients %+");
|
||||||
IConsole::AliasRegister("max_companies", "setting max_companies %+");
|
IConsole::AliasRegister("max_companies", "setting max_companies %+");
|
||||||
IConsole::AliasRegister("max_spectators", "setting max_spectators %+");
|
|
||||||
IConsole::AliasRegister("max_join_time", "setting max_join_time %+");
|
IConsole::AliasRegister("max_join_time", "setting max_join_time %+");
|
||||||
IConsole::AliasRegister("pause_on_join", "setting pause_on_join %+");
|
IConsole::AliasRegister("pause_on_join", "setting pause_on_join %+");
|
||||||
IConsole::AliasRegister("autoclean_companies", "setting autoclean_companies %+");
|
IConsole::AliasRegister("autoclean_companies", "setting autoclean_companies %+");
|
||||||
|
@@ -29,7 +29,7 @@ enum ConsoleHookResult {
|
|||||||
* effect they produce are carried out. The arguments to the commands
|
* effect they produce are carried out. The arguments to the commands
|
||||||
* are given to them, each input word separated by a double-quote (") is an argument
|
* are given to them, each input word separated by a double-quote (") is an argument
|
||||||
* 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 sexy boy"'
|
* eg. 'say "hello everybody"'
|
||||||
*/
|
*/
|
||||||
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
|
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
|
||||||
typedef ConsoleHookResult IConsoleHook(bool echo);
|
typedef ConsoleHookResult IConsoleHook(bool echo);
|
||||||
|
@@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
/** Modes of the in-game console. */
|
/** Modes of the in-game console. */
|
||||||
enum IConsoleModes {
|
enum IConsoleModes {
|
||||||
ICONSOLE_FULL, ///< In-game console is closed.
|
ICONSOLE_FULL, ///< In-game console is opened, whole screen.
|
||||||
ICONSOLE_OPENED, ///< In-game console is opened, upper 1/3 of the screen.
|
ICONSOLE_OPENED, ///< In-game console is opened, upper 1/3 of the screen.
|
||||||
ICONSOLE_CLOSED, ///< In-game console is opened, whole screen.
|
ICONSOLE_CLOSED, ///< In-game console is closed.
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Colours of the console messages. */
|
/* Colours of the console messages. */
|
||||||
|
@@ -25,18 +25,7 @@ const uint8 _ffb_64[64] = {
|
|||||||
3, 0, 1, 0, 2, 0, 1, 0,
|
3, 0, 1, 0, 2, 0, 1, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
uint8 FindFirstBit32(uint32 x)
|
||||||
* Search the first set bit in a 32 bit variable.
|
|
||||||
*
|
|
||||||
* This algorithm is a static implementation of a log
|
|
||||||
* congruence search algorithm. It checks the first half
|
|
||||||
* if there is a bit set search there further. And this
|
|
||||||
* way further. If no bit is set return 0.
|
|
||||||
*
|
|
||||||
* @param x The value to search
|
|
||||||
* @return The position of the first bit set
|
|
||||||
*/
|
|
||||||
uint8 FindFirstBit(uint32 x)
|
|
||||||
{
|
{
|
||||||
if (x == 0) return 0;
|
if (x == 0) return 0;
|
||||||
/* The macro FIND_FIRST_BIT is better to use when your x is
|
/* The macro FIND_FIRST_BIT is better to use when your x is
|
||||||
|
@@ -187,21 +187,7 @@ static inline T ToggleBit(T &x, const uint8 y)
|
|||||||
|
|
||||||
#ifdef WITH_BITMATH_BUILTINS
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
|
|
||||||
#define FIND_FIRST_BIT(x) FindFirstBit(x)
|
#define FIND_FIRST_BIT(x) FindFirstBit<uint>(x)
|
||||||
|
|
||||||
inline uint8 FindFirstBit(uint32 x)
|
|
||||||
{
|
|
||||||
if (x == 0) return 0;
|
|
||||||
|
|
||||||
return __builtin_ctz(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8 FindFirstBit64(uint64 x)
|
|
||||||
{
|
|
||||||
if (x == 0) return 0;
|
|
||||||
|
|
||||||
return __builtin_ctzll(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -218,13 +204,41 @@ extern const uint8 _ffb_64[64];
|
|||||||
* @param x The 6-bit value to check the first zero-bit
|
* @param x The 6-bit value to check the first zero-bit
|
||||||
* @return The first position of a bit started from the LSB or 0 if x is 0.
|
* @return The first position of a bit started from the LSB or 0 if x is 0.
|
||||||
*/
|
*/
|
||||||
#define FIND_FIRST_BIT(x) _ffb_64[(x)]
|
#define FIND_FIRST_BIT(x) _ffb_64[(x) & 0x3F]
|
||||||
|
|
||||||
uint8 FindFirstBit(uint32 x);
|
|
||||||
uint8 FindFirstBit64(uint64 x);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the first set bit in an integer variable.
|
||||||
|
*
|
||||||
|
* @param value The value to search
|
||||||
|
* @return The position of the first bit set, or 0 when value is 0
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
static inline uint8 FindFirstBit(T value)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(T) <= sizeof(unsigned long long));
|
||||||
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
|
if (value == 0) return 0;
|
||||||
|
typename std::make_unsigned<T>::type unsigned_value = value;
|
||||||
|
if (sizeof(T) <= sizeof(unsigned int)) {
|
||||||
|
return __builtin_ctz(unsigned_value);
|
||||||
|
} else if (sizeof(T) == sizeof(unsigned long)) {
|
||||||
|
return __builtin_ctzl(unsigned_value);
|
||||||
|
} else {
|
||||||
|
return __builtin_ctzll(unsigned_value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (sizeof(T) <= sizeof(uint32)) {
|
||||||
|
extern uint8 FindFirstBit32(uint32 x);
|
||||||
|
return FindFirstBit32(value);
|
||||||
|
} else {
|
||||||
|
extern uint8 FindFirstBit64(uint64 x);
|
||||||
|
return FindFirstBit64(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
uint8 FindLastBit(uint64 x);
|
uint8 FindLastBit(uint64 x);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,10 +246,7 @@ uint8 FindLastBit(uint64 x);
|
|||||||
*
|
*
|
||||||
* This function returns the position of the first bit set in the
|
* This function returns the position of the first bit set in the
|
||||||
* integer. It does only check the bits of the bitmask
|
* integer. It does only check the bits of the bitmask
|
||||||
* 0x3F3F (0011111100111111) and checks only the
|
* 0x3F3F (0011111100111111).
|
||||||
* bits of the bitmask 0x3F00 if and only if the
|
|
||||||
* lower part 0x00FF is 0. This results the bits at 0x00C0 must
|
|
||||||
* be also zero to check the bits at 0x3F00.
|
|
||||||
*
|
*
|
||||||
* @param value The value to check the first bits
|
* @param value The value to check the first bits
|
||||||
* @return The position of the first bit which is set
|
* @return The position of the first bit which is set
|
||||||
@@ -243,11 +254,16 @@ uint8 FindLastBit(uint64 x);
|
|||||||
*/
|
*/
|
||||||
static inline uint8 FindFirstBit2x64(const int value)
|
static inline uint8 FindFirstBit2x64(const int value)
|
||||||
{
|
{
|
||||||
if ((value & 0xFF) == 0) {
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
|
return FindFirstBit(value & 0x3F3F);
|
||||||
|
#else
|
||||||
|
if (value == 0) return 0;
|
||||||
|
if ((value & 0x3F) == 0) {
|
||||||
return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
|
return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
|
||||||
} else {
|
} else {
|
||||||
return FIND_FIRST_BIT(value & 0x3F);
|
return FIND_FIRST_BIT(value & 0x3F);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -275,6 +291,7 @@ static inline T KillFirstBit(T value)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
static inline uint CountBits(T value)
|
static inline uint CountBits(T value)
|
||||||
{
|
{
|
||||||
|
static_assert(sizeof(T) <= sizeof(unsigned long long));
|
||||||
#ifdef WITH_BITMATH_BUILTINS
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
typename std::make_unsigned<T>::type unsigned_value = value;
|
typename std::make_unsigned<T>::type unsigned_value = value;
|
||||||
if (sizeof(T) <= sizeof(unsigned int)) {
|
if (sizeof(T) <= sizeof(unsigned int)) {
|
||||||
@@ -356,45 +373,76 @@ static inline T ROR(const T x, const uint8 n)
|
|||||||
return (T)(x >> n | x << (sizeof(x) * 8 - n));
|
return (T)(x >> n | x << (sizeof(x) * 8 - n));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do an operation for each set bit in a value.
|
* Iterable ensemble of each set bit in a value.
|
||||||
*
|
* @tparam Tbitpos Type of the position variable.
|
||||||
* This macros is used to do an operation for each set
|
* @tparam Tbitset Type of the bitset value.
|
||||||
* bit in a variable. The second parameter is a
|
*/
|
||||||
* variable that is used as the bit position counter.
|
template <typename Tbitpos = uint, typename Tbitset = uint>
|
||||||
* The fourth parameter is an expression of the bits
|
struct SetBitIterator {
|
||||||
* we need to iterate over. This expression will be
|
struct Iterator {
|
||||||
* evaluated once.
|
typedef Tbitpos value_type;
|
||||||
*
|
typedef value_type *pointer;
|
||||||
* @param Tbitpos_type Type of the position counter variable.
|
typedef value_type &reference;
|
||||||
* @param bitpos_var The position counter variable.
|
typedef size_t difference_type;
|
||||||
* @param Tbitset_type Type of the bitset value.
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
* @param bitset_value The bitset value which we check for bits.
|
|
||||||
*
|
|
||||||
* @see FOR_EACH_SET_BIT
|
|
||||||
*/
|
|
||||||
#define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
|
|
||||||
for ( \
|
|
||||||
Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \
|
|
||||||
___FESBE_bits != (Tbitset_type)0; \
|
|
||||||
___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \
|
|
||||||
) \
|
|
||||||
if ((___FESBE_bits & 1) != 0)
|
|
||||||
|
|
||||||
/**
|
explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(static_cast<Tbitpos>(0))
|
||||||
* Do an operation for each set set bit in a value.
|
{
|
||||||
*
|
this->Validate();
|
||||||
* This macros is used to do an operation for each set
|
}
|
||||||
* bit in a variable. The first parameter is a variable
|
|
||||||
* that is used as the bit position counter.
|
bool operator==(const Iterator &other) const
|
||||||
* The second parameter is an expression of the bits
|
{
|
||||||
* we need to iterate over. This expression will be
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
* evaluated once.
|
return this->bitset == other.bitset;
|
||||||
*
|
#else
|
||||||
* @param bitpos_var The position counter variable.
|
return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos);
|
||||||
* @param bitset_value The value which we check for set bits.
|
#endif
|
||||||
*/
|
}
|
||||||
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
|
bool operator!=(const Iterator &other) const { return !(*this == other); }
|
||||||
|
Tbitpos operator*() const { return this->bitpos; }
|
||||||
|
Iterator & operator++() { this->Next(); this->Validate(); return *this; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tbitset bitset;
|
||||||
|
Tbitpos bitpos;
|
||||||
|
void Validate()
|
||||||
|
{
|
||||||
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
|
if (this->bitset != 0) {
|
||||||
|
typename std::make_unsigned<Tbitset>::type unsigned_value = this->bitset;
|
||||||
|
if (sizeof(Tbitset) <= sizeof(unsigned int)) {
|
||||||
|
bitpos = static_cast<Tbitpos>(__builtin_ctz(unsigned_value));
|
||||||
|
} else if (sizeof(Tbitset) == sizeof(unsigned long)) {
|
||||||
|
bitpos = static_cast<Tbitpos>(__builtin_ctzl(unsigned_value));
|
||||||
|
} else {
|
||||||
|
bitpos = static_cast<Tbitpos>(__builtin_ctzll(unsigned_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void Next()
|
||||||
|
{
|
||||||
|
#ifdef WITH_BITMATH_BUILTINS
|
||||||
|
this->bitset = static_cast<Tbitset>(this->bitset ^ (this->bitset & -this->bitset));
|
||||||
|
#else
|
||||||
|
this->bitset = static_cast<Tbitset>(this->bitset >> 1);
|
||||||
|
this->bitpos++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SetBitIterator(Tbitset bitset) : bitset(bitset) {}
|
||||||
|
Iterator begin() { return Iterator(this->bitset); }
|
||||||
|
Iterator end() { return Iterator(static_cast<Tbitset>(0)); }
|
||||||
|
bool empty() { return this->begin() == this->end(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Tbitset bitset;
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
/* Make endian swapping use Apple's macros to increase speed
|
/* Make endian swapping use Apple's macros to increase speed
|
||||||
|
@@ -274,7 +274,7 @@ class Kdtree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Outputter>
|
template <typename Outputter>
|
||||||
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const
|
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, const Outputter &outputter) const
|
||||||
{
|
{
|
||||||
/* Dimension index of current level */
|
/* Dimension index of current level */
|
||||||
int dim = level % 2;
|
int dim = level % 2;
|
||||||
@@ -458,7 +458,7 @@ public:
|
|||||||
* @param outputter Callback used to return values from the search.
|
* @param outputter Callback used to return values from the search.
|
||||||
*/
|
*/
|
||||||
template <typename Outputter>
|
template <typename Outputter>
|
||||||
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const
|
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const
|
||||||
{
|
{
|
||||||
assert(x1 < x2);
|
assert(x1 < x2);
|
||||||
assert(y1 < y2);
|
assert(y1 < y2);
|
||||||
|
@@ -18,25 +18,26 @@
|
|||||||
* you multiply the maximum value with 2, or add 2, or subtract something from
|
* you multiply the maximum value with 2, or add 2, or subtract something from
|
||||||
* the minimum value, etc.
|
* the minimum value, etc.
|
||||||
* @param T the type these integers are stored with.
|
* @param T the type these integers are stored with.
|
||||||
* @param T_MAX the maximum value for the integers.
|
|
||||||
* @param T_MIN the minimum value for the integers.
|
|
||||||
*/
|
*/
|
||||||
template <class T, T T_MAX, T T_MIN>
|
template <class T>
|
||||||
class OverflowSafeInt
|
class OverflowSafeInt
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
static constexpr T T_MAX = std::numeric_limits<T>::max();
|
||||||
|
static constexpr T T_MIN = std::numeric_limits<T>::min();
|
||||||
|
|
||||||
/** The non-overflow safe backend to store the value in. */
|
/** The non-overflow safe backend to store the value in. */
|
||||||
T m_value;
|
T m_value;
|
||||||
typedef typename std::make_unsigned<T>::type T_unsigned;
|
typedef typename std::make_unsigned<T>::type T_unsigned;
|
||||||
public:
|
public:
|
||||||
OverflowSafeInt() : m_value(0) { }
|
constexpr OverflowSafeInt() : m_value(0) { }
|
||||||
|
|
||||||
OverflowSafeInt(const OverflowSafeInt& other) { this->m_value = other.m_value; }
|
constexpr OverflowSafeInt(const OverflowSafeInt& other) : m_value(other.m_value) { }
|
||||||
OverflowSafeInt(const int64 int_) { this->m_value = int_; }
|
constexpr OverflowSafeInt(const int64 int_) : m_value(int_) { }
|
||||||
|
|
||||||
inline OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
|
inline constexpr OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
|
||||||
|
|
||||||
inline OverflowSafeInt operator - () const { return OverflowSafeInt(this->m_value == T_MIN ? T_MAX : -this->m_value); }
|
inline constexpr OverflowSafeInt operator - () const { return OverflowSafeInt(this->m_value == T_MIN ? T_MAX : -this->m_value); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safe implementation of addition.
|
* Safe implementation of addition.
|
||||||
@@ -44,7 +45,7 @@ public:
|
|||||||
* @note when the addition would yield more than T_MAX (or less than T_MIN),
|
* @note when the addition would yield more than T_MAX (or less than T_MIN),
|
||||||
* it will be T_MAX (respectively T_MIN).
|
* it will be T_MAX (respectively T_MIN).
|
||||||
*/
|
*/
|
||||||
inline OverflowSafeInt& operator += (const OverflowSafeInt& other)
|
inline constexpr OverflowSafeInt& operator += (const OverflowSafeInt& other)
|
||||||
{
|
{
|
||||||
#ifdef WITH_OVERFLOW_BUILTINS
|
#ifdef WITH_OVERFLOW_BUILTINS
|
||||||
if (unlikely(__builtin_add_overflow(this->m_value, other.m_value, &this->m_value))) {
|
if (unlikely(__builtin_add_overflow(this->m_value, other.m_value, &this->m_value))) {
|
||||||
@@ -62,7 +63,12 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline OverflowSafeInt& operator -= (const OverflowSafeInt& other)
|
/**
|
||||||
|
* Safe implementation of subtraction.
|
||||||
|
* @param other the amount to subtract
|
||||||
|
* @note when the subtraction would yield less than T_MIN, it will be T_MIN.
|
||||||
|
*/
|
||||||
|
inline constexpr OverflowSafeInt& operator -= (const OverflowSafeInt& other)
|
||||||
{
|
{
|
||||||
#ifdef WITH_OVERFLOW_BUILTINS
|
#ifdef WITH_OVERFLOW_BUILTINS
|
||||||
if (unlikely(__builtin_sub_overflow(this->m_value, other.m_value, &this->m_value))) {
|
if (unlikely(__builtin_sub_overflow(this->m_value, other.m_value, &this->m_value))) {
|
||||||
@@ -80,18 +86,18 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operators for addition and subtraction */
|
/* Operators for addition and subtraction. */
|
||||||
inline OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
|
inline constexpr OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
|
||||||
inline OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
inline constexpr OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||||
inline OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
inline constexpr OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||||
inline OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
|
inline constexpr OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
|
||||||
inline OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
inline constexpr OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||||
inline OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
inline constexpr OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||||
|
|
||||||
inline OverflowSafeInt& operator ++ () { return *this += 1; }
|
inline constexpr OverflowSafeInt& operator ++ () { return *this += 1; }
|
||||||
inline OverflowSafeInt& operator -- () { return *this += -1; }
|
inline constexpr OverflowSafeInt& operator -- () { return *this += -1; }
|
||||||
inline OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
|
inline constexpr OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
|
||||||
inline OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
|
inline constexpr OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safe implementation of multiplication.
|
* Safe implementation of multiplication.
|
||||||
@@ -99,10 +105,10 @@ public:
|
|||||||
* @note when the multiplication would yield more than T_MAX (or less than T_MIN),
|
* @note when the multiplication would yield more than T_MAX (or less than T_MIN),
|
||||||
* it will be T_MAX (respectively T_MIN).
|
* it will be T_MAX (respectively T_MIN).
|
||||||
*/
|
*/
|
||||||
inline OverflowSafeInt& operator *= (const int factor)
|
inline constexpr OverflowSafeInt& operator *= (const int factor)
|
||||||
{
|
{
|
||||||
#ifdef WITH_OVERFLOW_BUILTINS
|
#ifdef WITH_OVERFLOW_BUILTINS
|
||||||
T out;
|
T out = 0;
|
||||||
if (likely(!__builtin_mul_overflow(this->m_value, factor, &out))) {
|
if (likely(!__builtin_mul_overflow(this->m_value, factor, &out))) {
|
||||||
this->m_value = out;
|
this->m_value = out;
|
||||||
} else {
|
} else {
|
||||||
@@ -126,73 +132,80 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operators for multiplication */
|
/* Operators for multiplication. */
|
||||||
inline OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
|
||||||
inline OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||||
inline OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||||
inline OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||||
inline OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
inline constexpr OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||||
|
|
||||||
/* Operators for division */
|
/* Operators for division. */
|
||||||
inline OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
|
inline constexpr OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
|
||||||
inline OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
|
inline constexpr OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
|
||||||
inline OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
|
inline constexpr OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
|
||||||
inline OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
|
inline constexpr OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
|
||||||
|
|
||||||
/* Operators for modulo */
|
/* Operators for modulo */
|
||||||
inline OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
|
inline constexpr OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
|
||||||
inline OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
|
inline constexpr OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
|
||||||
|
|
||||||
/* Operators for shifting */
|
/* Operators for shifting. */
|
||||||
inline OverflowSafeInt& operator <<= (const int shift) { this->m_value = ((T_unsigned) this->m_value) << shift; return *this; }
|
inline constexpr OverflowSafeInt& operator <<= (const int shift) { this->m_value = ((T_unsigned) this->m_value) << shift; return *this; }
|
||||||
inline OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
|
inline constexpr OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
|
||||||
inline OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
|
inline constexpr OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
|
||||||
inline OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
|
inline constexpr OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
|
||||||
|
|
||||||
/* Operators for (in)equality when comparing overflow safe ints */
|
/* Operators for (in)equality when comparing overflow safe ints. */
|
||||||
inline bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
|
inline constexpr bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
|
||||||
inline bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
|
inline constexpr bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
|
||||||
inline bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
|
inline constexpr bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
|
||||||
inline bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
|
inline constexpr bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
|
||||||
inline bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
|
inline constexpr bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
|
||||||
inline bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
|
inline constexpr bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
|
||||||
|
|
||||||
/* Operators for (in)equality when comparing non-overflow safe ints */
|
/* Operators for (in)equality when comparing non-overflow safe ints. */
|
||||||
inline bool operator == (const int other) const { return this->m_value == other; }
|
inline constexpr bool operator == (const int other) const { return this->m_value == other; }
|
||||||
inline bool operator != (const int other) const { return !(*this == other); }
|
inline constexpr bool operator != (const int other) const { return !(*this == other); }
|
||||||
inline bool operator > (const int other) const { return this->m_value > other; }
|
inline constexpr bool operator > (const int other) const { return this->m_value > other; }
|
||||||
inline bool operator >= (const int other) const { return this->m_value >= other; }
|
inline constexpr bool operator >= (const int other) const { return this->m_value >= other; }
|
||||||
inline bool operator < (const int other) const { return !(*this >= other); }
|
inline constexpr bool operator < (const int other) const { return !(*this >= other); }
|
||||||
inline bool operator <= (const int other) const { return !(*this > other); }
|
inline constexpr bool operator <= (const int other) const { return !(*this > other); }
|
||||||
|
|
||||||
inline operator int64 () const { return this->m_value; }
|
inline constexpr operator int64 () const { return this->m_value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly */
|
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
|
||||||
|
|
||||||
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly */
|
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int64 a, const OverflowSafeInt<T> b) { return b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int64 a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int64 a, const OverflowSafeInt<T> b) { return b * a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int64 a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||||
|
|
||||||
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly */
|
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int a, const OverflowSafeInt<T> b) { return b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int a, const OverflowSafeInt<T> b) { return b * a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int 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 uint operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator + (const uint a, const OverflowSafeInt<T> b) { return b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator - (const uint a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * (uint)a; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint a, const OverflowSafeInt<T> b) { return b * a; }
|
||||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||||
|
|
||||||
typedef OverflowSafeInt<int64, INT64_MAX, INT64_MIN> OverflowSafeInt64;
|
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||||
typedef OverflowSafeInt<int32, INT32_MAX, INT32_MIN> OverflowSafeInt32;
|
template <class T> inline constexpr OverflowSafeInt<T> operator + (const byte a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
||||||
|
template <class T> inline constexpr OverflowSafeInt<T> operator - (const byte a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
||||||
|
template <class T> inline constexpr OverflowSafeInt<T> operator * (const byte a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
||||||
|
template <class T> inline constexpr OverflowSafeInt<T> operator / (const byte a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||||
|
|
||||||
|
typedef OverflowSafeInt<int64> OverflowSafeInt64;
|
||||||
|
typedef OverflowSafeInt<int32> OverflowSafeInt32;
|
||||||
|
|
||||||
|
/* Some basic "unit tests". Also has the bonus of confirming that constexpr is working. */
|
||||||
|
static_assert(OverflowSafeInt32(INT32_MIN) - 1 == OverflowSafeInt32(INT32_MIN));
|
||||||
|
static_assert(OverflowSafeInt32(INT32_MAX) + 1 == OverflowSafeInt32(INT32_MAX));
|
||||||
|
static_assert(OverflowSafeInt32(INT32_MAX) * 2 == OverflowSafeInt32(INT32_MAX));
|
||||||
|
static_assert(OverflowSafeInt32(INT32_MIN) * 2 == OverflowSafeInt32(INT32_MIN));
|
||||||
|
|
||||||
#endif /* OVERFLOWSAFE_TYPE_HPP */
|
#endif /* OVERFLOWSAFE_TYPE_HPP */
|
||||||
|
@@ -35,9 +35,9 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
|||||||
first_free(0),
|
first_free(0),
|
||||||
first_unused(0),
|
first_unused(0),
|
||||||
items(0),
|
items(0),
|
||||||
#ifdef OTTD_ASSERT
|
#ifdef WITH_ASSERT
|
||||||
checked(0),
|
checked(0),
|
||||||
#endif /* OTTD_ASSERT */
|
#endif /* WITH_ASSERT */
|
||||||
cleaning(false),
|
cleaning(false),
|
||||||
data(nullptr),
|
data(nullptr),
|
||||||
free_bitmap(nullptr),
|
free_bitmap(nullptr),
|
||||||
@@ -81,7 +81,7 @@ DEFINE_POOL_METHOD(inline size_t)::FindFirstFree()
|
|||||||
for (; bitmap_index < bitmap_end; bitmap_index++) {
|
for (; bitmap_index < bitmap_end; bitmap_index++) {
|
||||||
uint64 available = ~this->free_bitmap[bitmap_index];
|
uint64 available = ~this->free_bitmap[bitmap_index];
|
||||||
if (available == 0) continue;
|
if (available == 0) continue;
|
||||||
return (bitmap_index * 64) + FindFirstBit64(available);
|
return (bitmap_index * 64) + FindFirstBit(available);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->first_unused < this->size) {
|
if (this->first_unused < this->size) {
|
||||||
@@ -145,10 +145,10 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size)
|
|||||||
{
|
{
|
||||||
size_t index = this->FindFirstFree();
|
size_t index = this->FindFirstFree();
|
||||||
|
|
||||||
#ifdef OTTD_ASSERT
|
#ifdef WITH_ASSERT
|
||||||
assert(this->checked != 0);
|
assert(this->checked != 0);
|
||||||
this->checked--;
|
this->checked--;
|
||||||
#endif /* OTTD_ASSERT */
|
#endif /* WITH_ASSERT */
|
||||||
if (index == NO_FREE_ITEM) {
|
if (index == NO_FREE_ITEM) {
|
||||||
error("%s: no more free items", this->name);
|
error("%s: no more free items", this->name);
|
||||||
}
|
}
|
||||||
|
@@ -90,9 +90,9 @@ struct Pool : PoolBase {
|
|||||||
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
|
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
|
||||||
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
|
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
|
||||||
size_t items; ///< Number of used indexes (non-nullptr)
|
size_t items; ///< Number of used indexes (non-nullptr)
|
||||||
#ifdef OTTD_ASSERT
|
#ifdef WITH_ASSERT
|
||||||
size_t checked; ///< Number of items we checked for
|
size_t checked; ///< Number of items we checked for
|
||||||
#endif /* OTTD_ASSERT */
|
#endif /* WITH_ASSERT */
|
||||||
bool cleaning; ///< True if cleaning pool (deleting all items)
|
bool cleaning; ///< True if cleaning pool (deleting all items)
|
||||||
|
|
||||||
Titem **data; ///< Pointer to array of pointers to Titem
|
Titem **data; ///< Pointer to array of pointers to Titem
|
||||||
@@ -131,9 +131,9 @@ struct Pool : PoolBase {
|
|||||||
inline bool CanAllocate(size_t n = 1)
|
inline bool CanAllocate(size_t n = 1)
|
||||||
{
|
{
|
||||||
bool ret = this->items <= Tmax_size - n;
|
bool ret = this->items <= Tmax_size - n;
|
||||||
#ifdef OTTD_ASSERT
|
#ifdef WITH_ASSERT
|
||||||
this->checked = ret ? n : 0;
|
this->checked = ret ? n : 0;
|
||||||
#endif /* OTTD_ASSERT */
|
#endif /* WITH_ASSERT */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,11 @@ struct Pool : PoolBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
size_t index;
|
size_t index;
|
||||||
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++; }
|
void ValidateIndex()
|
||||||
|
{
|
||||||
|
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
|
||||||
|
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -173,7 +177,7 @@ struct Pool : PoolBase {
|
|||||||
size_t from;
|
size_t from;
|
||||||
IterateWrapper(size_t from = 0) : from(from) {}
|
IterateWrapper(size_t from = 0) : from(from) {}
|
||||||
PoolIterator<T> begin() { return PoolIterator<T>(this->from); }
|
PoolIterator<T> begin() { return PoolIterator<T>(this->from); }
|
||||||
PoolIterator<T> end() { return PoolIterator<T>(T::GetPoolSize()); }
|
PoolIterator<T> end() { return PoolIterator<T>(T::Pool::MAX_SIZE); }
|
||||||
bool empty() { return this->begin() == this->end(); }
|
bool empty() { return this->begin() == this->end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -202,7 +206,11 @@ struct Pool : PoolBase {
|
|||||||
private:
|
private:
|
||||||
size_t index;
|
size_t index;
|
||||||
F filter;
|
F filter;
|
||||||
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; }
|
void ValidateIndex()
|
||||||
|
{
|
||||||
|
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
|
||||||
|
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -215,7 +223,7 @@ struct Pool : PoolBase {
|
|||||||
F filter;
|
F filter;
|
||||||
IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {}
|
IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {}
|
||||||
PoolIteratorFiltered<T, F> begin() { return PoolIteratorFiltered<T, F>(this->from, this->filter); }
|
PoolIteratorFiltered<T, F> begin() { return PoolIteratorFiltered<T, F>(this->from, this->filter); }
|
||||||
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::GetPoolSize(), this->filter); }
|
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::Pool::MAX_SIZE, this->filter); }
|
||||||
bool empty() { return this->begin() == this->end(); }
|
bool empty() { return this->begin() == this->end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
100
src/core/span_type.hpp
Normal file
100
src/core/span_type.hpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* 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 span_type.hpp Minimized implementation of C++20 std::span. */
|
||||||
|
|
||||||
|
#ifndef CORE_SPAN_TYPE_HPP
|
||||||
|
#define CORE_SPAN_TYPE_HPP
|
||||||
|
|
||||||
|
/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
|
||||||
|
|
||||||
|
/* Template to check if a template variable defines size() and data(). */
|
||||||
|
template <class, class = void>
|
||||||
|
struct has_size_and_data : std::false_type{};
|
||||||
|
template <class C>
|
||||||
|
struct has_size_and_data
|
||||||
|
<
|
||||||
|
C, std::void_t<
|
||||||
|
decltype(std::size(std::declval<C>())),
|
||||||
|
decltype(std::data(std::declval<C>()))>
|
||||||
|
> : std::true_type{};
|
||||||
|
|
||||||
|
/* Template to check if two elements are compatible. */
|
||||||
|
template <class, class, class = void>
|
||||||
|
struct is_compatible_element : std::false_type {};
|
||||||
|
template <class C, class E>
|
||||||
|
struct is_compatible_element
|
||||||
|
<
|
||||||
|
C, E, std::void_t<
|
||||||
|
decltype(std::data(std::declval<C>())),
|
||||||
|
typename std::remove_pointer<decltype(std::data( std::declval<C&>()))>::type(*)[]>
|
||||||
|
> : std::is_convertible<typename std::remove_pointer<decltype(std::data(std::declval<C&>()))>::type(*)[], E(*)[]>{};
|
||||||
|
|
||||||
|
/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
|
||||||
|
template <class C, class E>
|
||||||
|
struct is_compatible_container : std::bool_constant
|
||||||
|
<
|
||||||
|
has_size_and_data<C>::value
|
||||||
|
&& is_compatible_element<C,E>::value
|
||||||
|
>{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A trimmed down version of what std::span will be in C++20.
|
||||||
|
*
|
||||||
|
* It is fully forwards compatible, so if this codebase switches to C++20,
|
||||||
|
* all "span" instances can be replaced by "std::span" without loss of
|
||||||
|
* functionality.
|
||||||
|
*
|
||||||
|
* Currently it only supports basic functionality:
|
||||||
|
* - size() and friends
|
||||||
|
* - begin() and friends
|
||||||
|
*
|
||||||
|
* It is meant to simplify function parameters, where we only want to walk
|
||||||
|
* a continuous list.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class span {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
typedef typename std::remove_cv< T >::type value_type;
|
||||||
|
|
||||||
|
typedef T &reference;
|
||||||
|
typedef T *pointer;
|
||||||
|
typedef const T &const_reference;
|
||||||
|
typedef const T *const_pointer;
|
||||||
|
|
||||||
|
typedef pointer iterator;
|
||||||
|
typedef const_pointer const_iterator;
|
||||||
|
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
constexpr span() noexcept : first(nullptr), last(nullptr) {}
|
||||||
|
|
||||||
|
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
|
||||||
|
|
||||||
|
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
|
||||||
|
constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
|
||||||
|
template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
|
||||||
|
constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
|
||||||
|
|
||||||
|
constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
|
||||||
|
constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
|
||||||
|
constexpr bool empty() const noexcept { return size() == 0; }
|
||||||
|
|
||||||
|
constexpr iterator begin() const noexcept { return iterator(first); }
|
||||||
|
constexpr iterator end() const noexcept { return iterator(last); }
|
||||||
|
|
||||||
|
constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
|
||||||
|
constexpr const_iterator cend() const noexcept { return const_iterator(last); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
pointer first;
|
||||||
|
pointer last;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CORE_SPAN_TYPE_HPP */
|
30
src/cpu.cpp
30
src/cpu.cpp
@@ -73,6 +73,18 @@ uint64 ottd_rdtsc()
|
|||||||
# define RDTSC_AVAILABLE
|
# define RDTSC_AVAILABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* rdtsc for MCST Elbrus 2000 */
|
||||||
|
#if defined(__e2k__) && !defined(RDTSC_AVAILABLE)
|
||||||
|
uint64 ottd_rdtsc()
|
||||||
|
{
|
||||||
|
uint64_t dst;
|
||||||
|
# pragma asm_inline
|
||||||
|
asm("rrd %%clkr, %0" : "=r" (dst));
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
# define RDTSC_AVAILABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__) && !defined(RDTSC_AVAILABLE)
|
#if defined(__EMSCRIPTEN__) && !defined(RDTSC_AVAILABLE)
|
||||||
/* On emscripten doing TIC/TOC would be ill-advised */
|
/* On emscripten doing TIC/TOC would be ill-advised */
|
||||||
uint64 ottd_rdtsc() {return 0;}
|
uint64 ottd_rdtsc() {return 0;}
|
||||||
@@ -131,6 +143,24 @@ void ottd_cpuid(int info[4], int type)
|
|||||||
);
|
);
|
||||||
#endif /* i386 PIC */
|
#endif /* i386 PIC */
|
||||||
}
|
}
|
||||||
|
#elif defined(__e2k__) /* MCST Elbrus 2000*/
|
||||||
|
void ottd_cpuid(int info[4], int type)
|
||||||
|
{
|
||||||
|
info[0] = info[1] = info[2] = info[3] = 0;
|
||||||
|
if (type == 0) {
|
||||||
|
info[0] = 1;
|
||||||
|
} else if (type == 1) {
|
||||||
|
#if defined(__SSE4_1__)
|
||||||
|
info[2] |= (1<<19); /* HasCPUIDFlag(1, 2, 19) */
|
||||||
|
#endif
|
||||||
|
#if defined(__SSSE3__)
|
||||||
|
info[2] |= (1<<9); /* HasCPUIDFlag(1, 2, 9) */
|
||||||
|
#endif
|
||||||
|
#if defined(__SSE2__)
|
||||||
|
info[3] |= (1<<26); /* HasCPUIDFlag(1, 3, 26) */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
void ottd_cpuid(int info[4], int type)
|
void ottd_cpuid(int info[4], int type)
|
||||||
{
|
{
|
||||||
|
@@ -38,8 +38,7 @@
|
|||||||
#include "game/game_info.hpp"
|
#include "game/game_info.hpp"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "company_func.h"
|
#include "company_func.h"
|
||||||
|
#include "walltime_func.h"
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#ifdef WITH_ALLEGRO
|
#ifdef WITH_ALLEGRO
|
||||||
# include <allegro.h>
|
# include <allegro.h>
|
||||||
@@ -154,7 +153,7 @@ char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
|
|||||||
_openttd_revision_modified,
|
_openttd_revision_modified,
|
||||||
_openttd_release_version,
|
_openttd_release_version,
|
||||||
_openttd_newgrf_version,
|
_openttd_newgrf_version,
|
||||||
#ifdef _SQ64
|
#ifdef POINTER_IS_64BIT
|
||||||
64,
|
64,
|
||||||
#else
|
#else
|
||||||
32,
|
32,
|
||||||
@@ -424,7 +423,6 @@ char *CrashLog::LogCommandLog(char *buffer, const char *last) const
|
|||||||
*/
|
*/
|
||||||
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
|
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
|
||||||
{
|
{
|
||||||
time_t cur_time = time(nullptr);
|
|
||||||
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
|
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
|
||||||
|
|
||||||
if (GamelogTestEmergency()) {
|
if (GamelogTestEmergency()) {
|
||||||
@@ -434,7 +432,7 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const
|
|||||||
buffer += seprintf(buffer, last, "-=-=- As you loaded a savegame for which you do not have the required NewGRFs no crash information would ordinarily be generated. -=-=-\n\n");
|
buffer += seprintf(buffer, last, "-=-=- As you loaded a savegame for which you do not have the required NewGRFs no crash information would ordinarily be generated. -=-=-\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
|
buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n");
|
||||||
|
|
||||||
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u)\n", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, _settings_game.economy.day_length_factor);
|
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u)\n", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, _settings_game.economy.day_length_factor);
|
||||||
if (_game_load_time != 0) {
|
if (_game_load_time != 0) {
|
||||||
|
@@ -70,11 +70,11 @@ enum Currencies {
|
|||||||
|
|
||||||
/** Specification of a currency. */
|
/** Specification of a currency. */
|
||||||
struct CurrencySpec {
|
struct CurrencySpec {
|
||||||
uint16 rate;
|
uint16 rate; ///< The conversion rate compared to the base currency.
|
||||||
char separator[8];
|
std::string separator; ///< The thousands separator for this currency.
|
||||||
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
|
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
|
||||||
char prefix[16];
|
std::string prefix; ///< Prefix to apply when formatting money in this currency.
|
||||||
char suffix[16];
|
std::string suffix; ///< Suffix to apply when formatting money in this currency.
|
||||||
/**
|
/**
|
||||||
* The currency symbol is represented by two possible values, prefix and suffix
|
* The currency symbol is represented by two possible values, prefix and suffix
|
||||||
* Usage of one or the other is determined by #symbol_pos.
|
* Usage of one or the other is determined by #symbol_pos.
|
||||||
@@ -89,11 +89,9 @@ struct CurrencySpec {
|
|||||||
|
|
||||||
CurrencySpec() = default;
|
CurrencySpec() = default;
|
||||||
|
|
||||||
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : rate(rate), to_euro(to_euro), symbol_pos(symbol_pos), name(name)
|
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) :
|
||||||
|
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name)
|
||||||
{
|
{
|
||||||
strecpy(this->separator, separator, lastof(this->separator));
|
|
||||||
strecpy(this->prefix, prefix, lastof(this->prefix));
|
|
||||||
strecpy(this->suffix, suffix, lastof(this->suffix));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user